Skip to content

Commit

Permalink
Fix issue #2932 (allow speculative nested variables) (#2940)
Browse files Browse the repository at this point in the history
  • Loading branch information
kinke committed Jan 20, 2019
1 parent 82dabb4 commit 61ed056
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 5 deletions.
22 changes: 17 additions & 5 deletions gen/nested.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,27 @@ DValue *DtoNestedVariable(Loc &loc, Type *astype, VarDeclaration *vd,
IF_LOG { Logger::cout() << "Context: " << *ctx << '\n'; }

DtoCreateNestedContextType(vdparent->isFuncDeclaration());

assert(isIrLocalCreated(vd));
IrLocal *const irLocal = getIrLocal(vd);

// The variable may not actually be nested in a speculative context (e.g.,
// with `-allinst`, see https://github.com/ldc-developers/ldc/issues/2932).
// Use an invalid null storage in that case, so that accessing the var at
// runtime will cause a segfault.
if (irLocal->nestedIndex == -1) {
Logger::println(
"WARNING: isn't actually nested, using invalid null storage");
auto llType = DtoPtrToType(astype);
if (isSpecialRefVar(vd))
llType = llType->getPointerTo();
return makeVarDValue(astype, vd, llvm::ConstantPointerNull::get(llType));
}

////////////////////////////////////
// Extract variable from nested context

assert(irfunc->frameType);
const auto frameType = LLPointerType::getUnqual(irfunc->frameType);
IF_LOG { Logger::cout() << "casting to: " << *irfunc->frameType << '\n'; }
LLValue *val = DtoBitCast(ctx, frameType);
Expand All @@ -108,7 +124,6 @@ DValue *DtoNestedVariable(Loc &loc, Type *astype, VarDeclaration *vd,
val = DtoAlignedLoad(val, name);
};

IrLocal *const irLocal = getIrLocal(vd);
const auto vardepth = irLocal->nestedDepth;
const auto funcdepth = irfunc->depth;

Expand All @@ -132,10 +147,7 @@ DValue *DtoNestedVariable(Loc &loc, Type *astype, VarDeclaration *vd,
IF_LOG Logger::cout() << "Frame: " << *val << '\n';
}

const auto idx = irLocal->nestedIndex;
assert(idx != -1 && "Nested context not yet resolved for variable.");

offsetToNthField(idx, vd->toChars());
offsetToNthField(irLocal->nestedIndex, vd->toChars());
IF_LOG {
Logger::cout() << "Addr: " << *val << '\n';
Logger::cout() << "of type: " << *val->getType() << '\n';
Expand Down
20 changes: 20 additions & 0 deletions tests/compilable/gh2932.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %ldc -c -allinst %s

import std.algorithm;

extern __gshared int[] array;

void funcWithNoFrame()
{
int local;
// lambda is codegen'd
pragma(msg, typeof(array.map!(e => local)));
}

void funcWithFrame()
{
int capturedVar, local;
int nestedFunc() { return capturedVar; }
// lambda is codegen'd with `-allinst`
static assert(__traits(compiles, array.map!(e => local)));
}

0 comments on commit 61ed056

Please sign in to comment.