Reduced from a DDMD build regression: We've got a function getMemtype which has side effects and returns a class object Bar which has a virtual function isintegral. The function is called in this way: getMemtype().isintegral(). In this call the return value of getMemtype, the reference to a Bar object, is needed twice: Once to get the vtbl entry for isintegral and once to pass the object reference as the this pointer for isintegral. I guess the result of the getMemtype call is not saved properly. We can certainly see that the getMemType function executes twice. @Iain I'll assign this to you as you are more familiar with this code. --------------------------------------------------- import std.stdio; class Bar { bool isintegral() { return false; } } class Symbol { Bar getMemtype() { writeln("foo"); return new Bar(); } } class Enum { Symbol sym; bool isintegral() { return sym.getMemtype().isintegral(); } } void main() { Enum e = new Enum(); e.sym = new Symbol(); e.isintegral(); } ---------------------------------------------------
Blocks new binary releases for travis-CI.
(In reply to Johannes Pfau from comment #0) > Reduced from a DDMD build regression: > > We've got a function getMemtype which has side effects and returns a class > object Bar which has a virtual function isintegral. The function is called > in this way: getMemtype().isintegral(). In this call the return value of > getMemtype, the reference to a Bar object, is needed twice: Once to get the > vtbl entry for isintegral and once to pass the object reference as the this > pointer for isintegral. I guess the result of the getMemtype call is not > saved properly. We can certainly see that the getMemType function executes > twice. > > @Iain I'll assign this to you as you are more familiar with this code. > > --------------------------------------------------- > import std.stdio; > > class Bar > { > bool isintegral() > { > return false; > } > } > > class Symbol > { > Bar getMemtype() > { > writeln("foo"); > return new Bar(); > } > } > > class Enum > { > Symbol sym; > bool isintegral() > { > return sym.getMemtype().isintegral(); > } > } > > void main() > { > Enum e = new Enum(); > e.sym = new Symbol(); > e.isintegral(); > } > --------------------------------------------------- It looks like the expression is saved, but the saved expression is not re-used when passed as a parameter. Analogous to: SAVE_EXPR<this.sym.getMemtype(this.sym)>.isintegral(this.sym.getMemtype(this.sym));
(In reply to Iain Buclaw from comment #2) > > It looks like the expression is saved, but the saved expression is not > re-used when passed as a parameter. > > Analogous to: > > SAVE_EXPR<this.sym.getMemtype(this.sym)>.isintegral(this.sym.getMemtype(this. > sym)); See build_vindex_ref. Where `object` is saved, but in the caller, the unsaved `object` is then passed to `build_method_call`. So this saving of `object` should happen in the caller before calling build_vindex_ref.
https://github.com/D-Programming-GDC/GDC/pull/264