xref: /llvm-project/clang/test/CodeGen/linux-kernel-struct-union-initializer.c (revision 627746581b8fde4143533937130f420bbbdf9ddf)
1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --version 5
2 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=gnu11 -verify -emit-llvm %s -o - | FileCheck %s
3 // expected-no-diagnostics
4 
5 union U1 {
6   int x;
7   char y[16];
8 };
9 
10 struct S1 {
11   int x;
12   union U1 y;
13 };
14 
15 union U2 {
16   int x;
17   char y[16];
18 } __attribute__((__aligned__(32)));
19 
20 struct S2 {
21   int x;
22   long long y;
23   char z[8];
24 } __attribute__((__aligned__(32)));
25 
26 struct S3 {
27   char x;
28   unsigned char y : 4;
29   unsigned char z : 7;
30 } __attribute__((packed));
31 
32 union U1 global_u1 = {};
33 
34 union U1 global_u2 = {3};
35 
36 union U1 global_u2_from_cast = (union U1)3;
37 
38 struct S1 global_s1 = {};
39 
40 struct S1 global_s2 = {
41     .x = 3,
42 };
43 
44 struct S1 global_s3 = {.x = 3, .y = {.x = 6}};
45 
46 const union U1 global_const_u1 = {4};
47 struct S1 global_s3_from_const_u1 = {.y = global_const_u1};
48 
49 union U2 global_u3 = {};
50 
51 struct S2 global_s4 = {};
52 
53 struct S2 global_s5 = {.x = 1};
54 
55 struct S3 global_s6 = {101,  15, 123};
56 
57 // Test empty initializer for union.
58 //.
59 // CHECK: @global_u1 = global %union.U1 zeroinitializer, align 4
60 // CHECK: @global_u2 = global %union.U1 { i32 3, [12 x i8] zeroinitializer }, align 4
61 // CHECK: @global_u2_from_cast = global { i32, [12 x i8] } { i32 3, [12 x i8] zeroinitializer }, align 4
62 // CHECK: @global_s1 = global %struct.S1 zeroinitializer, align 4
63 // CHECK: @global_s2 = global %struct.S1 { i32 3, %union.U1 zeroinitializer }, align 4
64 // CHECK: @global_s3 = global %struct.S1 { i32 3, %union.U1 { i32 6, [12 x i8] zeroinitializer } }, align 4
65 // CHECK: @global_const_u1 = constant %union.U1 { i32 4, [12 x i8] zeroinitializer }, align 4
66 // CHECK: @global_s3_from_const_u1 = global %struct.S1 { i32 0, %union.U1 { i32 4, [12 x i8] zeroinitializer } }, align 4
67 // CHECK: @global_u3 = global %union.U2 zeroinitializer, align 32
68 // CHECK: @global_s4 = global { i32, [4 x i8], i64, [8 x i8], [8 x i8] } zeroinitializer, align 32
69 // CHECK: @global_s5 = global { i32, [4 x i8], i64, [8 x i8], [8 x i8] } { i32 1, [4 x i8] zeroinitializer, i64 0, [8 x i8] zeroinitializer, [8 x i8] zeroinitializer }, align 32
70 // CHECK: @global_s6 = global { i8, i8, i8 } { i8 101, i8 -65, i8 7 }, align 1
71 // CHECK: @test2.a = internal global %union.U1 zeroinitializer, align 4
72 // CHECK: @__const.test3.a = private unnamed_addr constant %union.U1 { i32 3, [12 x i8] zeroinitializer }, align 4
73 // CHECK: @test4.a = internal global %union.U1 { i32 3, [12 x i8] zeroinitializer }, align 4
74 // CHECK: @test6.s = internal global %struct.S1 zeroinitializer, align 4
75 // CHECK: @__const.test7.s = private unnamed_addr constant %struct.S1 { i32 3, %union.U1 zeroinitializer }, align 4
76 // CHECK: @test8.s = internal global %struct.S1 { i32 3, %union.U1 zeroinitializer }, align 4
77 // CHECK: @__const.test9.s = private unnamed_addr constant %struct.S1 { i32 3, %union.U1 { i32 6, [12 x i8] zeroinitializer } }, align 4
78 // CHECK: @test10.s = internal global %struct.S1 { i32 3, %union.U1 { i32 6, [12 x i8] zeroinitializer } }, align 4
79 // CHECK: @test12.a = internal global %union.U2 zeroinitializer, align 32
80 // CHECK: @test14.s = internal global { i32, [4 x i8], i64, [8 x i8], [8 x i8] } zeroinitializer, align 32
81 // CHECK: @__const.test15.s = private unnamed_addr constant { i32, [4 x i8], i64, [8 x i8], [8 x i8] } { i32 1, [4 x i8] zeroinitializer, i64 0, [8 x i8] zeroinitializer, [8 x i8] zeroinitializer }, align 32
82 // CHECK: @test16.s = internal global { i32, [4 x i8], i64, [8 x i8], [8 x i8] } { i32 1, [4 x i8] zeroinitializer, i64 0, [8 x i8] zeroinitializer, [8 x i8] zeroinitializer }, align 32
83 //.
84 // CHECK-LABEL: define dso_local void @test1(
85 // CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
86 // CHECK-NEXT:  [[ENTRY:.*:]]
87 // CHECK-NEXT:    [[A:%.*]] = alloca [[UNION_U1:%.*]], align 4
88 // CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[A]], i8 0, i64 16, i1 false)
89 // CHECK-NEXT:    ret void
90 //
91 void test1() {
92   union U1 a = {};
93 }
94 
95 // Test empty initializer for union. Use static variable.
96 // CHECK-LABEL: define dso_local void @test2(
97 // CHECK-SAME: ) #[[ATTR0]] {
98 // CHECK-NEXT:  [[ENTRY:.*:]]
99 // CHECK-NEXT:    ret void
100 //
101 void test2() {
102   static union U1 a = {};
103 }
104 
105 // Test only initializing a small field for union.
106 // CHECK-LABEL: define dso_local void @test3(
107 // CHECK-SAME: ) #[[ATTR0]] {
108 // CHECK-NEXT:  [[ENTRY:.*:]]
109 // CHECK-NEXT:    [[A:%.*]] = alloca [[UNION_U1:%.*]], align 4
110 // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[A]], ptr align 4 @__const.test3.a, i64 16, i1 false)
111 // CHECK-NEXT:    ret void
112 //
113 void test3() {
114   union U1 a = {3};
115 }
116 
117 // Test only initializing a small field for union. Use static variable.
118 // CHECK-LABEL: define dso_local void @test4(
119 // CHECK-SAME: ) #[[ATTR0]] {
120 // CHECK-NEXT:  [[ENTRY:.*:]]
121 // CHECK-NEXT:    ret void
122 //
123 void test4() {
124   static union U1 a = {3};
125 }
126 
127 // Test union in struct. Use empty initializer for the struct.
128 // CHECK-LABEL: define dso_local void @test5(
129 // CHECK-SAME: ) #[[ATTR0]] {
130 // CHECK-NEXT:  [[ENTRY:.*:]]
131 // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S1:%.*]], align 4
132 // CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[S]], i8 0, i64 20, i1 false)
133 // CHECK-NEXT:    ret void
134 //
135 void test5() {
136   struct S1 s = {};
137 }
138 
139 // Test union in struct. Use empty initializer for the struct. Use static variable.
140 // CHECK-LABEL: define dso_local void @test6(
141 // CHECK-SAME: ) #[[ATTR0]] {
142 // CHECK-NEXT:  [[ENTRY:.*:]]
143 // CHECK-NEXT:    ret void
144 //
145 void test6() {
146   static struct S1 s = {};
147 }
148 
149 // Test union in struct. Initialize other fields of the struct.
150 // CHECK-LABEL: define dso_local void @test7(
151 // CHECK-SAME: ) #[[ATTR0]] {
152 // CHECK-NEXT:  [[ENTRY:.*:]]
153 // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S1:%.*]], align 4
154 // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[S]], ptr align 4 @__const.test7.s, i64 20, i1 false)
155 // CHECK-NEXT:    ret void
156 //
157 void test7() {
158   struct S1 s = {
159       .x = 3,
160   };
161 }
162 
163 // Test union in struct. Initialize other fields of the struct. Use static variable.
164 // CHECK-LABEL: define dso_local void @test8(
165 // CHECK-SAME: ) #[[ATTR0]] {
166 // CHECK-NEXT:  [[ENTRY:.*:]]
167 // CHECK-NEXT:    ret void
168 //
169 void test8() {
170   static struct S1 s = {
171       .x = 3,
172   };
173 }
174 
175 // Test union in struct. Initialize a small field for union.
176 // CHECK-LABEL: define dso_local void @test9(
177 // CHECK-SAME: ) #[[ATTR0]] {
178 // CHECK-NEXT:  [[ENTRY:.*:]]
179 // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S1:%.*]], align 4
180 // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[S]], ptr align 4 @__const.test9.s, i64 20, i1 false)
181 // CHECK-NEXT:    ret void
182 //
183 void test9() {
184   struct S1 s = {.x = 3,
185                 .y = {
186                     .x = 6,
187                 }};
188 }
189 
190 // Test union in struct. Initialize a small field for union. Use static variable.
191 // CHECK-LABEL: define dso_local void @test10(
192 // CHECK-SAME: ) #[[ATTR0]] {
193 // CHECK-NEXT:  [[ENTRY:.*:]]
194 // CHECK-NEXT:    ret void
195 //
196 void test10() {
197   static struct S1 s = {.x = 3,
198                        .y = {
199                            .x = 6,
200                        }};
201 }
202 
203 // Test empty initializer for union with padding.
204 // CHECK-LABEL: define dso_local void @test11(
205 // CHECK-SAME: ) #[[ATTR0]] {
206 // CHECK-NEXT:  [[ENTRY:.*:]]
207 // CHECK-NEXT:    [[A:%.*]] = alloca [[UNION_U2:%.*]], align 32
208 // CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 32 [[A]], i8 0, i64 32, i1 false)
209 // CHECK-NEXT:    ret void
210 //
211 void test11() {
212   union U2 a = {};
213 }
214 
215 // Test empty initializer for union with padding. Use static variable.
216 // CHECK-LABEL: define dso_local void @test12(
217 // CHECK-SAME: ) #[[ATTR0]] {
218 // CHECK-NEXT:  [[ENTRY:.*:]]
219 // CHECK-NEXT:    ret void
220 //
221 void test12() {
222   static union U2 a = {};
223 }
224 
225 // Test empty initializer for struct with padding.
226 // CHECK-LABEL: define dso_local void @test13(
227 // CHECK-SAME: ) #[[ATTR0]] {
228 // CHECK-NEXT:  [[ENTRY:.*:]]
229 // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S2:%.*]], align 32
230 // CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 32 [[S]], i8 0, i64 32, i1 false)
231 // CHECK-NEXT:    ret void
232 //
233 void test13() {
234   struct S2 s = {};
235 }
236 
237 // Test empty initializer for struct with padding. Use static variable.
238 // CHECK-LABEL: define dso_local void @test14(
239 // CHECK-SAME: ) #[[ATTR0]] {
240 // CHECK-NEXT:  [[ENTRY:.*:]]
241 // CHECK-NEXT:    ret void
242 //
243 void test14() {
244   static struct S2 s = {};
245 }
246 
247 // Test partial initialization for struct with padding.
248 // CHECK-LABEL: define dso_local void @test15(
249 // CHECK-SAME: ) #[[ATTR0]] {
250 // CHECK-NEXT:  [[ENTRY:.*:]]
251 // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S2:%.*]], align 32
252 // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 32 [[S]], ptr align 32 @__const.test15.s, i64 32, i1 false)
253 // CHECK-NEXT:    ret void
254 //
255 void test15() {
256   struct S2 s = {.x = 1};
257 }
258 
259 // Test partial initialization for struct with padding. Use static variable.
260 // CHECK-LABEL: define dso_local void @test16(
261 // CHECK-SAME: ) #[[ATTR0]] {
262 // CHECK-NEXT:  [[ENTRY:.*:]]
263 // CHECK-NEXT:    ret void
264 //
265 void test16() {
266   static struct S2 s = {.x = 1};
267 }
268 //.
269 // CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
270 // CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
271 // CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
272 //.
273 // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
274 // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
275 //.
276