diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index 5169be204c14d..b7aab51660b5e 100644 --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -950,6 +950,9 @@ void CGRecordLowering::calculateZeroInit() { // Verify accumulateBitfields computed the correct storage representations. void CGRecordLowering::checkBitfieldClipping(bool IsNonVirtualBaseType) const { #ifndef NDEBUG + if (Context.getLangOpts().DebuggerSupport) + return; + auto ScissorOffset = calculateTailClippingOffset(IsNonVirtualBaseType); auto Tail = CharUnits::Zero(); for (const auto &M : Members) { @@ -1008,7 +1011,8 @@ void CGRecordLowering::insertPadding() { if (!Member->Data) continue; CharUnits Offset = Member->Offset; - assert(Offset >= Size); + if (!Context.getLangOpts().DebuggerSupport) + assert(Offset >= Size); // Insert padding if we need to. if (Offset != Size.alignTo(Packed ? CharUnits::One() : getAlignment(Member->Data))) @@ -1138,8 +1142,9 @@ CodeGenTypes::ComputeRecordLayout(const RecordDecl *D, llvm::StructType *Ty) { const ASTRecordLayout &Layout = getContext().getASTRecordLayout(D); uint64_t TypeSizeInBits = getContext().toBits(Layout.getSize()); - assert(TypeSizeInBits == getDataLayout().getTypeAllocSizeInBits(Ty) && - "Type size mismatch!"); + if (!Context.getLangOpts().DebuggerSupport) + assert(TypeSizeInBits == getDataLayout().getTypeAllocSizeInBits(Ty) && + "Type size mismatch!"); if (BaseTy) { CharUnits NonVirtualSize = Layout.getNonVirtualSize(); @@ -1147,9 +1152,10 @@ CodeGenTypes::ComputeRecordLayout(const RecordDecl *D, llvm::StructType *Ty) { uint64_t AlignedNonVirtualTypeSizeInBits = getContext().toBits(NonVirtualSize); - assert(AlignedNonVirtualTypeSizeInBits == - getDataLayout().getTypeAllocSizeInBits(BaseTy) && - "Type size mismatch!"); + if (!Context.getLangOpts().DebuggerSupport) + assert(AlignedNonVirtualTypeSizeInBits == + getDataLayout().getTypeAllocSizeInBits(BaseTy) && + "Type size mismatch!"); } // Verify that the LLVM and AST field offsets agree. diff --git a/lldb/test/API/lang/cpp/no_unique_address/Makefile b/lldb/test/API/lang/cpp/no_unique_address/Makefile new file mode 100644 index 0000000000000..99998b20bcb05 --- /dev/null +++ b/lldb/test/API/lang/cpp/no_unique_address/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/lang/cpp/no_unique_address/TestNoUniqueAddress.py b/lldb/test/API/lang/cpp/no_unique_address/TestNoUniqueAddress.py new file mode 100644 index 0000000000000..d16aaa14153fd --- /dev/null +++ b/lldb/test/API/lang/cpp/no_unique_address/TestNoUniqueAddress.py @@ -0,0 +1,67 @@ +""" +Test that LLDB correctly handles fields +marked with [[no_unique_address]]. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class NoUniqueAddressTestCase(TestBase): + def test(self): + self.build() + lldbutil.run_to_source_breakpoint( + self, "return 0", lldb.SBFileSpec("main.cpp", False) + ) + + # Qualified/unqualified lookup to templates in namespace + self.expect_expr( + "b1", + result_type="basic::Foo", + result_children=[ValueCheck(name="a", type="Empty")], + ) + + self.expect_expr( + "b2", + result_type="bases::Foo", + result_children=[ + ValueCheck( + type="bases::B", children=[ValueCheck(name="x", type="Empty")] + ), + ValueCheck( + type="bases::A", + children=[ + ValueCheck(name="c", type="long", value="1"), + ValueCheck(name="d", type="long", value="2"), + ], + ), + ValueCheck( + type="bases::C", children=[ValueCheck(name="x", type="Empty")] + ), + ], + ) + self.expect_expr( + "b3", + result_type="bases::Bar", + result_children=[ + ValueCheck( + type="bases::B", children=[ValueCheck(name="x", type="Empty")] + ), + ValueCheck( + type="bases::C", children=[ValueCheck(name="x", type="Empty")] + ), + ValueCheck( + type="bases::A", + children=[ + ValueCheck(name="c", type="long", value="5"), + ValueCheck(name="d", type="long", value="6"), + ], + ), + ], + ) + + self.expect("frame var b1") + self.expect("frame var b2") + self.expect("frame var b3") diff --git a/lldb/test/API/lang/cpp/no_unique_address/main.cpp b/lldb/test/API/lang/cpp/no_unique_address/main.cpp new file mode 100644 index 0000000000000..424fa90859cea --- /dev/null +++ b/lldb/test/API/lang/cpp/no_unique_address/main.cpp @@ -0,0 +1,35 @@ +struct Empty {}; + +namespace basic { +struct Foo { + [[no_unique_address]] Empty a; +}; +} // namespace basic + +namespace bases { +struct A { + long c, d; +}; + +struct B { + [[no_unique_address]] Empty x; +}; + +struct C { + [[no_unique_address]] Empty x; +}; + +struct Foo : B, A, C {}; +struct Bar : B, C, A {}; +} // namespace bases + +int main() { + basic::Foo b1; + bases::Foo b2; + bases::Bar b3; + b2.c = 1; + b2.d = 2; + b3.c = 5; + b3.d = 6; + return 0; +}