summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGDecl.cpp
diff options
context:
space:
mode:
authorJF Bastien <jfbastien@apple.com>2019-02-15 17:26:29 +0000
committerJF Bastien <jfbastien@apple.com>2019-02-15 17:26:29 +0000
commit0bae08ae7698869f17b7341f8378cf2de0502be8 (patch)
tree82e05a7286ac5ae31dadcde2019cd93b48db8649 /clang/lib/CodeGen/CGDecl.cpp
parentd9c4646d051ad6d61a1949df808e0e6f8cb2892a (diff)
downloadbcm5719-llvm-0bae08ae7698869f17b7341f8378cf2de0502be8.tar.gz
bcm5719-llvm-0bae08ae7698869f17b7341f8378cf2de0502be8.zip
Variable auto-init of blocks capturing self after init bugfix
Summary: Blocks that capture themselves (and escape) after initialization currently codegen wrong because this: bool capturedByInit = Init && emission.IsEscapingByRef && isCapturedBy(D, Init); Address Loc = capturedByInit ? emission.Addr : emission.getObjectAddress(*this); Already adjusts Loc from thr alloca to a GEP. This code: if (emission.IsEscapingByRef) Loc = emitBlockByrefAddress(Loc, &D, /*follow=*/false); Was trying to do the same adjustment, and a GEP on a GEP (returning an int) triggers an assertion. <rdar://problem/47943027> Reviewers: ahatanak Subscribers: jkorous, dexonsmith, cfe-commits, rjmccall Tags: #clang Differential Revision: https://reviews.llvm.org/D58218 llvm-svn: 354147
Diffstat (limited to 'clang/lib/CodeGen/CGDecl.cpp')
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp14
1 files changed, 7 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 2ac3de9f3bc..6c8b27a97b4 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1620,8 +1620,9 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
bool capturedByInit =
Init && emission.IsEscapingByRef && isCapturedBy(D, Init);
- Address Loc =
- capturedByInit ? emission.Addr : emission.getObjectAddress(*this);
+ bool locIsByrefHeader = !capturedByInit;
+ const Address Loc =
+ locIsByrefHeader ? emission.getObjectAddress(*this) : emission.Addr;
// Note: constexpr already initializes everything correctly.
LangOptions::TrivialAutoVarInitKind trivialAutoVarInit =
@@ -1637,7 +1638,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
return;
// Only initialize a __block's storage: we always initialize the header.
- if (emission.IsEscapingByRef)
+ if (emission.IsEscapingByRef && !locIsByrefHeader)
Loc = emitBlockByrefAddress(Loc, &D, /*follow=*/false);
CharUnits Size = getContext().getTypeSizeInChars(type);
@@ -1744,10 +1745,9 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
}
llvm::Type *BP = CGM.Int8Ty->getPointerTo(Loc.getAddressSpace());
- if (Loc.getType() != BP)
- Loc = Builder.CreateBitCast(Loc, BP);
-
- emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant);
+ emitStoresForConstant(
+ CGM, D, (Loc.getType() == BP) ? Loc : Builder.CreateBitCast(Loc, BP),
+ isVolatile, Builder, constant);
}
/// Emit an expression as an initializer for an object (variable, field, etc.)
OpenPOWER on IntegriCloud