Skip to content

Commit 5bc9c53

Browse files
authored
Merge pull request swiftlang#9217 from swiftlang/bugfix/lldb-def-crash-to-20240723
[lldb][TypeSystemClang] Avoid accessing definition if none is available
2 parents 0d1fece + ebe8b80 commit 5bc9c53

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

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

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "TypeSystemClang.h"
1010

1111
#include "clang/AST/DeclBase.h"
12+
#include "clang/AST/DeclCXX.h"
1213
#include "clang/AST/ExprCXX.h"
1314
#include "llvm/ADT/STLForwardCompat.h"
1415
#include "llvm/Support/Casting.h"
@@ -3650,6 +3651,15 @@ bool TypeSystemClang::IsPolymorphicClass(lldb::opaque_compiler_type_t type) {
36503651
return false;
36513652
}
36523653

3654+
/// Returns 'true' if \ref decl has been allocated a definition
3655+
/// *and* the definition was marked as completed. There are currently
3656+
/// situations in which LLDB marks a definition as `isCompleteDefinition`
3657+
/// while no definition was allocated. This function guards against those
3658+
/// situations.
3659+
static bool HasCompleteDefinition(clang::CXXRecordDecl *decl) {
3660+
return decl && decl->hasDefinition() && decl->isCompleteDefinition();
3661+
}
3662+
36533663
bool TypeSystemClang::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
36543664
CompilerType *dynamic_pointee_type,
36553665
bool check_cplusplus,
@@ -3732,8 +3742,9 @@ bool TypeSystemClang::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
37323742
if (check_cplusplus) {
37333743
clang::CXXRecordDecl *cxx_record_decl =
37343744
pointee_qual_type->getAsCXXRecordDecl();
3745+
37353746
if (cxx_record_decl) {
3736-
bool is_complete = cxx_record_decl->isCompleteDefinition();
3747+
bool is_complete = HasCompleteDefinition(cxx_record_decl);
37373748

37383749
if (is_complete)
37393750
success = cxx_record_decl->isDynamicClass();
@@ -3742,7 +3753,9 @@ bool TypeSystemClang::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
37423753
if (metadata)
37433754
success = metadata->GetIsDynamicCXXType();
37443755
else {
3745-
is_complete = GetType(pointee_qual_type).GetCompleteType();
3756+
// Make sure completion has actually completed the type.
3757+
is_complete = GetType(pointee_qual_type).GetCompleteType() &&
3758+
HasCompleteDefinition(cxx_record_decl);
37463759
if (is_complete)
37473760
success = cxx_record_decl->isDynamicClass();
37483761
else
@@ -5478,8 +5491,12 @@ TypeSystemClang::GetNumChildren(lldb::opaque_compiler_type_t type,
54785491
llvm::cast<clang::RecordType>(qual_type.getTypePtr());
54795492
const clang::RecordDecl *record_decl = record_type->getDecl();
54805493
assert(record_decl);
5494+
5495+
// CXXBaseSpecifiers are stored on the definition. If we don't have
5496+
// one at this point that means we "completed" the type without actually
5497+
// having allocated a definition.
54815498
const clang::CXXRecordDecl *cxx_record_decl =
5482-
llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
5499+
llvm::dyn_cast<clang::CXXRecordDecl>(record_decl)->getDefinition();
54835500
if (cxx_record_decl) {
54845501
if (omit_empty_base_classes) {
54855502
// Check each base classes to see if it or any of its base classes

0 commit comments

Comments
 (0)