Skip to content

Commit

Permalink
7144 [CTFE] base class does not call overridden members
Browse files Browse the repository at this point in the history
We need to do the vtable lookup, even if called directly from 'this'.
  • Loading branch information
Don Clugston committed Dec 21, 2011
1 parent 312a6c9 commit 879a208
Showing 1 changed file with 33 additions and 29 deletions.
62 changes: 33 additions & 29 deletions src/interpret.c
Expand Up @@ -4601,49 +4601,53 @@ Expression *CallExp::interpret(InterState *istate, CtfeGoal goal)
}
if (pthis)
{ // Member function call
Expression *oldpthis;
if (pthis->op == TOKthis)
{
pthis = istate ? istate->localThis : NULL;
oldpthis == pthis;
}
else
{
if (pthis->op == TOKcomma)
pthis = pthis->interpret(istate);
if (exceptionOrCantInterpret(pthis))
return pthis;
// Evaluate 'this'
Expression *oldpthis = pthis;
oldpthis = pthis;
if (pthis->op != TOKvar)
pthis = pthis->interpret(istate, ctfeNeedLvalue);
if (exceptionOrCantInterpret(pthis))
return pthis;
if (fd->isVirtual())
{ // Make a virtual function call.
Expression *thisval = pthis;
if (pthis->op == TOKvar)
{ 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;
}
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);

assert(fd);
}
if (fd->isVirtual())
{ // Make a virtual function call.
Expression *thisval = pthis;
if (pthis->op == TOKvar)
{ 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;
}
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);

assert(fd);
}
}
if (fd && fd->semanticRun >= PASSsemantic3done && fd->semantic3Errors)
Expand Down

0 comments on commit 879a208

Please sign in to comment.