[Lldb-commits] [lldb] [lldb][test] Add tests for alignof on class with overlapping bases (PR #97068)

Michael Buch via lldb-commits lldb-commits at lists.llvm.org
Fri Jun 28 10:28:40 PDT 2024


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 <michaelbuch12 at 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 <michaelbuch12 at 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() {}



More information about the lldb-commits mailing list