Skip to content

Commit

Permalink
CTFE: Support 'with', fix for 'super'
Browse files Browse the repository at this point in the history
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
Don Clugston committed Nov 7, 2011
1 parent 43d7ffe commit dc34a98
Showing 1 changed file with 24 additions and 5 deletions.
29 changes: 24 additions & 5 deletions src/interpret.c
Expand Up @@ -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)
Expand Down Expand Up @@ -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))
Expand All @@ -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);
Expand Down

0 comments on commit dc34a98

Please sign in to comment.