https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121068
Jason Merrill <jason at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Status|UNCONFIRMED |NEW Last reconfirmed| |2025-07-21 Assignee|unassigned at gcc dot gnu.org |jason at gcc dot gnu.org --- Comment #8 from Jason Merrill <jason at gcc dot gnu.org> --- (In reply to Tomasz KamiĆski from comment #6) > I believed that `_member` being active after new should directly fall from > the definition of active member in > https://eel.is/c++draft/class.union#general-2: > > In a union, a non-static data member is active if its name refers to an > > object whose lifetime has begun and has not ended ([basic.life]). > > So if new operations, starts lifetime of member of the union (regardless of > how) it becomes active member of the union, until it's lifetime is ended. I > do not think that syntax how does it happen matters. Sure, that matches this comment in cxx_eval_store_expression: /* An INIT_EXPR of the last member in an access chain is always OK, so I tried changing the clobber to happen regardless of the syntax of the placement argument. This mostly worked well, including fixing an xfail in one of the constexpr new tests. But it also ran into trouble on the current libstdc++ construct_at, which when told to construct a _Tp where _Tp is an array type, instead tries to construct a _Tp[1], which seems undefined to me; there is no such multidimensional array at that location. This is related to LWG issue 3436. The proposed resolution there seems reasonable, so I'm trying this library change: index 217a0416d42..1ba9740e90d 100644 --- a/libstdc++-v3/include/bits/stl_construct.h +++ b/libstdc++-v3/include/bits/stl_construct.h @@ -104,7 +104,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static_assert(sizeof...(_Args) == 0, "std::construct_at for array " "types must not use any arguments to initialize the " "array"); - return ::new(__loc) _Tp[1](); + __loc = ::new(__loc) _Tp(); +#if __cpp_lib_launder + return std::launder(__location); +#else + return static_cast<_Tp*>(__loc); +#endif