3500 – super behaves differently with -inline

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3500 - super behaves differently with -inline
Summary: super behaves differently with -inline
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: Other All
: P2 critical
Assignee: No Owner
URL:
Keywords: patch, wrong-code
Depends on:
Blocks: 3761
Show dependency tree / graph
Reported: 2009年11月12日 10:20 UTC by nfxjfg
Modified: 2014年02月15日 13:12 UTC (History)
3 users (show)

See Also:


Attachments
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 nfxjfg 2009年11月12日 10:20:47 UTC
The following program behaves differently whether you pass -inline to dmd or not.
The correct output is "A::x()", but with -inline, it outputs "B::x()".
Conclusion: the dmd inliner must be buggy.
I confirmed this with:
- dmd 1.051/Tango
- dmd 2.035/Phobos
Command line, failing binary: dmd bug.d -inline
Correct binary: dmd bug.d
Test using Tango:
import tango.util.log.Trace;
class A {
 void x() {
 Trace.formatln("A::x()");
 }
}
class B : A {
 override void x() {
 Trace.formatln("B::x()");
 }
 private void do_x() {
 super.x();
 }
}
void main() {
 B b = new B();
 b.do_x();
}
Comment 1 nfxjfg 2009年11月12日 10:29:58 UTC
D2 testcase.
import std.stdio;
class A {
 void x() {
 writefln("A::x()");
 }
}
class B : A {
 override void x() {
 writefln("B::x()");
 }
 private void do_x() {
 super.x();
 }
}
void main() {
 B b = new B();
 b.do_x();
}
Comment 2 Don 2010年01月04日 02:48:03 UTC
This may be related to bug 2127.
Comment 3 Don 2010年02月03日 00:19:21 UTC
The thing that isn't working correctly is this line from the 'Expressions' page in the spec: "If a member function is called with an explicit reference to super, a non-virtual call is made." This bug applies to D1 as well (DMD1.00 fails).
Cause: direct calls are normally implemented in e2ir.c. If CallExp::toElem() finds TOKsuper, it makes it a non-virtual call. But the direct call is a little bit of a hack (there's a "//BUG: fix" comment in FuncExp::toElem()).
inline.c, SuperExp::doInline() changes it from 'super' to a variable, so e2ir can't find it.
This patch disables inlining for direct 'super' calls. Allowing them to be inlined would be a quite difficult, I think.
Index: inline.c
===================================================================
--- inline.c	(revision 362)
+++ inline.c	(working copy)
@@ -275,6 +275,10 @@
 
 int CallExp::inlineCost(InlineCostState *ics)
 {
+ // Bugzilla 3500: super.func() calls must be devirtualized, and the inliner
+ // can't handle that at present.
+ if (e1->op == TOKdotvar && ((DotVarExp *)e1)->e1->op == TOKsuper)
+	return COST_MAX;
 return 1 + e1->inlineCost(ics) + arrayInlineCost(ics, arguments);
 }
-------------------------------------------------
Test case without any imports: 
--------------------------------
class A {
 void x() { }
}
class B : A {
 override void x() {
 assert(0);
 }
 final void do_x() {
 super.x();
 }
}
void main() {
 B b = new B();
 b.do_x();
}
--------------------------------
Comment 4 Walter Bright 2010年02月06日 00:03:16 UTC
changeset 373
Comment 5 Walter Bright 2010年03月08日 22:21:10 UTC
Fixed dmd 1.057 and 2.041


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