1 // RUN: %clang_cc1 -std=c++2a %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s
2 // RUN: %clang_cc1 -std=c++2a %s -emit-llvm -o - -triple x86_64-linux-gnu -O2 -disable-llvm-passes | FileCheck %s --check-prefix=CHECK-OPT
4 struct A
{ ~A(); int n
; char c
[3]; };
5 struct B
{ [[no_unique_address
]] A a
; char k
; };
6 // CHECK-DAG: @b ={{.*}} global { i32, [3 x i8], i8 } { i32 1, [3 x i8] c"\02\03\04", i8 5 }
11 struct E
{ int e
; [[no_unique_address
]] D d
; char k
; };
12 // CHECK-DAG: @e ={{.*}} global { i32, i32, [3 x i8], i8 } { i32 1, i32 2, [3 x i8] c"\03\04\05", i8 6 }
13 E e
= {1, 2, 3, 4, 5, 6};
19 [[no_unique_address
]] Empty1 e1
;
21 [[no_unique_address
]] Empty2 e2
;
23 [[no_unique_address
]] Empty3 e3
;
25 // CHECK-DAG: @he ={{.*}} global %{{[^ ]*}} { i32 1, i32 2 }
26 HasEmpty he
= {{}, 1, {}, 2, {}};
28 struct HasEmptyDuplicates
{
29 [[no_unique_address
]] Empty1 e1
; // +0
31 [[no_unique_address
]] Empty1 e2
; // +4
33 [[no_unique_address
]] Empty1 e3
; // +8
35 // CHECK-DAG: @off1 ={{.*}} global i64 0
36 Empty1
HasEmptyDuplicates::*off1
= &HasEmptyDuplicates::e1
;
37 // CHECK-DAG: @off2 ={{.*}} global i64 4
38 Empty1
HasEmptyDuplicates::*off2
= &HasEmptyDuplicates::e2
;
39 // CHECK-DAG: @off3 ={{.*}} global i64 8
40 Empty1
HasEmptyDuplicates::*off3
= &HasEmptyDuplicates::e3
;
42 // CHECK-DAG: @hed ={{.*}} global %{{[^ ]*}} { i32 1, i32 2, [4 x i8] undef }
43 HasEmptyDuplicates hed
= {{}, 1, {}, 2, {}};
45 struct __attribute__((packed
, aligned(2))) PackedAndPadded
{
50 struct WithPackedAndPadded
{
51 [[no_unique_address
]] PackedAndPadded pap
;
54 // CHECK-DAG: @wpap ={{.*}} global <{ i8, i32, i8 }> <{ i8 1, i32 2, i8 3 }>
55 WithPackedAndPadded wpap
= {1, 2, 3};
58 [[no_unique_address
]] Empty1 e1
, e2
, e3
, e4
;
61 static_assert(sizeof(FieldOverlap
) == 4);
62 // CHECK-DAG: @fo ={{.*}} global %{{[^ ]*}} { i32 1234 }
63 FieldOverlap fo
= {{}, {}, {}, {}, 1234};
65 // CHECK-DAG: @e1 ={{.*}} constant ptr @fo
67 // CHECK-DAG: @e2 ={{.*}} constant ptr getelementptr (i8, ptr @fo, i64 1)
70 // CHECK-LABEL: accessE1
71 // CHECK: ret ptr %{{.*}}
72 Empty1
&accessE1(FieldOverlap
&fo
) { return fo
.e1
; }
74 // CHECK-LABEL: accessE2
75 // CHECK: %[[ADJUSTED:.*]] = getelementptr inbounds i8, ptr %{{.*}}, i64 1
76 // CHECK: ret ptr %[[ADJUSTED]]
77 Empty1
&accessE2(FieldOverlap
&fo
) { return fo
.e2
; }
79 struct LaterDeclaredFieldHasLowerOffset
{
82 [[no_unique_address
]] Empty1 e
;
84 // CHECK-OPT-LABEL: @_Z41loadWhereLaterDeclaredFieldHasLowerOffset
85 int loadWhereLaterDeclaredFieldHasLowerOffset(LaterDeclaredFieldHasLowerOffset
&a
) {
86 // CHECK-OPT: getelementptr
87 // CHECK-OPT: load {{.*}}, !tbaa ![[TBAA_AB:[0-9]*]]
90 // Note, never emit TBAA for zero-size fields.
91 // CHECK-OPT: ![[TBAA_AB]] = !{![[TBAA_A:[0-9]*]], ![[TBAA_INT:[0-9]*]], i64 4}
92 // CHECK-OPT: ![[TBAA_A]] = !{!"_ZTS32LaterDeclaredFieldHasLowerOffset", ![[TBAA_INT]], i64 0, ![[TBAA_INT]], i64 4}
94 struct NonTrivialInit
{
97 struct HasZeroSizedFieldWithNonTrivialInit
{
99 [[no_unique_address
]] NonTrivialInit b
;
101 HasZeroSizedFieldWithNonTrivialInit testHasZeroSizedFieldWithNonTrivialInit
= {.a
= 1};
102 // CHECK-LABEL: define {{.*}}cxx_global_var_init
103 // CHECK: call {{.*}}@_ZN14NonTrivialInitC1Ev({{.*}}@testHasZeroSizedFieldWithNonTrivialInit