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(); }
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(); }
This may be related to bug 2127.
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(); } --------------------------------
changeset 373
Fixed dmd 1.057 and 2.041
AltStyle によって変換されたページ (->オリジナル) / アドレス: モード: デフォルト 音声ブラウザ ルビ付き 配色反転 文字拡大 モバイル