Properly handle DMD-internal "reference variables".

Previously, we just had a hack to make ref foreach statements work.
This commit enables them to work in other cases as well, like the
implicit __result variable for functions with out-contracts (which
is such a magic ref variable for ref-returning functions).

Fixes DMD testcase 'testcontracts'.
This commit is contained in:
David Nadlinger
2012-09-04 01:36:52 +02:00
parent 6b1b84a28d
commit ee4285f934
8 changed files with 173 additions and 172 deletions

View File

@@ -583,6 +583,30 @@ DValue* AssignExp::toElem(IRState* p)
return newlen;
}
// Can't just override ConstructExp::toElem because not all TOKconstruct
// operations are actually instances of ConstructExp... Long live the DMD
// coding style!
if (op == TOKconstruct)
{
if (e1->op == TOKvar)
{
VarExp* ve = (VarExp*)e1;
if (ve->var->storage_class & STCref)
{
// 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");
DValue* rhs = e2->toElem(p);
DtoStore(rhs->getLVal(), local->value);
return rhs;
}
}
}
Logger::println("performing normal assignment");
DValue* l = e1->toElem(p);