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