diff options
| author | JF Bastien <jfbastien@apple.com> | 2019-02-15 17:26:29 +0000 |
|---|---|---|
| committer | JF Bastien <jfbastien@apple.com> | 2019-02-15 17:26:29 +0000 |
| commit | 0bae08ae7698869f17b7341f8378cf2de0502be8 (patch) | |
| tree | 82e05a7286ac5ae31dadcde2019cd93b48db8649 /clang/lib/CodeGen/CGDecl.cpp | |
| parent | d9c4646d051ad6d61a1949df808e0e6f8cb2892a (diff) | |
| download | bcm5719-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.cpp | 14 |
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.) |

