Skip to content

Commit 5fee7cc

Browse files
authored
Merge pull request #9361 from swiftlang/lldb-astcontext-init-to-20240723
[cherry-pick][stable/20240723] [lldb][TypeSystemClang] Add warning and defensive checks when ASTContext is not fully initialized
2 parents 1d0efd1 + b09c5d3 commit 5fee7cc

File tree

2 files changed

+68
-4
lines changed

2 files changed

+68
-4
lines changed

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#include "Plugins/ExpressionParser/Clang/ClangUserExpression.h"
5757
#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
5858
#include "Plugins/ExpressionParser/Clang/ClangUtilityFunction.h"
59+
#include "lldb/Core/Debugger.h"
5960
#include "lldb/Core/DumpDataExtractor.h"
6061
#include "lldb/Core/Module.h"
6162
#include "lldb/Core/PluginManager.h"
@@ -748,10 +749,20 @@ void TypeSystemClang::CreateASTContext() {
748749
TargetInfo *target_info = getTargetInfo();
749750
if (target_info)
750751
m_ast_up->InitBuiltinTypes(*target_info);
751-
else if (auto *log = GetLog(LLDBLog::Expressions))
752-
LLDB_LOG(log,
753-
"Failed to initialize builtin ASTContext types for target '{0}'",
754-
m_target_triple);
752+
else {
753+
std::string err =
754+
llvm::formatv(
755+
"Failed to initialize builtin ASTContext types for target '{0}'. "
756+
"Printing variables may behave unexpectedly.",
757+
m_target_triple)
758+
.str();
759+
760+
LLDB_LOG(GetLog(LLDBLog::Expressions), err.c_str());
761+
762+
static std::once_flag s_uninitialized_target_warning;
763+
Debugger::ReportWarning(std::move(err), /*debugger_id=*/std::nullopt,
764+
&s_uninitialized_target_warning);
765+
}
755766

756767
GetASTMap().Insert(m_ast_up.get(), this);
757768

@@ -801,6 +812,10 @@ CompilerType
801812
TypeSystemClang::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding,
802813
size_t bit_size) {
803814
ASTContext &ast = getASTContext();
815+
816+
if (!ast.VoidPtrTy)
817+
return {};
818+
804819
switch (encoding) {
805820
case eEncodingInvalid:
806821
if (QualTypeMatchesBitSize(bit_size, ast, ast.VoidPtrTy))
@@ -943,6 +958,9 @@ CompilerType TypeSystemClang::GetBuiltinTypeForDWARFEncodingAndBitSize(
943958
llvm::StringRef type_name, uint32_t dw_ate, uint32_t bit_size) {
944959
ASTContext &ast = getASTContext();
945960

961+
if (!ast.VoidPtrTy)
962+
return {};
963+
946964
switch (dw_ate) {
947965
default:
948966
break;
@@ -2421,6 +2439,9 @@ CompilerType TypeSystemClang::GetIntTypeFromBitSize(size_t bit_size,
24212439
bool is_signed) {
24222440
clang::ASTContext &ast = getASTContext();
24232441

2442+
if (!ast.VoidPtrTy)
2443+
return {};
2444+
24242445
if (is_signed) {
24252446
if (bit_size == ast.getTypeSize(ast.SignedCharTy))
24262447
return GetType(ast.SignedCharTy);
@@ -2462,6 +2483,9 @@ CompilerType TypeSystemClang::GetIntTypeFromBitSize(size_t bit_size,
24622483
}
24632484

24642485
CompilerType TypeSystemClang::GetPointerSizedIntType(bool is_signed) {
2486+
if (!getASTContext().VoidPtrTy)
2487+
return {};
2488+
24652489
return GetIntTypeFromBitSize(
24662490
getASTContext().getTypeSize(getASTContext().VoidPtrTy), is_signed);
24672491
}
@@ -7575,6 +7599,13 @@ clang::FieldDecl *TypeSystemClang::AddFieldToRecordType(
75757599

75767600
clang::Expr *bit_width = nullptr;
75777601
if (bitfield_bit_size != 0) {
7602+
if (clang_ast.IntTy.isNull()) {
7603+
LLDB_LOG(
7604+
GetLog(LLDBLog::Expressions),
7605+
"{0} failed: builtin ASTContext types have not been initialized");
7606+
return nullptr;
7607+
}
7608+
75787609
llvm::APInt bitfield_bit_size_apint(clang_ast.getTypeSize(clang_ast.IntTy),
75797610
bitfield_bit_size);
75807611
bit_width = new (clang_ast)

lldb/unittests/Symbol/TestTypeSystemClang.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
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"
20+
#include "llvm/BinaryFormat/Dwarf.h"
1921
#include "gtest/gtest.h"
2022

2123
using namespace clang;
@@ -231,6 +233,37 @@ TEST_F(TestTypeSystemClang, TestBuiltinTypeForEncodingAndBitSize) {
231233
VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 64);
232234
}
233235

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

0 commit comments

Comments
 (0)