Bug 3500 – super behaves differently with -inline

Status
RESOLVED
Resolution
FIXED
Severity
critical
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
Other
OS
All
Creation time
2009-11-12T10:20:00Z
Last change time
2014-02-15T13:12:40Z
Keywords
patch, wrong-code
Assigned to
nobody
Creator
nfxjfg
Blocks
3761

Comments

Comment #0 by nfxjfg — 2009-11-12T10:20:47Z
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 by nfxjfg — 2009-11-12T10:29:58Z
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 by clugdbug — 2010-01-04T02:48:03Z
This may be related to bug 2127.
Comment #3 by clugdbug — 2010-02-03T00:19:21Z
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 by bugzilla — 2010-02-06T00:03:16Z
changeset 373
Comment #5 by bugzilla — 2010-03-08T22:21:10Z
Fixed dmd 1.057 and 2.041