Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

CTFE: Support 'with', fix for 'super'

With statements are simple, but exposed a bug in CTFE super:
calls to 'super' shouldn't use the vtable of the original class.
  • Loading branch information...
commit dc34a98532c5393bc50baec484ef19cd26f2f93c 1 parent 43d7ffe
@donc authored
Showing with 24 additions and 5 deletions.
  1. +24 −5 src/interpret.c
View
29 src/interpret.c
@@ -1575,8 +1575,18 @@ Expression *WithStatement::interpret(InterState *istate)
printf("WithStatement::interpret()\n");
#endif
START()
- error("with statements are not yet supported in CTFE");
- return EXP_CANT_INTERPRET;
+ Expression *e = exp->interpret(istate);
+ if (exceptionOrCantInterpret(e))
+ return e;
+ if (wthis->type->ty == Tpointer && exp->type->ty != Tpointer)
+ {
+ e = new AddrExp(loc, e);
+ e->type = wthis->type;
+ }
+ wthis->createStackValue(e);
+ e = body ? body->interpret(istate) : EXP_VOID_INTERPRET;
+ wthis->setValueNull();
+ return e;
}
Expression *AsmStatement::interpret(InterState *istate)
@@ -4648,6 +4658,7 @@ Expression *CallExp::interpret(InterState *istate, CtfeGoal goal)
if (exceptionOrCantInterpret(pthis))
return pthis;
// Evaluate 'this'
+ Expression *oldpthis = pthis;
if (pthis->op != TOKvar)
pthis = pthis->interpret(istate, ctfeNeedLvalue);
if (exceptionOrCantInterpret(pthis))
@@ -4659,14 +4670,22 @@ Expression *CallExp::interpret(InterState *istate, CtfeGoal goal)
{ assert(((VarExp*)thisval)->var->isVarDeclaration());
thisval = ((VarExp*)thisval)->var->isVarDeclaration()->getValue();
}
+ // Get the function from the vtable of the original class
+ ClassDeclaration *cd;
if (thisval && thisval->op == TOKnull)
{
error("function call through null class reference %s", pthis->toChars());
return EXP_CANT_INTERPRET;
}
- // Get the function from the vtable of the original class
- assert(thisval && thisval->op == TOKclassreference);
- ClassDeclaration *cd = ((ClassReferenceExp *)thisval)->originalClass();
+ if (oldpthis->op == TOKsuper)
+ { assert(oldpthis->type->ty == Tclass);
+ cd = ((TypeClass *)oldpthis->type)->sym;
+ }
+ else
+ {
+ assert(thisval && thisval->op == TOKclassreference);
+ cd = ((ClassReferenceExp *)thisval)->originalClass();
+ }
// We can't just use the vtable index to look it up, because
// vtables for interfaces don't get populated until the glue layer.
fd = cd->findFunc(fd->ident, (TypeFunction *)fd->type);
Please sign in to comment.
Something went wrong with that request. Please try again.