Boost logo

Boost :

Subject: Re: [boost] [optional] get() misses optional r-value overload in contrast to operator* and value()
From: Viktor Sehr (viktor.sehr_at_[hidden])
Date: 2018-03-25 00:33:45


Thanks for the answer, but just so I understand, you said a const-reference
binds directly to a r-value as when passing an r-value to a const reference
argument. Doesn't this mean that both Clang and GCC compiles this
erroneously?

To my understanding, the compiler roughly emits the snippet (2) of the
following possible snippets? (Where the variables named temp_ correspond to
temporaries only existing inside the expression)

1. Defined behavior
auto temp_optional = boost::make_optional(std::make_unique<int>(42));
auto temp_uptr = std::move(temp_optional.value());
const auto& x = temp_uptr;
~temp_optional();
// temp_uptr is alive

2. Undefined behavior
auto temp_optional = boost::make_optional(std::make_unique<int>(42));
auto temp_uptr = std::move(temp_optional.value());
const auto& x = temp_optional.value(); // Whereas value is empty
~temp_uptr()
~temp_optional();

br /Viktor

On Fri, Mar 23, 2018 at 6:21 PM Peter Dimov via Boost <boost_at_[hidden]>
wrote:

> Viktor Sehr wrote:
>
> > Clang (6.0) emits "ud2" instructions for both auto&& and const auto&. If
> > the const auto& can bind directly to an r-value, this must mean Clang is
> > wrong, or am I missing something?
>
> "ud2" is Clang's way of encoding undefined behavior. This is an invalid
> instruction that crashes. Both auto&& and auto const& do the same thing -
> bind to the rvalue reference returned by value() &&.
>
> > GCC on the other hand emits code for both functions, although with slight
> > difference (I'm not skilled enough in assembler to analyze the GCC output
> > in further detail)
> >
> > Code example: https://godbolt.org/g/7fjszE <https://godbolt.org/g/uNJoZB
> >
>
> GCC crashes too, in another creative way. It returns *p, where the pointer
> p
> is [rsp+8], which is NULL. If you change the functions to
>
> int * func1() {
> const auto& x = func0().value();
> return &*x;
> }
>
> you'll see that Clang returns NULL and GCC returns the value in [rsp+8]
> which is also NULL.
>
> So both compilers deliberately dereference a NULL pointer because they see
> that the reference `x` is no longer valid.
>
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk