On Tue, Aug 25, 2026 at 11:38 AM Andrea Pinski <[email protected]> wrote: > > Sometimes the destructor will cause the optimizers not to see that > _M_engaged has been to set to false (e.g. an external call). This > means that we might get an uninitialized warning after the destructor > in some cases. > Adding `if (_M_engaged) __builtin_unreachable(); ` after the destructor > will allow for the optimizations to know that the value of _M_engaged > is 0 afterwards. This helps with optimizations and the uninitialized warning.
One minor change I did to this patch, the subject/summary line is now: libstdc++: optional: Treat _M_engaged as being assumed to be false after the destructor [PR127005] I had forgot to update it before sending it out. Sorry about that. > > PR libstdc++/127005 > > libstdc++-v3/ChangeLog: > > * include/std/optional (optional::_M_destroy): Add an assumption on > _M_engaged > being false after the destructor call. > > gcc/testsuite/ChangeLog: > > * g++.dg/warn/Wuninitialized-36.C: New test. > > Signed-off-by: Andrea Pinski <[email protected]> > --- > gcc/testsuite/g++.dg/warn/Wuninitialized-36.C | 26 +++++++++++++++++++ > libstdc++-v3/include/std/optional | 3 +++ > 2 files changed, 29 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/warn/Wuninitialized-36.C > > diff --git a/gcc/testsuite/g++.dg/warn/Wuninitialized-36.C > b/gcc/testsuite/g++.dg/warn/Wuninitialized-36.C > new file mode 100644 > index 00000000000..aacb3f4e6a4 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/warn/Wuninitialized-36.C > @@ -0,0 +1,26 @@ > +// PR tree-optimization/127005 > +// { dg-do compile { target c++17 } } > +// { dg-options "-O2 -W -Wall" } > + > +#include <optional> > + > +void f(int *); > +struct s1 > +{ > + int *a; > + ~s1() > + { > + f(a); // { dg-bogus "uninitialized" } > + } > +}; > + > +struct conn { > + void close() { guard.reset(); } > + std::optional<s1> guard; > +}; > +extern conn make_conn(); > +int main() > +{ > + conn c = make_conn(); > + c.close(); > +} > diff --git a/libstdc++-v3/include/std/optional > b/libstdc++-v3/include/std/optional > index d6fd33e8c2e..b56a3366ab7 100644 > --- a/libstdc++-v3/include/std/optional > +++ b/libstdc++-v3/include/std/optional > @@ -303,6 +303,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > { > _M_engaged = false; > _M_payload._M_value.~_Stored_type(); > + // After the destructor, _M_engaged should always be false, see PR > 127005. > + if (_M_engaged) > + __builtin_unreachable(); > #if defined(__clang__) && __cpp_lib_optional >= 202106L // full constexpr > support > if (std::is_constant_evaluated()) > // Work around PR124910 for Clang. > -- > 2.43.0 >
