Correctly handle ref variables in an outer frame.

Fixes DMD testcase 'testcontracts'.
This commit is contained in:
David Nadlinger 2013-01-04 07:26:15 +01:00
parent 0508acf10b
commit c3d517e17f
3 changed files with 14 additions and 5 deletions

View file

@ -57,6 +57,13 @@ LLValue* DVarValue::getRVal()
return DtoLoad(tmp);
}
LLValue* DVarValue::getRefStorage()
{
assert(val);
assert(isSpecialRefVar(var));
return val;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////

View file

@ -110,6 +110,10 @@ struct DVarValue : DValue
virtual llvm::Value* getLVal();
virtual llvm::Value* getRVal();
/// Returns the underlying storage for special internal ref variables.
/// Illegal to call on any other value.
virtual llvm::Value* getRefStorage();
virtual DVarValue* isVar() { return this; }
};

View file

@ -597,12 +597,10 @@ DValue* AssignExp::toElem(IRState* p)
// Note that the variable value is accessed directly (instead
// of via getLValue(), which would perform a load from the
// uninitialized location), and that rhs is stored as an l-value!
IrLocal* const local = ve->var->ir.irLocal;
assert(local && "ref var must be local and already initialized");
DVarValue* lhs = e1->toElem(p)->isVar();
assert(lhs);
DValue* rhs = e2->toElem(p);
DtoStore(rhs->getLVal(), local->value);
DtoStore(rhs->getLVal(), lhs->getRefStorage());
return rhs;
}
}