https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/97068
>From 1c924c866cc2de5e9e1d84ce0b185e9dacefd4ec Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Fri, 28 Jun 2024 15:29:54 +0100 Subject: [PATCH 1/2] [lldb][test] Add tests for alignof on class with overlapping bases 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`. --- .../no_unique_address-base-alignment.cpp | 30 ++++++++++++++ .../Shell/SymbolFile/DWARF/packed-alignof.cpp | 41 +++++++++++++++++++ lldb/test/Shell/SymbolFile/DWARF/packed.cpp | 14 +++++++ 3 files changed, 85 insertions(+) create mode 100644 lldb/test/Shell/SymbolFile/DWARF/no_unique_address-base-alignment.cpp create mode 100644 lldb/test/Shell/SymbolFile/DWARF/packed-alignof.cpp 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..634d461e6ff19 --- /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 + +// CHECK: (lldb) expr alignof(OverlappingDerived) +// CHECK-NEXT: ${{.*}} = 4 +// CHECK: (lldb) expr sizeof(OverlappingDerived) +// CHECK-NEXT: ${{.*}} = 4 + +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); + +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..a15e88f0b65df --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/packed-alignof.cpp @@ -0,0 +1,41 @@ +// 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 + +// CHECK: (lldb) expr alignof(base) +// CHECK-NEXT: ${{.*}} = 4 +// CHECK: (lldb) expr alignof(packed_base) +// CHECK-NEXT: ${{.*}} = 1 +// CHECK: (lldb) expr alignof(derived) +// CHECK-NEXT: ${{.*}} = 2 +// CHECK: (lldb) expr sizeof(derived) +// CHECK-NEXT: ${{.*}} = 16 + +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); + +// LLDB incorrectly calculates alignof(packed_base) +struct __attribute__((packed)) packed_base { int x; }; +static_assert(alignof(packed_base) == 1); + +struct derived : packed, packed_base { + short s; +} g_derived; +static_assert(alignof(derived) == 2); +static_assert(sizeof(derived) == 16); + +int main() {} diff --git a/lldb/test/Shell/SymbolFile/DWARF/packed.cpp b/lldb/test/Shell/SymbolFile/DWARF/packed.cpp index 640a2e0454c92..135808f46d7ea 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/packed.cpp +++ b/lldb/test/Shell/SymbolFile/DWARF/packed.cpp @@ -4,6 +4,8 @@ // 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) @@ -16,6 +18,11 @@ // CHECK: (lldb) expr sizeof(packed_and_aligned) // CHECK-NEXT: ${{.*}} = 16 +// CHECK: (lldb) expr alignof(derived) +// CHECK-NEXT: ${{.*}} = 1 +// CHECK: (lldb) expr sizeof(derived) +// CHECK-NEXT: ${{.*}} = 13 + struct __attribute__((packed)) packed { int x; char y; @@ -32,4 +39,11 @@ struct __attribute__((packed, aligned(16))) packed_and_aligned { static_assert(alignof(packed_and_aligned) == 16); static_assert(sizeof(packed_and_aligned) == 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); + int main() {} >From cbbd6cc7b0ae973f7cca1bd7ee56ba87a95235c4 Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Fri, 28 Jun 2024 18:28:28 +0100 Subject: [PATCH 2/2] fixup! move CHECKs closer to their relevant static_asserts --- .../no_unique_address-base-alignment.cpp | 10 +++---- .../Shell/SymbolFile/DWARF/packed-alignof.cpp | 20 +++++++------ lldb/test/Shell/SymbolFile/DWARF/packed.cpp | 30 +++++++++---------- 3 files changed, 31 insertions(+), 29 deletions(-) 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 index 634d461e6ff19..15d8de0e3ee98 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/no_unique_address-base-alignment.cpp +++ b/lldb/test/Shell/SymbolFile/DWARF/no_unique_address-base-alignment.cpp @@ -6,11 +6,6 @@ // RUN: -o "expr sizeof(OverlappingDerived)" \ // RUN: -o exit | FileCheck %s -// CHECK: (lldb) expr alignof(OverlappingDerived) -// CHECK-NEXT: ${{.*}} = 4 -// CHECK: (lldb) expr sizeof(OverlappingDerived) -// CHECK-NEXT: ${{.*}} = 4 - struct Empty {}; struct OverlappingBase { @@ -27,4 +22,9 @@ 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 index a15e88f0b65df..dcc02736a9be7 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/packed-alignof.cpp +++ b/lldb/test/Shell/SymbolFile/DWARF/packed-alignof.cpp @@ -8,15 +8,6 @@ // RUN: -o "expr sizeof(derived)" \ // RUN: -o exit | FileCheck %s -// CHECK: (lldb) expr alignof(base) -// CHECK-NEXT: ${{.*}} = 4 -// CHECK: (lldb) expr alignof(packed_base) -// CHECK-NEXT: ${{.*}} = 1 -// CHECK: (lldb) expr alignof(derived) -// CHECK-NEXT: ${{.*}} = 2 -// CHECK: (lldb) expr sizeof(derived) -// CHECK-NEXT: ${{.*}} = 16 - struct __attribute__((packed)) packed { int x; char y; @@ -28,14 +19,25 @@ 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 135808f46d7ea..360293b1d4184 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/packed.cpp +++ b/lldb/test/Shell/SymbolFile/DWARF/packed.cpp @@ -8,21 +8,6 @@ // 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 - -// CHECK: (lldb) expr alignof(derived) -// CHECK-NEXT: ${{.*}} = 1 -// CHECK: (lldb) expr sizeof(derived) -// CHECK-NEXT: ${{.*}} = 13 - struct __attribute__((packed)) packed { int x; char y; @@ -31,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; @@ -39,6 +29,11 @@ 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); @@ -46,4 +41,9 @@ 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