[PATCH] D57797: Variable auto-init: fix __block initialization
JF Bastien via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 7 16:51:20 PST 2019
jfb updated this revision to Diff 185892.
jfb marked 4 inline comments as done.
jfb added a comment.
- Simplify patch greatly.
Repository:
rC Clang
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D57797/new/
https://reviews.llvm.org/D57797
Files:
lib/CodeGen/CGDecl.cpp
test/CodeGenCXX/trivial-auto-var-init.cpp
Index: test/CodeGenCXX/trivial-auto-var-init.cpp
===================================================================
--- test/CodeGenCXX/trivial-auto-var-init.cpp
+++ test/CodeGenCXX/trivial-auto-var-init.cpp
@@ -30,6 +30,32 @@
used(block);
}
+// Using the variable being initialized is typically UB in C, but for blocks we
+// can be nice: they imply extra book-keeping and we can do the auto-init before
+// any of said book-keeping.
+//
+// UNINIT-LABEL: test_block_self_init(
+// ZERO-LABEL: test_block_self_init(
+// ZERO: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
+// ZERO: %captured1 = getelementptr inbounds %struct.__block_byref_captured, %struct.__block_byref_captured* %captured, i32 0, i32 4
+// ZERO-NEXT: store %struct.XYZ* null, %struct.XYZ** %captured1, align 8
+// ZERO: %call = call %struct.XYZ* @create(
+// PATTERN-LABEL: test_block_self_init(
+// PATTERN: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
+// PATTERN: %captured1 = getelementptr inbounds %struct.__block_byref_captured, %struct.__block_byref_captured* %captured, i32 0, i32 4
+// PATTERN-NEXT: store %struct.XYZ* inttoptr (i64 -6148914691236517206 to %struct.XYZ*), %struct.XYZ** %captured1, align 8
+// PATTERN: %call = call %struct.XYZ* @create(
+void test_block_self_init() {
+ using Block = void (^)();
+ typedef struct XYZ {
+ Block block;
+ } * xyz_t;
+ extern xyz_t create(Block block);
+ __block xyz_t captured = create(^() {
+ (void)captured;
+ });
+}
+
// This type of code is currently not handled by zero / pattern initialization.
// The test will break when that is fixed.
// UNINIT-LABEL: test_goto_unreachable_value(
Index: lib/CodeGen/CGDecl.cpp
===================================================================
--- lib/CodeGen/CGDecl.cpp
+++ lib/CodeGen/CGDecl.cpp
@@ -1598,7 +1598,7 @@
if (!Init || !ContainsLabel(Init)) return;
EnsureInsertPoint();
}
-
+
// Initialize the structure of a __block variable.
if (emission.IsEscapingByRef)
emitByrefStructureInit(emission);
@@ -1606,9 +1606,8 @@
// Initialize the variable here if it doesn't have a initializer and it is a
// C struct that is non-trivial to initialize or an array containing such a
// struct.
- if (!Init &&
- type.isNonTrivialToPrimitiveDefaultInitialize() ==
- QualType::PDIK_Struct) {
+ if (!Init && type.isNonTrivialToPrimitiveDefaultInitialize() ==
+ QualType::PDIK_Struct) {
LValue Dst = MakeAddrLValue(emission.getAllocatedAddress(), type);
if (emission.IsEscapingByRef)
drillIntoBlockVariable(*this, Dst, &D);
@@ -1633,11 +1632,15 @@
? LangOptions::TrivialAutoVarInitKind::Uninitialized
: getContext().getLangOpts().getTrivialAutoVarInit()));
- auto initializeWhatIsTechnicallyUninitialized = [&]() {
+ auto initializeWhatIsTechnicallyUninitialized = [&](Address Loc) {
if (trivialAutoVarInit ==
LangOptions::TrivialAutoVarInitKind::Uninitialized)
return;
+ // Only initialize a __block's storage: we always initialize the header.
+ if (emission.IsEscapingByRef)
+ Loc = emitBlockByrefAddress(Loc, &D, /*follow=*/false);
+
CharUnits Size = getContext().getTypeSizeInChars(type);
if (!Size.isZero()) {
switch (trivialAutoVarInit) {
@@ -1715,7 +1718,7 @@
};
if (isTrivialInitializer(Init)) {
- initializeWhatIsTechnicallyUninitialized();
+ initializeWhatIsTechnicallyUninitialized(Loc);
return;
}
@@ -1729,7 +1732,7 @@
}
if (!constant) {
- initializeWhatIsTechnicallyUninitialized();
+ initializeWhatIsTechnicallyUninitialized(Loc);
LValue lv = MakeAddrLValue(Loc, type);
lv.setNonGC(true);
return EmitExprAsInit(Init, &D, lv, capturedByInit);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D57797.185892.patch
Type: text/x-patch
Size: 3906 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190208/18a8cfb8/attachment.bin>
More information about the cfe-commits
mailing list