[Bug c++/98665] lvalue ref lifetime extension missing for via sub-object of temporary expression

2021-01-14 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98665

--- Comment #6 from Jonathan Wakely  ---
(In reply to Jonathan Wakely from comment #2)
> GCC should not compile this.

That's now PR c++/98675

[Bug c++/98665] lvalue ref lifetime extension missing for via sub-object of temporary expression

2021-01-13 Thread jgilbert at mozilla dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98665

Jeff Gilbert  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #5 from Jeff Gilbert  ---
Thanks for the clarification!

[Bug c++/98665] lvalue ref lifetime extension missing for via sub-object of temporary expression

2021-01-13 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98665

--- Comment #4 from Jonathan Wakely  ---
Right.

[Bug c++/98665] lvalue ref lifetime extension missing for via sub-object of temporary expression

2021-01-13 Thread jgilbert at mozilla dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98665

--- Comment #3 from Jeff Gilbert  ---
Ok, but this is ok, right?

const auto& i2 = f().i;

[Bug c++/98665] lvalue ref lifetime extension missing for via sub-object of temporary expression

2021-01-13 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98665

--- Comment #2 from Jonathan Wakely  ---
If you make everything constexpr then Clang will correctly diagnose the UB, but
GCC fails to:

constexpr int IntSize() { return sizeof(int); }

#include 

// -

template
class Maybe {
bool mIsSome = false;
T mVal = {};

public:
Maybe() = default;
constexpr Maybe(const T& rhs) : mIsSome(true), mVal(rhs) {}

constexpr T& operator*() {
assert(mIsSome);
return mVal;
}
};

// -

struct Int {
int val = {};

Int() = default;
constexpr Int(int x) : val(x) {}
};

struct Even : public Int {
public:
constexpr static Maybe From(const Int x) {
if (x.val & 1) return {};
return Even{x.val};
}

Even() = default;
private:
constexpr Even(int x) : Int(x) {
assert((val & 1) == 0);
}
};

constexpr int Oops(const Int i) {
const auto& e = *Even::From(i); // lvalue ref lifetime extension of
sub-object
// of temporary?
return e.val + 9; // or UB access?
}

int main()
{
constexpr int i = Oops({});
}

GCC should not compile this.

[Bug c++/98665] lvalue ref lifetime extension missing for via sub-object of temporary expression

2021-01-13 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98665

--- Comment #1 from Jonathan Wakely  ---
Not a bug. This is equivalent to:

struct X { int i; };

X f() { return { 0 }; }

const int& g(const X& x) { return x.i; }

int main()
{
  const auto& i = g(f());
}

The temporary's lifetime is not extended, because the reference doesn't bind
directly to it.