https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112591

--- Comment #9 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Tomasz Kaminski <[email protected]>:

https://gcc.gnu.org/g:b3c167b61fd75fe9820636d9f7fff7920ca9b084

commit r16-6301-gb3c167b61fd75fe9820636d9f7fff7920ca9b084
Author: Tomasz KamiÅski <[email protected]>
Date:   Thu Dec 11 10:43:44 2025 +0100

    libstdc++: Use union to store non-trivially destructible types in C++17
mode [PR112591]

    This patch disables use of specialization _Uninitialized<_Type, false> for
    non-trivially destructible types by default in C++17, and fallbacks to
    the  primary template, that stores the type in union directly. This makes
the
    ABI consistent between C++17 and C++20 (or later). This partial
specialization
    is no longer required after the changes introduced in
r16-5961-g09bece00d0ec98.

    This fixes non-conformance in C++17 mode where global variables of a
variant
    specialization type, were not statically-initialized for non-trivially
    destructible types, even if initialization of the selected alternative
could
    be performed at compile time. For illustration, the following global
variable
    will be statically initialized after this change:
      std::variant<std::unique_ptr<T>, std::unique_ptr<U>> ptr;

    This constitutes an ABI break, and changes the layout of the types, that
uses
    the same non-trivially copyable both as the base class, as alternative of
the
    variant object that is first member:
      struct EmptyNonTrivial { ~EmptyNonTrivial(); };
      struct Affected : EmptyNonTrivial {
        std::variant<EmptyNonTrivial, char> mem; // mem was at offset zero,
                                                 // will use non-zero offset
now
      };
    After changes the layout of such types consistent with one used for empty
types
    with trivial destructor, or one used for any empty type in C++20 or later.

    For programs affected by this change, it can be reverted in C++17 mode, by
    defining _GLIBCXX_USE_VARIANT_CXX17_OLD_ABI. However, presence of this
macro
    has no effect in C++20 or later modes.

            PR libstdc++/112591

    libstdc++-v3/ChangeLog:

            * include/std/variant (_Uninitialized::_M_get, __get_n)
            (_Uninitialized<_Type, false>): Add
_GLIBCXX_USE_VARIANT_CXX17_OLD_ABI
            check to preprocessor guard.
            * testsuite/20_util/variant/112591.cc: Updated tests.
            * testsuite/20_util/variant/112591_compat.cc: New test.
            * testsuite/20_util/variant/constinit.cc: New test.
            * testsuite/20_util/variant/constinit_compat.cc: New test.

    Reviewed-by: Jonathan Wakely <[email protected]>
    Signed-off-by: Tomasz KamiÅski <[email protected]>

Reply via email to