Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fix issue 9777 Wrong code when calling final interface methods #1781

Merged
merged 1 commit into from

2 participants

@jpf91

Can't use DotTypeExp when converting to the interface as the pointer needs to be adjusted. Use CastExp instead.

It would be nice if we can get this merged soon as it causes worse consequences in gdc. (In gdc not even the simple case in the original test case is working)

@jpf91 jpf91 Fix issue 9777 Wrong code when calling final interface methods
Can't use DotTypeExp when converting to the interface as the
pointer needs to be adjusted. Use CastExp instead.
f35c753
@jpf91 jpf91 referenced this pull request in D-Programming-GDC/GDC
Merged

Fix final interface calls #58

@WalterBright WalterBright merged commit 1375dee into D-Programming-Language:master

1 check was pending

Details default Pass: 5, In Progress: 3, Pending: 2
@WalterBright WalterBright referenced this pull request from a commit
@WalterBright WalterBright merge D2 pull #1781 48ffc28
@jpf91

thanks

@jpf91 jpf91 deleted the jpf91:fix9777 branch
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 21, 2013
  1. @jpf91

    Fix issue 9777 Wrong code when calling final interface methods

    jpf91 authored
    Can't use DotTypeExp when converting to the interface as the
    pointer needs to be adjusted. Use CastExp instead.
This page is out of date. Refresh to see the latest.
View
2  src/aggregate.h
@@ -261,7 +261,7 @@ struct ClassDeclaration : AggregateDeclaration
virtual int isBaseInfoComplete();
Dsymbol *search(Loc, Identifier *ident, int flags);
- Dsymbol *searchBase(Loc, Identifier *ident);
+ ClassDeclaration *searchBase(Loc, Identifier *ident);
#if DMDV2
int isFuncHidden(FuncDeclaration *fd);
#endif
View
6 src/class.c
@@ -979,17 +979,17 @@ Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags)
return s;
}
-Dsymbol *ClassDeclaration::searchBase(Loc loc, Identifier *ident)
+ClassDeclaration *ClassDeclaration::searchBase(Loc loc, Identifier *ident)
{
// Search bases classes in depth-first, left to right order
for (size_t i = 0; i < baseclasses->dim; i++)
{
BaseClass *b = (*baseclasses)[i];
- Dsymbol *cdb = b->type->isClassHandle();
+ ClassDeclaration *cdb = b->type->isClassHandle();
if (cdb->ident->equals(ident))
return cdb;
- cdb = ((ClassDeclaration *)cdb)->searchBase(loc, ident);
+ cdb = cdb->searchBase(loc, ident);
if (cdb)
return cdb;
}
View
21 src/mtype.c
@@ -8487,13 +8487,26 @@ Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident)
// See if it's 'this' class or a base class
if (e->op != TOKtype)
{
- Dsymbol *cbase = sym->ident == ident ?
- sym : sym->searchBase(e->loc, ident);
- if (cbase)
+ if (sym->ident == ident)
{
- e = new DotTypeExp(0, e, cbase);
+ e = new DotTypeExp(0, e, sym);
return e;
}
+
+ ClassDeclaration *cbase = sym->searchBase(e->loc, ident);
+ if (cbase)
+ {
+ if (InterfaceDeclaration *ifbase = cbase->isInterfaceDeclaration())
+ {
+ e = new CastExp(0, e, ifbase->type);
+ return e;
+ }
+ else
+ {
+ e = new DotTypeExp(0, e, cbase);
+ return e;
+ }
+ }
}
if (ident == Id::classinfo)
View
61 test/runnable/xtest46.d
@@ -4300,25 +4300,78 @@ static assert(typeof(cfunc6596).stringof == "extern (C) int()");
interface Timer
{
- final int run() { printf("Timer.run()\n"); return 1; };
+ final int run() { printf("Timer.run()\n"); fun(); return 1; };
+ int fun();
}
interface Application
{
- final int run() { printf("Application.run()\n"); return 2; };
+ final int run() { printf("Application.run()\n"); fun(); return 2; };
+ int fun();
}
class TimedApp : Timer, Application
{
+ int funCalls;
+ override int fun()
+ {
+ printf("TimedApp.fun()\n");
+ funCalls++;
+ return 2;
+ }
+}
+
+class SubTimedApp : TimedApp
+{
+ int subFunCalls;
+
+ override int fun()
+ {
+ printf("SubTimedApp.fun()\n");
+ subFunCalls++;
+ return 1;
+ }
}
void test4647()
{
- auto app = new TimedApp;
- assert(app.Timer.run() == 1); // error, no Timer property
+ //Test access to TimedApps base interfaces
+ auto app = new TimedApp();
+ assert((cast(Application)app).run() == 2);
+ assert((cast(Timer)app).run() == 1);
+ assert(app.Timer.run() == 1); // error, no Timer property
assert(app.Application.run() == 2); // error, no Application property
assert(app.run() == 1); // This would call Timer.run() if the two calls
// above were commented out
+ assert(app.funCalls == 5);
+
+ assert(app.TimedApp.fun() == 2);
+ assert(app.funCalls == 6);
+
+ //Test direct access to SubTimedApp interfaces
+ auto app2 = new SubTimedApp();
+ assert((cast(Application)app2).run() == 2);
+ assert((cast(Timer)app2).run() == 1);
+ assert(app2.Application.run() == 2);
+ assert(app2.Timer.run() == 1);
+ assert(app2.funCalls == 0);
+ assert(app2.subFunCalls == 4);
+
+ assert(app2.fun() == 1);
+ assert(app2.SubTimedApp.fun() == 1);
+ assert(app2.funCalls == 0);
+ assert(app2.subFunCalls == 6);
+
+ //Test access to SubTimedApp interfaces via TimedApp
+ auto app3 = new SubTimedApp();
+ (cast(Timer)cast(TimedApp)app3).run();
+ app3.TimedApp.Timer.run();
+ assert((cast(Application)cast(TimedApp)app3).run() == 2);
+ assert((cast(Timer)cast(TimedApp)app3).run() == 1);
+ assert(app3.TimedApp.Application.run() == 2);
+ assert(app3.TimedApp.Timer.run() == 1);
+ assert(app3.funCalls == 0);
+ assert(app3.subFunCalls == 6);
}
/***************************************************/
Something went wrong with that request. Please try again.