Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit cba9ca2

Browse files
committedSep 30, 2024·
[lldb][TypeSystemClang] Add warning and defensive checks when ASTContext is not fully initialized
1 parent 2612316 commit cba9ca2

File tree

2 files changed

+67
-4
lines changed

2 files changed

+67
-4
lines changed
 

Diff for: ‎lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp

+35-4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h"
5555
#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
5656
#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h"
57+
#include "lldb/Core/Debugger.h"
5758
#include "lldb/Core/DumpDataExtractor.h"
5859
#include "lldb/Core/Module.h"
5960
#include "lldb/Core/PluginManager.h"
@@ -697,10 +698,20 @@ void TypeSystemClang::CreateASTContext() {
697698
TargetInfo *target_info = getTargetInfo();
698699
if (target_info)
699700
m_ast_up->InitBuiltinTypes(*target_info);
700-
else if (auto *log = GetLog(LLDBLog::Expressions))
701-
LLDB_LOG(log,
702-
"Failed to initialize builtin ASTContext types for target '{0}'",
703-
m_target_triple);
701+
else {
702+
std::string err =
703+
llvm::formatv(
704+
"Failed to initialize builtin ASTContext types for target '{0}'. "
705+
"Printing variables may behave unexpectedly.",
706+
m_target_triple)
707+
.str();
708+
709+
LLDB_LOG(GetLog(LLDBLog::Expressions), err.c_str());
710+
711+
static std::once_flag s_uninitialized_target_warning;
712+
Debugger::ReportWarning(std::move(err), /*debugger_id=*/std::nullopt,
713+
&s_uninitialized_target_warning);
714+
}
704715

705716
GetASTMap().Insert(m_ast_up.get(), this);
706717

@@ -749,6 +760,10 @@ CompilerType
749760
TypeSystemClang::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding,
750761
size_t bit_size) {
751762
ASTContext &ast = getASTContext();
763+
764+
if (!ast.VoidPtrTy)
765+
return {};
766+
752767
switch (encoding) {
753768
case eEncodingInvalid:
754769
if (QualTypeMatchesBitSize(bit_size, ast, ast.VoidPtrTy))
@@ -891,6 +906,9 @@ CompilerType TypeSystemClang::GetBuiltinTypeForDWARFEncodingAndBitSize(
891906
llvm::StringRef type_name, uint32_t dw_ate, uint32_t bit_size) {
892907
ASTContext &ast = getASTContext();
893908

909+
if (!ast.VoidPtrTy)
910+
return {};
911+
894912
switch (dw_ate) {
895913
default:
896914
break;
@@ -2335,6 +2353,9 @@ CompilerType TypeSystemClang::GetIntTypeFromBitSize(size_t bit_size,
23352353
bool is_signed) {
23362354
clang::ASTContext &ast = getASTContext();
23372355

2356+
if (!ast.VoidPtrTy)
2357+
return {};
2358+
23382359
if (is_signed) {
23392360
if (bit_size == ast.getTypeSize(ast.SignedCharTy))
23402361
return GetType(ast.SignedCharTy);
@@ -2376,6 +2397,9 @@ CompilerType TypeSystemClang::GetIntTypeFromBitSize(size_t bit_size,
23762397
}
23772398

23782399
CompilerType TypeSystemClang::GetPointerSizedIntType(bool is_signed) {
2400+
if (!getASTContext().VoidPtrTy)
2401+
return {};
2402+
23792403
return GetIntTypeFromBitSize(
23802404
getASTContext().getTypeSize(getASTContext().VoidPtrTy), is_signed);
23812405
}
@@ -7453,6 +7477,13 @@ clang::FieldDecl *TypeSystemClang::AddFieldToRecordType(
74537477

74547478
clang::Expr *bit_width = nullptr;
74557479
if (bitfield_bit_size != 0) {
7480+
if (clang_ast.IntTy.isNull()) {
7481+
LLDB_LOG(
7482+
GetLog(LLDBLog::Expressions),
7483+
"{0} failed: builtin ASTContext types have not been initialized");
7484+
return nullptr;
7485+
}
7486+
74567487
llvm::APInt bitfield_bit_size_apint(clang_ast.getTypeSize(clang_ast.IntTy),
74577488
bitfield_bit_size);
74587489
bit_width = new (clang_ast)

Diff for: ‎lldb/unittests/Symbol/TestTypeSystemClang.cpp

+32
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "lldb/Core/Declaration.h"
1414
#include "lldb/Host/FileSystem.h"
1515
#include "lldb/Host/HostInfo.h"
16+
#include "lldb/lldb-enumerations.h"
1617
#include "clang/AST/DeclCXX.h"
1718
#include "clang/AST/DeclObjC.h"
1819
#include "clang/AST/ExprCXX.h"
@@ -231,6 +232,37 @@ TEST_F(TestTypeSystemClang, TestBuiltinTypeForEncodingAndBitSize) {
231232
VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 64);
232233
}
233234

235+
TEST_F(TestTypeSystemClang, TestBuiltinTypeForEmptyTriple) {
236+
// Test that we can access type-info of builtin Clang AST
237+
// types without crashing even when the target triple is
238+
// empty.
239+
240+
TypeSystemClang ast("empty triple AST", llvm::Triple{});
241+
242+
// This test only makes sense if the builtin ASTContext types were
243+
// not initialized.
244+
ASSERT_TRUE(ast.getASTContext().VoidPtrTy.isNull());
245+
246+
EXPECT_FALSE(ast.GetBuiltinTypeByName(ConstString("int")).IsValid());
247+
EXPECT_FALSE(ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
248+
"char", dwarf::DW_ATE_signed_char, 8)
249+
.IsValid());
250+
EXPECT_FALSE(ast.GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 8)
251+
.IsValid());
252+
EXPECT_FALSE(ast.GetPointerSizedIntType(/*is_signed=*/false));
253+
EXPECT_FALSE(ast.GetIntTypeFromBitSize(8, /*is_signed=*/false));
254+
255+
CompilerType record_type = ast.CreateRecordType(
256+
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "Record",
257+
llvm::to_underlying(clang::TagTypeKind::Struct),
258+
lldb::eLanguageTypeC_plus_plus, std::nullopt);
259+
TypeSystemClang::StartTagDeclarationDefinition(record_type);
260+
EXPECT_EQ(ast.AddFieldToRecordType(record_type, "field", record_type,
261+
eAccessPublic, /*bitfield_bit_size=*/8),
262+
nullptr);
263+
TypeSystemClang::CompleteTagDeclarationDefinition(record_type);
264+
}
265+
234266
TEST_F(TestTypeSystemClang, TestDisplayName) {
235267
TypeSystemClang ast("some name", llvm::Triple());
236268
EXPECT_EQ("some name", ast.getDisplayName());

0 commit comments

Comments
 (0)
Please sign in to comment.