Skip to content
This repository was archived by the owner on Oct 24, 2019. It is now read-only.

Commit f40cbaa

Browse files
committed
Merge remote-tracking branch 'origin/swift-5.1-branch' into stable
2 parents a382bb1 + c2ce2ce commit f40cbaa

File tree

3 files changed

+64
-6
lines changed

3 files changed

+64
-6
lines changed

lib/CodeGen/CGDecl.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,13 +1788,20 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
17881788
if (emission.IsConstantAggregate || D.isConstexpr()) {
17891789
assert(!capturedByInit && "constant init contains a capturing block?");
17901790
constant = ConstantEmitter(*this).tryEmitAbstractForInitializer(D);
1791-
if (constant && trivialAutoVarInit !=
1792-
LangOptions::TrivialAutoVarInitKind::Uninitialized) {
1791+
if (constant && !constant->isZeroValue() &&
1792+
(trivialAutoVarInit !=
1793+
LangOptions::TrivialAutoVarInitKind::Uninitialized)) {
17931794
IsPattern isPattern =
17941795
(trivialAutoVarInit == LangOptions::TrivialAutoVarInitKind::Pattern)
17951796
? IsPattern::Yes
17961797
: IsPattern::No;
1797-
constant = constWithPadding(CGM, isPattern,
1798+
// C guarantees that brace-init with fewer initializers than members in
1799+
// the aggregate will initialize the rest of the aggregate as-if it were
1800+
// static initialization. In turn static initialization guarantees that
1801+
// padding is initialized to zero bits. We could instead pattern-init if D
1802+
// has any ImplicitValueInitExpr, but that seems to be unintuitive
1803+
// behavior.
1804+
constant = constWithPadding(CGM, IsPattern::No,
17981805
replaceUndef(CGM, isPattern, constant));
17991806
}
18001807
}

test/CodeGen/padding-init.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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)
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)
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)
48+
void init_all() {
49+
struct S s = { .c = 42, .l = 0xdeadbeefc0fedead };
50+
return use(&s);
51+
}

test/CodeGenCXX/auto-var-init.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ struct smallpartinit { char c = 42, d; };
6464
// PATTERN-O1-NOT: @__const.test_nullinit_custom.custom
6565
struct nullinit { char* null = nullptr; };
6666
// PATTERN-O0: @__const.test_padded_uninit.uninit = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 4
67-
// PATTERN-O0: @__const.test_padded_custom.custom = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 42, [3 x i8] c"\AA\AA\AA", i32 13371337 }, align 4
67+
// PATTERN-O0: @__const.test_padded_custom.custom = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 42, [3 x i8] zeroinitializer, i32 13371337 }, align 4
6868
// ZERO-O0: @__const.test_padded_custom.custom = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 42, [3 x i8] zeroinitializer, i32 13371337 }, align 4
6969
// PATTERN-O1-NOT: @__const.test_padded_uninit.uninit
7070
// PATTERN-O1-NOT: @__const.test_padded_custom.custom
@@ -88,7 +88,7 @@ struct paddedpackedarray { struct paddedpacked p[2]; };
8888
// PATTERN-O0: @__const.test_unpackedinpacked_uninit.uninit = private unnamed_addr constant <{ { i8, [3 x i8], i32 }, i8 }> <{ { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, i8 -86 }>, align 1
8989
struct unpackedinpacked { padded a; char b; } __attribute__((packed));
9090
// PATTERN-O0: @__const.test_paddednested_uninit.uninit = private unnamed_addr constant { { i8, [3 x i8], i32 }, { i8, [3 x i8], i32 } } { { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 } }, align 4
91-
// PATTERN: @__const.test_paddednested_custom.custom = private unnamed_addr constant { { i8, [3 x i8], i32 }, { i8, [3 x i8], i32 } } { { i8, [3 x i8], i32 } { i8 42, [3 x i8] c"\AA\AA\AA", i32 13371337 }, { i8, [3 x i8], i32 } { i8 43, [3 x i8] c"\AA\AA\AA", i32 13371338 } }, align 4
91+
// PATTERN: @__const.test_paddednested_custom.custom = private unnamed_addr constant { { i8, [3 x i8], i32 }, { i8, [3 x i8], i32 } } { { i8, [3 x i8], i32 } { i8 42, [3 x i8] zeroinitializer, i32 13371337 }, { i8, [3 x i8], i32 } { i8 43, [3 x i8] zeroinitializer, i32 13371338 } }, align 4
9292
// ZERO: @__const.test_paddednested_custom.custom = private unnamed_addr constant { { i8, [3 x i8], i32 }, { i8, [3 x i8], i32 } } { { i8, [3 x i8], i32 } { i8 42, [3 x i8] zeroinitializer, i32 13371337 }, { i8, [3 x i8], i32 } { i8 43, [3 x i8] zeroinitializer, i32 13371338 } }, align 4
9393
struct paddednested { struct padded p1, p2; };
9494
// PATTERN-O0: @__const.test_paddedpackednested_uninit.uninit = private unnamed_addr constant %struct.paddedpackednested { %struct.paddedpacked <{ i8 -86, i32 -1431655766 }>, %struct.paddedpacked <{ i8 -86, i32 -1431655766 }> }, align 1
@@ -135,7 +135,7 @@ struct arraytail { int i; int arr[]; };
135135
// ZERO: @__const.test_intptr4_custom.custom = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*)], align 16
136136
// PATTERN-O0: @__const.test_tailpad4_uninit.uninit = private unnamed_addr constant [4 x { i16, i8, [1 x i8] }] [{ i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }], align 16
137137
// PATTERN-O1-NOT: @__const.test_tailpad4_uninit.uninit
138-
// PATTERN: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x { i16, i8, [1 x i8] }] [{ i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] c"\AA" }], align 16
138+
// PATTERN: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x { i16, i8, [1 x i8] }] [{ i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }], align 16
139139
// ZERO: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x { i16, i8, [1 x i8] }] [{ i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }], align 16
140140
struct tailpad { short s; char c; };
141141
// PATTERN-O0: @__const.test_atomicnotlockfree_uninit.uninit = private unnamed_addr constant %struct.notlockfree { [4 x i64] [i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206] }, align 8

0 commit comments

Comments
 (0)