jankratochvil created this revision. jankratochvil added reviewers: dblaikie, labath, clayborg. jankratochvil added a project: LLDB. Herald added a subscriber: JDevlieghere. jankratochvil requested review of this revision.
libstc++ 11 started using `[[no_unique_address]]` which crashes LLDB: echo -e '#include <memory>\nstd::unique_ptr<int> p;'|clang -Wall -g -c -o a.o -x c++ -;lldb -b ./a.o -o 'p p' lldb: clang/lib/CodeGen/CGRecordLayoutBuilder.cpp:742: void (anonymous namespace)::CGRecordLowering::clipTailPadding(): Assertion `Prior->Kind == MemberInfo::Field && "Only storage fields have tail padding!"' failed. As DWARF does not contain the `[[no_unique_address]]` attribute the patch adds it to every record member, could it be a problem? Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D101237 Files: lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp lldb/test/Shell/Expr/no_unique_address.cpp lldb/test/Shell/SymbolFile/NativePDB/bitfields.cpp Index: lldb/test/Shell/SymbolFile/NativePDB/bitfields.cpp =================================================================== --- lldb/test/Shell/SymbolFile/NativePDB/bitfields.cpp +++ lldb/test/Shell/SymbolFile/NativePDB/bitfields.cpp @@ -44,18 +44,18 @@ // CHECK: TranslationUnitDecl {{.*}} // CHECK: |-CXXRecordDecl {{.*}} struct Struct definition // CHECK: | |-FieldDecl {{.*}} A 'int' -// CHECK: | | `-IntegerLiteral {{.*}} 'int' 5 +// CHECK: | | {{.}}-IntegerLiteral {{.*}} 'int' 5 // CHECK: | |-FieldDecl {{.*}} B 'int' -// CHECK: | | `-IntegerLiteral {{.*}} 'int' 7 +// CHECK: | | {{.}}-IntegerLiteral {{.*}} 'int' 7 // CHECK: | |-FieldDecl {{.*}} C 'unsigned int' -// CHECK: | | `-IntegerLiteral {{.*}} 'int' 3 +// CHECK: | | {{.}}-IntegerLiteral {{.*}} 'int' 3 // CHECK: | |-FieldDecl {{.*}} D 'unsigned int' -// CHECK: | | `-IntegerLiteral {{.*}} 'int' 15 +// CHECK: | | {{.}}-IntegerLiteral {{.*}} 'int' 15 // CHECK: | |-FieldDecl {{.*}} E 'char' -// CHECK: | | `-IntegerLiteral {{.*}} 'int' 1 +// CHECK: | | {{.}}-IntegerLiteral {{.*}} 'int' 1 // CHECK: | |-FieldDecl {{.*}} F 'char' -// CHECK: | | `-IntegerLiteral {{.*}} 'int' 2 +// CHECK: | | {{.}}-IntegerLiteral {{.*}} 'int' 2 // CHECK: | |-FieldDecl {{.*}} G 'char' -// CHECK: | | `-IntegerLiteral {{.*}} 'int' 3 +// CHECK: | | {{.}}-IntegerLiteral {{.*}} 'int' 3 // CHECK: | `-FieldDecl {{.*}} H 'char' -// CHECK: | `-IntegerLiteral {{.*}} 'int' 3 +// CHECK: | {{.}}-IntegerLiteral {{.*}} 'int' 3 Index: lldb/test/Shell/Expr/no_unique_address.cpp =================================================================== --- /dev/null +++ lldb/test/Shell/Expr/no_unique_address.cpp @@ -0,0 +1,15 @@ +// Test LLDB does not assert on miscalculated field offsets. + +// RUN: %clang_host %s -g -c -o %t.o +// RUN: %lldb %t.o -o "p c.c" -o exit | FileCheck %s + +// CHECK: (lldb) p c.c +// CHECK-NEXT: (char) $0 = '\0' + +struct A {}; +struct B { + [[no_unique_address]] A a; +}; +struct C : B { + char c; +} c; Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp =================================================================== --- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -7196,6 +7196,7 @@ if (bit_width) field->setBitWidth(bit_width); SetMemberOwningModule(field, record_decl); + field->addAttr(NoUniqueAddressAttr::CreateImplicit(ast->getASTContext())); if (name.empty()) { // Determine whether this field corresponds to an anonymous struct or Index: lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp =================================================================== --- lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp +++ lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp @@ -99,9 +99,12 @@ if (ptr_obj) m_ptr_obj = ptr_obj->Clone(ConstString("pointer")).get(); - ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1); - if (del_obj) - m_del_obj = del_obj->Clone(ConstString("deleter")).get(); + // GCC 11 std::default_delete<...> has existing child with GetByteSize()==1. + if (tuple_sp->GetByteSize() > ptr_obj->GetByteSize()) { + ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1); + if (del_obj) + m_del_obj = del_obj->Clone(ConstString("deleter")).get(); + } if (m_ptr_obj) { Status error;
Index: lldb/test/Shell/SymbolFile/NativePDB/bitfields.cpp =================================================================== --- lldb/test/Shell/SymbolFile/NativePDB/bitfields.cpp +++ lldb/test/Shell/SymbolFile/NativePDB/bitfields.cpp @@ -44,18 +44,18 @@ // CHECK: TranslationUnitDecl {{.*}} // CHECK: |-CXXRecordDecl {{.*}} struct Struct definition // CHECK: | |-FieldDecl {{.*}} A 'int' -// CHECK: | | `-IntegerLiteral {{.*}} 'int' 5 +// CHECK: | | {{.}}-IntegerLiteral {{.*}} 'int' 5 // CHECK: | |-FieldDecl {{.*}} B 'int' -// CHECK: | | `-IntegerLiteral {{.*}} 'int' 7 +// CHECK: | | {{.}}-IntegerLiteral {{.*}} 'int' 7 // CHECK: | |-FieldDecl {{.*}} C 'unsigned int' -// CHECK: | | `-IntegerLiteral {{.*}} 'int' 3 +// CHECK: | | {{.}}-IntegerLiteral {{.*}} 'int' 3 // CHECK: | |-FieldDecl {{.*}} D 'unsigned int' -// CHECK: | | `-IntegerLiteral {{.*}} 'int' 15 +// CHECK: | | {{.}}-IntegerLiteral {{.*}} 'int' 15 // CHECK: | |-FieldDecl {{.*}} E 'char' -// CHECK: | | `-IntegerLiteral {{.*}} 'int' 1 +// CHECK: | | {{.}}-IntegerLiteral {{.*}} 'int' 1 // CHECK: | |-FieldDecl {{.*}} F 'char' -// CHECK: | | `-IntegerLiteral {{.*}} 'int' 2 +// CHECK: | | {{.}}-IntegerLiteral {{.*}} 'int' 2 // CHECK: | |-FieldDecl {{.*}} G 'char' -// CHECK: | | `-IntegerLiteral {{.*}} 'int' 3 +// CHECK: | | {{.}}-IntegerLiteral {{.*}} 'int' 3 // CHECK: | `-FieldDecl {{.*}} H 'char' -// CHECK: | `-IntegerLiteral {{.*}} 'int' 3 +// CHECK: | {{.}}-IntegerLiteral {{.*}} 'int' 3 Index: lldb/test/Shell/Expr/no_unique_address.cpp =================================================================== --- /dev/null +++ lldb/test/Shell/Expr/no_unique_address.cpp @@ -0,0 +1,15 @@ +// Test LLDB does not assert on miscalculated field offsets. + +// RUN: %clang_host %s -g -c -o %t.o +// RUN: %lldb %t.o -o "p c.c" -o exit | FileCheck %s + +// CHECK: (lldb) p c.c +// CHECK-NEXT: (char) $0 = '\0' + +struct A {}; +struct B { + [[no_unique_address]] A a; +}; +struct C : B { + char c; +} c; Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp =================================================================== --- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -7196,6 +7196,7 @@ if (bit_width) field->setBitWidth(bit_width); SetMemberOwningModule(field, record_decl); + field->addAttr(NoUniqueAddressAttr::CreateImplicit(ast->getASTContext())); if (name.empty()) { // Determine whether this field corresponds to an anonymous struct or Index: lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp =================================================================== --- lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp +++ lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp @@ -99,9 +99,12 @@ if (ptr_obj) m_ptr_obj = ptr_obj->Clone(ConstString("pointer")).get(); - ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1); - if (del_obj) - m_del_obj = del_obj->Clone(ConstString("deleter")).get(); + // GCC 11 std::default_delete<...> has existing child with GetByteSize()==1. + if (tuple_sp->GetByteSize() > ptr_obj->GetByteSize()) { + ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1); + if (del_obj) + m_del_obj = del_obj->Clone(ConstString("deleter")).get(); + } if (m_ptr_obj) { Status error;
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits