[PATCH] libstdc++: optional: Set _M_engaged after the call to destructor [PR127005]
Jonathan Wakely
jwakely.gcc@gmail.com
Tue Aug 25 19:09:26 GMT 2026
On Tue, 25 Aug 2026, 19:44 Andrea Pinski, <andrew.pinski@oss.qualcomm.com>
wrote:
> On Tue, Aug 25, 2026 at 11:38 AM Andrea Pinski
> <andrew.pinski@oss.qualcomm.com> 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]
>
OK with that summary line, thanks
> 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 <andrew.pinski@oss.qualcomm.com>
> > ---
> > 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
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20260825/338c9e66/attachment-0001.htm>
More information about the Libstdc++
mailing list