[cfe-dev] Smart Pointer Lifetime Optimizations

John McCall via cfe-dev cfe-dev at lists.llvm.org
Wed Jun 10 13:06:37 PDT 2020


On 10 Jun 2020, at 15:55, Richard Smith wrote:
> On Wed, 10 Jun 2020 at 12:18, John McCall via cfe-dev <
> cfe-dev at lists.llvm.org> wrote:
>
>> On 10 Jun 2020, at 14:32, Richard Smith wrote:
>>> On Mon, 8 Jun 2020 at 19:52, John McCall via cfe-dev
>>> <cfe-dev at lists.llvm.org>
>>> wrote:
>>>> It definitely changes observable semantics, but it’s not
>>>> *obviously*
>>>> non-conforming; [expr.call]p7 gives us a lot of flexibility here:
>>>>
>>>> It is implementation-defined whether the lifetime of a parameter
>>>> ends when the function in which it is defined returns or at the
>>>> end of the enclosing full-expression.
>>>>
>>> This is the non-conformance I'm referring to:
>>> https://godbolt.org/z/cgf5_2
>>>
>>> Even given [expr.call]p7, we are still required to destroy
>>> automatic-storage-duration objects in reverse construction order by
>>> [stmt.jump]p2:
>>>
>>> "On exit from a scope (however accomplished), objects with automatic
>>> storage duration (6.7.5.3) that have been constructed in that scope
>>> are
>>> destroyed in the reverse order of their construction."
>>
>> Don’t temporaries not have automatic storage duration formally?
>>
>
> The intent is that they don't; we have a longstanding open issue to
> introduce a notion of "full-expression storage duration" to describe
> temporary objects. But in the absence of such a language change, it's
> unclear which utterances about "automatic storage duration" apply to
> temporaries.
>
> But in any case, I think that's immaterial here, because function
> parameters are local variables, not temporary objects, and do have
> automatic storage duration even in the hypothetical world where there's a
> different storage duration for temporaries.
>
> That’s why [class.temporary]p7 has to spell out the interordering
>> of destruction of lifetime-extended temporaries.
>>
>> [expr.call]p7 is the most specific statement about the destruction
>> of parameters.   Under normal principles of interpretation, it should
>> take priority.
>
> Well, p7 says nothing about the relative ordering of parameter
> destructions, only the points where such destruction may occur.

Not relative with each other, but I think it has to be understood
as allowing differences relative to temporaries created by the calling
full-expression.

>> Doing the parameters in reverse order seems like a more serious problem,
>> but one that we can address very specifically.  On targets where we
>> normally emit left-to-right (everywhere except MS, right?), we can
>> just destroy arguments right-to-left in the caller. I think we
>> probably do this already, because we probably push cleanups
>> left-to-right.
>
> We can't destroy [[trivial_abi]] parameters in the caller.

Argh, sorry, I meant “callee” here.

>> The one exception about argument order is with
>> assignment operators, where the standard forces us to emit the RHS
>> first.  Simple assignment operators can only be declared as non-static
>> member functions with one parameter, so there can only be one by-value
>> parameter in the first place.  Compound assignment operators could in
>> theory be overloaded with two by-value parameters, but of course
>> they’ll usually have a reference on the LHS instead.  If we really
>> feel strongly about this case, we could destroy left-to-right and
>> thus make this only a problem when someone takes the address of an
>> oddly-defined overloaded compound assignment operator.  Or we could
>> call it a standard bug, yeah.
>
> I'm arguing on the core reflector right now that this case is a standard
> bug :) I think it would be great if we only got this wrong for an
> address-taken non-member operator$= function (that's the only case where
> right-to-left argument evaluation order is mandated and observable).

Yeah.

John.


More information about the cfe-dev mailing list