Author: Michael Buch Date: 2024-06-29T08:38:17+01:00 New Revision: ed9584457def4a51596b9d72ce76a1bfed88fa30
URL: https://github.com/llvm/llvm-project/commit/ed9584457def4a51596b9d72ce76a1bfed88fa30 DIFF: https://github.com/llvm/llvm-project/commit/ed9584457def4a51596b9d72ce76a1bfed88fa30.diff LOG: [lldb][test] Add tests for alignof on class with overlapping bases (#97068) Follow-up to https://github.com/llvm/llvm-project/pull/96932 Adds XFAILed test where LLDB incorrectly infers the alignment of a derived class whose bases are overlapping due to [[no_unique_address]]. Specifically, the `InferAlignment` code-path of the `ItaniumRecordLayoutBuilder` assumes that overlapping base offsets imply a packed structure and thus sets alignment to 1. See discussion in https://github.com/llvm/llvm-project/pull/93809. Also adds test where LLDB correctly infers an alignment of `1` when a packed base class is overlapping with other bases. Lastly, there were a couple of `alignof` inconsistencies which I encapsulated in an XFAIL-ed `packed-alignof.cpp`. Added: lldb/test/Shell/SymbolFile/DWARF/no_unique_address-base-alignment.cpp lldb/test/Shell/SymbolFile/DWARF/packed-alignof.cpp Modified: lldb/test/Shell/SymbolFile/DWARF/packed.cpp Removed: ################################################################################ diff --git a/lldb/test/Shell/SymbolFile/DWARF/no_unique_address-base-alignment.cpp b/lldb/test/Shell/SymbolFile/DWARF/no_unique_address-base-alignment.cpp new file mode 100644 index 0000000000000..15d8de0e3ee98 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/no_unique_address-base-alignment.cpp @@ -0,0 +1,30 @@ +// XFAIL: * + +// RUN: %clangxx_host -gdwarf -o %t %s +// RUN: %lldb %t \ +// RUN: -o "expr alignof(OverlappingDerived)" \ +// RUN: -o "expr sizeof(OverlappingDerived)" \ +// RUN: -o exit | FileCheck %s + +struct Empty {}; + +struct OverlappingBase { + [[no_unique_address]] Empty e; +}; +static_assert(sizeof(OverlappingBase) == 1); +static_assert(alignof(OverlappingBase) == 1); + +struct Base { + int mem; +}; + +struct OverlappingDerived : Base, OverlappingBase {}; +static_assert(alignof(OverlappingDerived) == 4); +static_assert(sizeof(OverlappingDerived) == 4); + +// CHECK: (lldb) expr alignof(OverlappingDerived) +// CHECK-NEXT: ${{.*}} = 4 +// CHECK: (lldb) expr sizeof(OverlappingDerived) +// CHECK-NEXT: ${{.*}} = 4 + +int main() { OverlappingDerived d; } diff --git a/lldb/test/Shell/SymbolFile/DWARF/packed-alignof.cpp b/lldb/test/Shell/SymbolFile/DWARF/packed-alignof.cpp new file mode 100644 index 0000000000000..dcc02736a9be7 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/packed-alignof.cpp @@ -0,0 +1,43 @@ +// XFAIL: * +// +// RUN: %clangxx_host -gdwarf -o %t %s +// RUN: %lldb %t \ +// RUN: -o "expr alignof(base)" \ +// RUN: -o "expr alignof(packed_base)" \ +// RUN: -o "expr alignof(derived)" \ +// RUN: -o "expr sizeof(derived)" \ +// RUN: -o exit | FileCheck %s + +struct __attribute__((packed)) packed { + int x; + char y; + int z; +} g_packed_struct; + +// LLDB incorrectly calculates alignof(base) +struct foo {}; +struct base : foo { int x; }; +static_assert(alignof(base) == 4); + +// CHECK: (lldb) expr alignof(base) +// CHECK-NEXT: ${{.*}} = 4 + +// LLDB incorrectly calculates alignof(packed_base) +struct __attribute__((packed)) packed_base { int x; }; +static_assert(alignof(packed_base) == 1); + +// CHECK: (lldb) expr alignof(packed_base) +// CHECK-NEXT: ${{.*}} = 1 + +struct derived : packed, packed_base { + short s; +} g_derived; +static_assert(alignof(derived) == 2); +static_assert(sizeof(derived) == 16); + +// CHECK: (lldb) expr alignof(derived) +// CHECK-NEXT: ${{.*}} = 2 +// CHECK: (lldb) expr sizeof(derived) +// CHECK-NEXT: ${{.*}} = 16 + +int main() {} diff --git a/lldb/test/Shell/SymbolFile/DWARF/packed.cpp b/lldb/test/Shell/SymbolFile/DWARF/packed.cpp index 640a2e0454c92..360293b1d4184 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/packed.cpp +++ b/lldb/test/Shell/SymbolFile/DWARF/packed.cpp @@ -4,18 +4,10 @@ // RUN: -o "expr sizeof(packed)" \ // RUN: -o "expr alignof(packed_and_aligned)" \ // RUN: -o "expr sizeof(packed_and_aligned)" \ +// RUN: -o "expr alignof(derived)" \ +// RUN: -o "expr sizeof(derived)" \ // RUN: -o exit | FileCheck %s -// CHECK: (lldb) expr alignof(packed) -// CHECK-NEXT: ${{.*}} = 1 -// CHECK: (lldb) expr sizeof(packed) -// CHECK-NEXT: ${{.*}} = 9 - -// CHECK: (lldb) expr alignof(packed_and_aligned) -// CHECK-NEXT: ${{.*}} = 16 -// CHECK: (lldb) expr sizeof(packed_and_aligned) -// CHECK-NEXT: ${{.*}} = 16 - struct __attribute__((packed)) packed { int x; char y; @@ -24,6 +16,11 @@ struct __attribute__((packed)) packed { static_assert(alignof(packed) == 1); static_assert(sizeof(packed) == 9); +// CHECK: (lldb) expr alignof(packed) +// CHECK-NEXT: ${{.*}} = 1 +// CHECK: (lldb) expr sizeof(packed) +// CHECK-NEXT: ${{.*}} = 9 + struct __attribute__((packed, aligned(16))) packed_and_aligned { int x; char y; @@ -32,4 +29,21 @@ struct __attribute__((packed, aligned(16))) packed_and_aligned { static_assert(alignof(packed_and_aligned) == 16); static_assert(sizeof(packed_and_aligned) == 16); +// CHECK: (lldb) expr alignof(packed_and_aligned) +// CHECK-NEXT: ${{.*}} = 16 +// CHECK: (lldb) expr sizeof(packed_and_aligned) +// CHECK-NEXT: ${{.*}} = 16 + +struct __attribute__((packed)) packed_base { int x; }; +static_assert(alignof(packed_base) == 1); + +struct derived : packed, packed_base {} g_derived; +static_assert(alignof(derived) == 1); +static_assert(sizeof(derived) == 13); + +// CHECK: (lldb) expr alignof(derived) +// CHECK-NEXT: ${{.*}} = 1 +// CHECK: (lldb) expr sizeof(derived) +// CHECK-NEXT: ${{.*}} = 13 + int main() {} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits