Skip to content

Commit ed95844

Browse files
authored
[lldb][test] Add tests for alignof on class with overlapping bases (#97068)
Follow-up to #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 #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`.
1 parent a7bf412 commit ed95844

File tree

3 files changed

+97
-10
lines changed

3 files changed

+97
-10
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// XFAIL: *
2+
3+
// RUN: %clangxx_host -gdwarf -o %t %s
4+
// RUN: %lldb %t \
5+
// RUN: -o "expr alignof(OverlappingDerived)" \
6+
// RUN: -o "expr sizeof(OverlappingDerived)" \
7+
// RUN: -o exit | FileCheck %s
8+
9+
struct Empty {};
10+
11+
struct OverlappingBase {
12+
[[no_unique_address]] Empty e;
13+
};
14+
static_assert(sizeof(OverlappingBase) == 1);
15+
static_assert(alignof(OverlappingBase) == 1);
16+
17+
struct Base {
18+
int mem;
19+
};
20+
21+
struct OverlappingDerived : Base, OverlappingBase {};
22+
static_assert(alignof(OverlappingDerived) == 4);
23+
static_assert(sizeof(OverlappingDerived) == 4);
24+
25+
// CHECK: (lldb) expr alignof(OverlappingDerived)
26+
// CHECK-NEXT: ${{.*}} = 4
27+
// CHECK: (lldb) expr sizeof(OverlappingDerived)
28+
// CHECK-NEXT: ${{.*}} = 4
29+
30+
int main() { OverlappingDerived d; }
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// XFAIL: *
2+
//
3+
// RUN: %clangxx_host -gdwarf -o %t %s
4+
// RUN: %lldb %t \
5+
// RUN: -o "expr alignof(base)" \
6+
// RUN: -o "expr alignof(packed_base)" \
7+
// RUN: -o "expr alignof(derived)" \
8+
// RUN: -o "expr sizeof(derived)" \
9+
// RUN: -o exit | FileCheck %s
10+
11+
struct __attribute__((packed)) packed {
12+
int x;
13+
char y;
14+
int z;
15+
} g_packed_struct;
16+
17+
// LLDB incorrectly calculates alignof(base)
18+
struct foo {};
19+
struct base : foo { int x; };
20+
static_assert(alignof(base) == 4);
21+
22+
// CHECK: (lldb) expr alignof(base)
23+
// CHECK-NEXT: ${{.*}} = 4
24+
25+
// LLDB incorrectly calculates alignof(packed_base)
26+
struct __attribute__((packed)) packed_base { int x; };
27+
static_assert(alignof(packed_base) == 1);
28+
29+
// CHECK: (lldb) expr alignof(packed_base)
30+
// CHECK-NEXT: ${{.*}} = 1
31+
32+
struct derived : packed, packed_base {
33+
short s;
34+
} g_derived;
35+
static_assert(alignof(derived) == 2);
36+
static_assert(sizeof(derived) == 16);
37+
38+
// CHECK: (lldb) expr alignof(derived)
39+
// CHECK-NEXT: ${{.*}} = 2
40+
// CHECK: (lldb) expr sizeof(derived)
41+
// CHECK-NEXT: ${{.*}} = 16
42+
43+
int main() {}

lldb/test/Shell/SymbolFile/DWARF/packed.cpp

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,10 @@
44
// RUN: -o "expr sizeof(packed)" \
55
// RUN: -o "expr alignof(packed_and_aligned)" \
66
// RUN: -o "expr sizeof(packed_and_aligned)" \
7+
// RUN: -o "expr alignof(derived)" \
8+
// RUN: -o "expr sizeof(derived)" \
79
// RUN: -o exit | FileCheck %s
810

9-
// CHECK: (lldb) expr alignof(packed)
10-
// CHECK-NEXT: ${{.*}} = 1
11-
// CHECK: (lldb) expr sizeof(packed)
12-
// CHECK-NEXT: ${{.*}} = 9
13-
14-
// CHECK: (lldb) expr alignof(packed_and_aligned)
15-
// CHECK-NEXT: ${{.*}} = 16
16-
// CHECK: (lldb) expr sizeof(packed_and_aligned)
17-
// CHECK-NEXT: ${{.*}} = 16
18-
1911
struct __attribute__((packed)) packed {
2012
int x;
2113
char y;
@@ -24,6 +16,11 @@ struct __attribute__((packed)) packed {
2416
static_assert(alignof(packed) == 1);
2517
static_assert(sizeof(packed) == 9);
2618

19+
// CHECK: (lldb) expr alignof(packed)
20+
// CHECK-NEXT: ${{.*}} = 1
21+
// CHECK: (lldb) expr sizeof(packed)
22+
// CHECK-NEXT: ${{.*}} = 9
23+
2724
struct __attribute__((packed, aligned(16))) packed_and_aligned {
2825
int x;
2926
char y;
@@ -32,4 +29,21 @@ struct __attribute__((packed, aligned(16))) packed_and_aligned {
3229
static_assert(alignof(packed_and_aligned) == 16);
3330
static_assert(sizeof(packed_and_aligned) == 16);
3431

32+
// CHECK: (lldb) expr alignof(packed_and_aligned)
33+
// CHECK-NEXT: ${{.*}} = 16
34+
// CHECK: (lldb) expr sizeof(packed_and_aligned)
35+
// CHECK-NEXT: ${{.*}} = 16
36+
37+
struct __attribute__((packed)) packed_base { int x; };
38+
static_assert(alignof(packed_base) == 1);
39+
40+
struct derived : packed, packed_base {} g_derived;
41+
static_assert(alignof(derived) == 1);
42+
static_assert(sizeof(derived) == 13);
43+
44+
// CHECK: (lldb) expr alignof(derived)
45+
// CHECK-NEXT: ${{.*}} = 1
46+
// CHECK: (lldb) expr sizeof(derived)
47+
// CHECK-NEXT: ${{.*}} = 13
48+
3549
int main() {}

0 commit comments

Comments
 (0)