1 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s
2 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s
3 
4 // C guarantees that brace-init with fewer initializers than members in the
5 // aggregate will initialize the rest of the aggregate as-if it were static
6 // initialization. In turn static initialization guarantees that padding is
7 // initialized to zero bits.
8 
9 // CHECK: @__const.partial_init.s = private unnamed_addr constant { i8, [7 x i8], i64 } { i8 42, [7 x i8] zeroinitializer, i64 0 }, align 8
10 
11 // Technically, we could initialize this padding to non-zero because all of the
12 // struct's members have initializers.
13 
14 // CHECK: @__const.init_all.s = private unnamed_addr constant { i8, [7 x i8], i64 } { i8 42, [7 x i8] zeroinitializer, i64 -2401053089374216531 }, align 8
15 
16 struct S {
17   char c;
18   long long l;
19 };
20 
21 void use(struct S*);
22 
23 // CHECK-LABEL: @empty_braces(
24 // CHECK:       %s = alloca
25 // CHECK-NEXT:  %[[B:[0-9+]]] = bitcast %struct.S* %s to i8*
26 // CHECK-NEXT:  call void @llvm.memset{{.*}}(i8* align 8 %[[B]], i8 0,
27 // CHECK-NEXT:  call void @use(%struct.S* %s)
empty_braces()28 void empty_braces() {
29   struct S s = {};
30   return use(&s);
31 }
32 
33 // CHECK-LABEL: @partial_init(
34 // CHECK:       %s = alloca
35 // CHECK-NEXT:  %[[B:[0-9+]]] = bitcast %struct.S* %s to i8*
36 // CHECK-NEXT:  call void @llvm.memcpy{{.*}}(i8* align 8 %[[B]], {{.*}}@__const.partial_init.s
37 // CHECK-NEXT:  call void @use(%struct.S* %s)
partial_init()38 void partial_init() {
39   struct S s = { .c = 42 };
40   return use(&s);
41 }
42 
43 // CHECK-LABEL: @init_all(
44 // CHECK:       %s = alloca
45 // CHECK-NEXT:  %[[B:[0-9+]]] = bitcast %struct.S* %s to i8*
46 // CHECK-NEXT:  call void @llvm.memcpy{{.*}}(i8* align 8 %[[B]], {{.*}}@__const.init_all.s
47 // CHECK-NEXT:  call void @use(%struct.S* %s)
init_all()48 void init_all() {
49   struct S s = { .c = 42, .l = 0xdeadbeefc0fedead };
50   return use(&s);
51 }
52