3706 – delegates of interfaces with multiple inheritance fail

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3706 - delegates of interfaces with multiple inheritance fail
Summary: delegates of interfaces with multiple inheritance fail
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other All
: P2 major
Assignee: No Owner
URL:
Keywords: patch, wrong-code
Depends on:
Blocks:
Reported: 2010年01月14日 12:42 UTC by Fawzi Mohamed
Modified: 2015年06月09日 05:10 UTC (History)
2 users (show)

See Also:


Attachments
an example of the bug (967 bytes, text/d-source)
2010年01月14日 12:42 UTC, Fawzi Mohamed
Details
a shorter example (571 bytes, text/d-source)
2010年01月14日 12:58 UTC, Fawzi Mohamed
Details
Add an attachment (proposed patch, testcase, etc.)

Note You need to log in before you can comment on or make changes to this issue.
Description Fawzi Mohamed 2010年01月14日 12:42:31 UTC
Created attachment 550 [details] 
an example of the bug
Delegates of an interface that refer to methods in sub interfaces that are not
the first one fail.
Somehow when done through ThreadLocal variables the bug is slightly different
(nothing seems to be called), whereas the other examples that I show another
method get called.
I set it as major because it is a subtle bug that took me very long to track
down, its effects a similar to memory pollution...
This is a bug in both 1.047 and 1.055
Comment 1 Fawzi Mohamed 2010年01月14日 12:58:44 UTC
Created attachment 551 [details] 
a shorter example
Comment 2 Don 2010年07月22日 12:20:12 UTC
Here's a slightly reduced test case.
--------------
interface I{
 void h();
}
interface K{
 void f();
}
interface J:I,K {}
class A:J{
 void f(){ }
 void h(){ } 
}
void main(){
 auto a = new A();
 J b = a;
 K c = a;
 assert(&b.f == &c.f); // fails: &b.f returns &a.h.
}
Comment 3 Don 2010年07月22日 13:55:22 UTC
The problem lies in delegate expressions formed from interfaces. We need to ensure that the correct interface is used, otherwise the vtblIndex will refer to the wrong one.
Applies to both D1 and D2.
PATCH: expression.c, not yet fully tested in the test suite. Maybe this patch should be made in getRightThis() instead?
Expression *DelegateExp::semantic(Scope *sc)
{
#if LOGSEMANTIC
 printf("DelegateExp::semantic('%s')\n", toChars());
#endif
 if (!type)
 {
 e1 = e1->semantic(sc);
 type = new TypeDelegate(func->type);
 type = type->semantic(loc, sc);
 AggregateDeclaration *ad = func->toParent()->isAggregateDeclaration();
 if (func->needThis())
 e1 = getRightThis(loc, sc, ad, e1, func);
+ if (ad && ad->type != e1->type)
+ { // A downcast is required for interfaces
+ e1 = new CastExp(loc, e1, ad->type);
+ e1 = e1->semantic(sc);
+ }
 }
 return this;
}
Comment 4 Walter Bright 2010年07月24日 19:10:38 UTC
http://www.dsource.org/projects/dmd/changeset/587 


AltStyle によって変換されたページ (->オリジナル) /