Local static block variable referecned in its
block-literal initializer expression causes IRgen to crash. This patch fixes by saving it in StaticLocalDecl map already used for such purposes. (radar 8390455). llvm-svn: 113307
This commit is contained in:
parent
a4d9c78aa1
commit
366a94822b
|
@ -244,6 +244,10 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D,
|
|||
// Make sure to evaluate VLA bounds now so that we have them for later.
|
||||
if (D.getType()->isVariablyModifiedType())
|
||||
EmitVLASize(D.getType());
|
||||
|
||||
// Local static block variables must be treated as globals as they may be
|
||||
// referenced in their RHS initializer block-literal expresion.
|
||||
CGM.setStaticLocalDeclAddress(&D, GV);
|
||||
|
||||
// If this value has an initializer, emit it.
|
||||
if (D.getInit())
|
||||
|
@ -266,9 +270,6 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D,
|
|||
if (D.hasAttr<UsedAttr>())
|
||||
CGM.AddUsedGlobal(GV);
|
||||
|
||||
if (getContext().getLangOptions().CPlusPlus)
|
||||
CGM.setStaticLocalDeclAddress(&D, GV);
|
||||
|
||||
// We may have to cast the constant because of the initializer
|
||||
// mismatch above.
|
||||
//
|
||||
|
|
|
@ -1152,8 +1152,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
|
|||
bool NonGCable = VD->hasLocalStorage() && !VD->hasAttr<BlocksAttr>();
|
||||
|
||||
llvm::Value *V = LocalDeclMap[VD];
|
||||
if (!V && getContext().getLangOptions().CPlusPlus &&
|
||||
VD->isStaticLocal())
|
||||
if (!V && VD->isStaticLocal())
|
||||
V = CGM.getStaticLocalDeclAddress(VD);
|
||||
assert(V && "DeclRefExpr not entered in LocalDeclMap?");
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin -emit-llvm %s -o %t-64.ll
|
||||
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.ll %s
|
||||
// rdar: // 8390455
|
||||
|
||||
@class NSArray;
|
||||
|
||||
static NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSArray *addresses, unsigned long level) {
|
||||
|
||||
for(id rawAddress in addresses)
|
||||
{
|
||||
NSArray *separatedAddresses = ((NSArray*)0);
|
||||
separatedAddresses = ArrayRecurs((NSArray *)rawAddress, level+1);
|
||||
}
|
||||
return (NSArray *)0;
|
||||
};
|
||||
|
||||
void FUNC()
|
||||
{
|
||||
static NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSArray *addresses, unsigned long level) {
|
||||
|
||||
for(id rawAddress in addresses)
|
||||
{
|
||||
NSArray *separatedAddresses = ((NSArray*)0);
|
||||
separatedAddresses = ArrayRecurs((NSArray *)rawAddress, level+1);
|
||||
}
|
||||
return (NSArray *)0;
|
||||
};
|
||||
|
||||
if (ArrayRecurs) {
|
||||
static NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSArray *addresses, unsigned long level) {
|
||||
|
||||
for(id rawAddress in addresses)
|
||||
{
|
||||
NSArray *separatedAddresses = ((NSArray*)0);
|
||||
separatedAddresses = ArrayRecurs((NSArray *)rawAddress, level+1);
|
||||
}
|
||||
return (NSArray *)0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void FUNC1()
|
||||
{
|
||||
static NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSArray *addresses, unsigned long level) {
|
||||
|
||||
for(id rawAddress in addresses)
|
||||
{
|
||||
NSArray *separatedAddresses = ((NSArray*)0);
|
||||
separatedAddresses = ArrayRecurs((NSArray *)rawAddress, level+1);
|
||||
}
|
||||
return (NSArray *)0;
|
||||
};
|
||||
}
|
||||
// CHECK-LP64: @ArrayRecurs = internal global
|
||||
// CHECK-LP64: @FUNC.ArrayRecurs = internal global
|
||||
// CHECK-LP64: @FUNC.ArrayRecurs3 = internal global
|
||||
// CHECK-LP64: @FUNC1.ArrayRecurs = internal global
|
Loading…
Reference in New Issue