On 27 June 2016 at 04:38, Timon Gehr via Digitalmars-d <[email protected]> wrote: > On 26.06.2016 20:08, Iain Buclaw via Digitalmars-d wrote: >> >> On 26 June 2016 at 14:33, Timon Gehr via Digitalmars-d >> <[email protected]> wrote: >>> >>> On 26.06.2016 10:08, Iain Buclaw via Digitalmars-d wrote: >>>> >>>> >>>> Old codegen: >>>> >>>> _base = *(getBase()); >>>> _lwr = getLowerBound(_base.length); >>>> _upr = getUpperBound(_base.length); >>>> r = {.length=(_upr - _lwr), .ptr=_base.ptr + _lwr * 4}; >>>> >>>> --- >>> >>> >>> >>> This seems to be what I'd expect. It's also what CTFE does. >>> CTFE and run time behaviour should be identical. (So either one of them >>> needs to be fixed.) >>> >>> >> >> Very likely CTFE. Anyway, this isn't the only thing where CTFE and >> Runtime do things differently. >> ... > > > All arbitrary differences should be eradicated. > >>>> Now when creating temporaries of references, the reference is stabilized >>>> instead. >>>> >>>> New codegen: >>>> >>>> *(_ptr = getBase()); >>>> _lwr = getLowerBound(_ptr.length); >>>> _upr = getUpperBound(_ptr.length); >>>> r = {.length=(_upr - _lwr), .ptr=_ptr.ptr + _lwr * 4}; >>>> --- >>>> >>>> I suggest you fix LDC if it doesn't already do this. :-) >>> >>> >>> >>> >>> I'm not convinced this is a good idea. It makes >>> (()=>base)()[lwr()..upr()] >>> behave differently from base[lwr()..upr()]. >> >> >> No, sorry, I'm afraid you are wrong there. They should both behave >> exactly the same. >> ... > > > I don't see how that is possible, unless I misunderstood your previous > explanation. As far as I understand, for the first expression, code gen will > generate a reference to a temporary copy of base, and for the second > expression, it will generate a reference to base directly. If lwr() or upr() > then update the ptr and/or the length of base, those changes will be seen > for the second slice expression, but not for the first. > > >> I may need to step aside and explain what changed in GDC, as it had >> nothing to do with this LDC bug. >> >> ==> Step >> >> What made this subtle change was in relation to fixing bug 42 and 228 >> in GDC, which involved turning on TREE_ADDRESSABLE(type) bit in our >> codegen trees, which in turn makes NRVO work consistently regardless >> of optimization flags used - no more optimizer being confused by us >> "faking it". >> >> How is the above jargon related? Well, one of the problems faced was >> that it must be ensured that lvalues continue being lvalues when >> considering creating a temporary in the codegen pass. Lvalue >> references must have the reference stabilized, not the value that is >> being dereferenced. This also came with an added assurance that GDC >> will now *never* create a temporary of a decl with a cpctor or dtor, >> else it'll die with an internal compiler error trying. :-) >> ... > > > What is the justification why the base should be evaluated as an lvalue? >
Because changes made to a temporary get lost as they never bind back to the original reference. Regardless, creating a temporary of a struct with a cpctor violates the semantics of the type - it's the job of the frontend to generate all the code for lifetime management for us. (Sorry for the belated response, I have been distracted).
