|  | // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --version 5 | 
|  | // RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=gnu11 -verify -emit-llvm %s -o - | FileCheck %s | 
|  | // expected-no-diagnostics | 
|  |  | 
|  | union U1 { | 
|  | int x; | 
|  | char y[16]; | 
|  | }; | 
|  |  | 
|  | struct S1 { | 
|  | int x; | 
|  | union U1 y; | 
|  | }; | 
|  |  | 
|  | union U2 { | 
|  | int x; | 
|  | char y[16]; | 
|  | } __attribute__((__aligned__(32))); | 
|  |  | 
|  | struct S2 { | 
|  | int x; | 
|  | long long y; | 
|  | char z[8]; | 
|  | } __attribute__((__aligned__(32))); | 
|  |  | 
|  | struct S3 { | 
|  | char x; | 
|  | unsigned char y : 4; | 
|  | unsigned char z : 7; | 
|  | } __attribute__((packed)); | 
|  |  | 
|  | union U1 global_u1 = {}; | 
|  |  | 
|  | union U1 global_u2 = {3}; | 
|  |  | 
|  | union U1 global_u2_from_cast = (union U1)3; | 
|  |  | 
|  | struct S1 global_s1 = {}; | 
|  |  | 
|  | struct S1 global_s2 = { | 
|  | .x = 3, | 
|  | }; | 
|  |  | 
|  | struct S1 global_s3 = {.x = 3, .y = {.x = 6}}; | 
|  |  | 
|  | const union U1 global_const_u1 = {4}; | 
|  | struct S1 global_s3_from_const_u1 = {.y = global_const_u1}; | 
|  |  | 
|  | union U2 global_u3 = {}; | 
|  |  | 
|  | struct S2 global_s4 = {}; | 
|  |  | 
|  | struct S2 global_s5 = {.x = 1}; | 
|  |  | 
|  | struct S3 global_s6 = {101,  15, 123}; | 
|  |  | 
|  | // Test empty initializer for union. | 
|  | //. | 
|  | // CHECK: @global_u1 = global %union.U1 zeroinitializer, align 4 | 
|  | // CHECK: @global_u2 = global %union.U1 { i32 3, [12 x i8] zeroinitializer }, align 4 | 
|  | // CHECK: @global_u2_from_cast = global { i32, [12 x i8] } { i32 3, [12 x i8] zeroinitializer }, align 4 | 
|  | // CHECK: @global_s1 = global %struct.S1 zeroinitializer, align 4 | 
|  | // CHECK: @global_s2 = global %struct.S1 { i32 3, %union.U1 zeroinitializer }, align 4 | 
|  | // CHECK: @global_s3 = global %struct.S1 { i32 3, %union.U1 { i32 6, [12 x i8] zeroinitializer } }, align 4 | 
|  | // CHECK: @global_const_u1 = constant %union.U1 { i32 4, [12 x i8] zeroinitializer }, align 4 | 
|  | // CHECK: @global_s3_from_const_u1 = global %struct.S1 { i32 0, %union.U1 { i32 4, [12 x i8] zeroinitializer } }, align 4 | 
|  | // CHECK: @global_u3 = global %union.U2 zeroinitializer, align 32 | 
|  | // CHECK: @global_s4 = global { i32, [4 x i8], i64, [8 x i8], [8 x i8] } zeroinitializer, align 32 | 
|  | // 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 | 
|  | // CHECK: @global_s6 = global { i8, i8, i8 } { i8 101, i8 -65, i8 7 }, align 1 | 
|  | // CHECK: @test2.a = internal global %union.U1 zeroinitializer, align 4 | 
|  | // CHECK: @__const.test3.a = private unnamed_addr constant %union.U1 { i32 3, [12 x i8] zeroinitializer }, align 4 | 
|  | // CHECK: @test4.a = internal global %union.U1 { i32 3, [12 x i8] zeroinitializer }, align 4 | 
|  | // CHECK: @test6.s = internal global %struct.S1 zeroinitializer, align 4 | 
|  | // CHECK: @__const.test7.s = private unnamed_addr constant %struct.S1 { i32 3, %union.U1 zeroinitializer }, align 4 | 
|  | // CHECK: @test8.s = internal global %struct.S1 { i32 3, %union.U1 zeroinitializer }, align 4 | 
|  | // CHECK: @__const.test9.s = private unnamed_addr constant %struct.S1 { i32 3, %union.U1 { i32 6, [12 x i8] zeroinitializer } }, align 4 | 
|  | // CHECK: @test10.s = internal global %struct.S1 { i32 3, %union.U1 { i32 6, [12 x i8] zeroinitializer } }, align 4 | 
|  | // CHECK: @test12.a = internal global %union.U2 zeroinitializer, align 32 | 
|  | // CHECK: @test14.s = internal global { i32, [4 x i8], i64, [8 x i8], [8 x i8] } zeroinitializer, align 32 | 
|  | // 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 | 
|  | // 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 | 
|  | //. | 
|  | // CHECK-LABEL: define dso_local void @test1( | 
|  | // CHECK-SAME: ) #[[ATTR0:[0-9]+]] { | 
|  | // CHECK-NEXT:  [[ENTRY:.*:]] | 
|  | // CHECK-NEXT:    [[A:%.*]] = alloca [[UNION_U1:%.*]], align 4 | 
|  | // CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[A]], i8 0, i64 16, i1 false) | 
|  | // CHECK-NEXT:    ret void | 
|  | // | 
|  | void test1() { | 
|  | union U1 a = {}; | 
|  | } | 
|  |  | 
|  | // Test empty initializer for union. Use static variable. | 
|  | // CHECK-LABEL: define dso_local void @test2( | 
|  | // CHECK-SAME: ) #[[ATTR0]] { | 
|  | // CHECK-NEXT:  [[ENTRY:.*:]] | 
|  | // CHECK-NEXT:    ret void | 
|  | // | 
|  | void test2() { | 
|  | static union U1 a = {}; | 
|  | } | 
|  |  | 
|  | // Test only initializing a small field for union. | 
|  | // CHECK-LABEL: define dso_local void @test3( | 
|  | // CHECK-SAME: ) #[[ATTR0]] { | 
|  | // CHECK-NEXT:  [[ENTRY:.*:]] | 
|  | // CHECK-NEXT:    [[A:%.*]] = alloca [[UNION_U1:%.*]], align 4 | 
|  | // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[A]], ptr align 4 @__const.test3.a, i64 16, i1 false) | 
|  | // CHECK-NEXT:    ret void | 
|  | // | 
|  | void test3() { | 
|  | union U1 a = {3}; | 
|  | } | 
|  |  | 
|  | // Test only initializing a small field for union. Use static variable. | 
|  | // CHECK-LABEL: define dso_local void @test4( | 
|  | // CHECK-SAME: ) #[[ATTR0]] { | 
|  | // CHECK-NEXT:  [[ENTRY:.*:]] | 
|  | // CHECK-NEXT:    ret void | 
|  | // | 
|  | void test4() { | 
|  | static union U1 a = {3}; | 
|  | } | 
|  |  | 
|  | // Test union in struct. Use empty initializer for the struct. | 
|  | // CHECK-LABEL: define dso_local void @test5( | 
|  | // CHECK-SAME: ) #[[ATTR0]] { | 
|  | // CHECK-NEXT:  [[ENTRY:.*:]] | 
|  | // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S1:%.*]], align 4 | 
|  | // CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[S]], i8 0, i64 20, i1 false) | 
|  | // CHECK-NEXT:    ret void | 
|  | // | 
|  | void test5() { | 
|  | struct S1 s = {}; | 
|  | } | 
|  |  | 
|  | // Test union in struct. Use empty initializer for the struct. Use static variable. | 
|  | // CHECK-LABEL: define dso_local void @test6( | 
|  | // CHECK-SAME: ) #[[ATTR0]] { | 
|  | // CHECK-NEXT:  [[ENTRY:.*:]] | 
|  | // CHECK-NEXT:    ret void | 
|  | // | 
|  | void test6() { | 
|  | static struct S1 s = {}; | 
|  | } | 
|  |  | 
|  | // Test union in struct. Initialize other fields of the struct. | 
|  | // CHECK-LABEL: define dso_local void @test7( | 
|  | // CHECK-SAME: ) #[[ATTR0]] { | 
|  | // CHECK-NEXT:  [[ENTRY:.*:]] | 
|  | // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S1:%.*]], align 4 | 
|  | // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[S]], ptr align 4 @__const.test7.s, i64 20, i1 false) | 
|  | // CHECK-NEXT:    ret void | 
|  | // | 
|  | void test7() { | 
|  | struct S1 s = { | 
|  | .x = 3, | 
|  | }; | 
|  | } | 
|  |  | 
|  | // Test union in struct. Initialize other fields of the struct. Use static variable. | 
|  | // CHECK-LABEL: define dso_local void @test8( | 
|  | // CHECK-SAME: ) #[[ATTR0]] { | 
|  | // CHECK-NEXT:  [[ENTRY:.*:]] | 
|  | // CHECK-NEXT:    ret void | 
|  | // | 
|  | void test8() { | 
|  | static struct S1 s = { | 
|  | .x = 3, | 
|  | }; | 
|  | } | 
|  |  | 
|  | // Test union in struct. Initialize a small field for union. | 
|  | // CHECK-LABEL: define dso_local void @test9( | 
|  | // CHECK-SAME: ) #[[ATTR0]] { | 
|  | // CHECK-NEXT:  [[ENTRY:.*:]] | 
|  | // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S1:%.*]], align 4 | 
|  | // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[S]], ptr align 4 @__const.test9.s, i64 20, i1 false) | 
|  | // CHECK-NEXT:    ret void | 
|  | // | 
|  | void test9() { | 
|  | struct S1 s = {.x = 3, | 
|  | .y = { | 
|  | .x = 6, | 
|  | }}; | 
|  | } | 
|  |  | 
|  | // Test union in struct. Initialize a small field for union. Use static variable. | 
|  | // CHECK-LABEL: define dso_local void @test10( | 
|  | // CHECK-SAME: ) #[[ATTR0]] { | 
|  | // CHECK-NEXT:  [[ENTRY:.*:]] | 
|  | // CHECK-NEXT:    ret void | 
|  | // | 
|  | void test10() { | 
|  | static struct S1 s = {.x = 3, | 
|  | .y = { | 
|  | .x = 6, | 
|  | }}; | 
|  | } | 
|  |  | 
|  | // Test empty initializer for union with padding. | 
|  | // CHECK-LABEL: define dso_local void @test11( | 
|  | // CHECK-SAME: ) #[[ATTR0]] { | 
|  | // CHECK-NEXT:  [[ENTRY:.*:]] | 
|  | // CHECK-NEXT:    [[A:%.*]] = alloca [[UNION_U2:%.*]], align 32 | 
|  | // CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 32 [[A]], i8 0, i64 32, i1 false) | 
|  | // CHECK-NEXT:    ret void | 
|  | // | 
|  | void test11() { | 
|  | union U2 a = {}; | 
|  | } | 
|  |  | 
|  | // Test empty initializer for union with padding. Use static variable. | 
|  | // CHECK-LABEL: define dso_local void @test12( | 
|  | // CHECK-SAME: ) #[[ATTR0]] { | 
|  | // CHECK-NEXT:  [[ENTRY:.*:]] | 
|  | // CHECK-NEXT:    ret void | 
|  | // | 
|  | void test12() { | 
|  | static union U2 a = {}; | 
|  | } | 
|  |  | 
|  | // Test empty initializer for struct with padding. | 
|  | // CHECK-LABEL: define dso_local void @test13( | 
|  | // CHECK-SAME: ) #[[ATTR0]] { | 
|  | // CHECK-NEXT:  [[ENTRY:.*:]] | 
|  | // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S2:%.*]], align 32 | 
|  | // CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 32 [[S]], i8 0, i64 32, i1 false) | 
|  | // CHECK-NEXT:    ret void | 
|  | // | 
|  | void test13() { | 
|  | struct S2 s = {}; | 
|  | } | 
|  |  | 
|  | // Test empty initializer for struct with padding. Use static variable. | 
|  | // CHECK-LABEL: define dso_local void @test14( | 
|  | // CHECK-SAME: ) #[[ATTR0]] { | 
|  | // CHECK-NEXT:  [[ENTRY:.*:]] | 
|  | // CHECK-NEXT:    ret void | 
|  | // | 
|  | void test14() { | 
|  | static struct S2 s = {}; | 
|  | } | 
|  |  | 
|  | // Test partial initialization for struct with padding. | 
|  | // CHECK-LABEL: define dso_local void @test15( | 
|  | // CHECK-SAME: ) #[[ATTR0]] { | 
|  | // CHECK-NEXT:  [[ENTRY:.*:]] | 
|  | // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S2:%.*]], align 32 | 
|  | // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 32 [[S]], ptr align 32 @__const.test15.s, i64 32, i1 false) | 
|  | // CHECK-NEXT:    ret void | 
|  | // | 
|  | void test15() { | 
|  | struct S2 s = {.x = 1}; | 
|  | } | 
|  |  | 
|  | // Test partial initialization for struct with padding. Use static variable. | 
|  | // CHECK-LABEL: define dso_local void @test16( | 
|  | // CHECK-SAME: ) #[[ATTR0]] { | 
|  | // CHECK-NEXT:  [[ENTRY:.*:]] | 
|  | // CHECK-NEXT:    ret void | 
|  | // | 
|  | void test16() { | 
|  | static struct S2 s = {.x = 1}; | 
|  | } | 
|  | //. | 
|  | // 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" } | 
|  | // CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } | 
|  | // CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } | 
|  | //. | 
|  | // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} | 
|  | // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} | 
|  | //. |