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

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

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

commit r17-4132-ga8c97564fbc39b5c52dffaa3c8229c396632e28d
Author: Jakub Jelinek <[email protected]>
Date:   Thu Sep 10 16:47:57 2026 +0200

    c++, libstdc++: Implement C++26 P3726R2 - Adjustments to Union Lifetime
Rules [PR125845]

    The following patch attempts to implement the C++26
    P3726R2 - Adjustments to Union Lifetime Rules
    paper except the
      #define __cpp_lib_constexpr_inplace_vector 2025XXL // also in
<inplace_vector>
    addition and possibly needed <inplace_vector> changes (will defer that to
    Jonathan / Tomasz).

    For std::start_lifetime I've added a FE builtin which unlike the standard
    function template takes a pointer rather than reference, because it needs
to
    be type-generic and for (...) it would attempt to pass a copy of the
    referenced object rather than the reference.  As I didn't want to duplicate
    most of the cxx_eval_store_expression function for its constant evaluation,
    I'm calling cxx_eval_store_expression on an artificial MODOP_EXPR with
    lhs as first operand and init as second operand and
cxx_eval_store_expression
    handles MODOP_EXPR as __builtin_start_lifetime where needed, in some
    cases it doesn't do anything (if already within lifetime), otherwise can
set
    an element to an empty CONSTRUCTOR_NO_CLEARING
    CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P CONSTRUCTOR.
    CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P is a new flag which says that
    the (sub)object represented by the CONSTRUCTOR is within lifetime, but
    its omitted elements are not.
    The builtin will be non-constant if there is a containing object of the
    referenced subobject and the containing object is not within lifetime.

    In reduced_constant_expression_p the patch also implements the second
    part of P3726R2, the changes to union elemental subobject handling, where
    it ignores holes for C++26 in arrays (possibly multi-dimensional) directly
    nested inside of union if they aren't active.

    2026-09-10  Jakub Jelinek  <[email protected]>

            P3726R2
            PR c++/125845
    gcc/c-family/
            * c-cppbuiltin.cc (c_cpp_builtins): For C++26 predefine
            __cpp_trivial_union to 202603L.
    gcc/cp/
            * cp-tree.h: Implement C++26 P3726R2 - Adjustments to Union
Lifetime
            Rules.  Document some generic flags used in C++ specific way on
some
            trees in the toplevel comment.
            (CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P): Define.
            (enum cp_built_in_function): Add CP_BUILT_IN_START_LIFETIME.
            (reduced_constant_expression_p): Add a bool argument defaulted to
            false.
            * tree.cc (builtin_valid_in_constant_expr_p): Handle
            CP_BUILT_IN_START_LIFETIME.
            * decl.cc (cxx_init_decl_processing): Create
__builtin_start_lifetime
            decl.
            * cp-gimplify.cc (cp_gimplify_expr): Handle
            CP_BUILT_IN_START_LIFETIME.
            * semantics.cc (check_frontend_builtin): New function.
            (finish_call_expr): Use it.
            * constexpr.cc (is_within_lifetime): New function.
            (cxx_eval_is_within_lifetime): Use it.  Add fun argument and pass
it
            to that function.
            (cxx_eval_start_lifetime): New function.
            (cxx_eval_builtin_function_call): Handle
CP_BUILT_IN_START_LIFETIME.
            Pass fun to cxx_eval_is_within_lifetime.
            (is_std_allocator_allocate): Only return true for
            std::allocator<T>::allocate and not for
std::allocator<T>::deallocate.
            (is_std_allocator_allocate_deallocate): New functions.
            (cxx_eval_call_expression): Use
is_std_allocator_allocate_deallocate
            rather than is_std_allocator_allocate.
            (reduced_constant_expression_p): Add union_elemental_subobject
            argument and propagate it to recursive calls.  If set, ignore for
            C++26 holes in array initializers which aren't within lifetime.
            (modifying_const_object_p): Change != MODIFY_EXPR test to ==
INIT_EXPR.
            (cxx_eval_store_expression): Handle MODOP_EXPR next to INIT_EXPR
and
            MODIFY_EXPR, meaning start_lifetime.  Don't preevaluate init in
that
            case, return void_node early if *valp is already non-NULL/void_node
            and within lifetime.
            (cxx_eval_constant_expression): For std::allocator<T>::allocate
            start lifetime of the created array but not of its subobjects.
            Use is_std_allocator_allocate_deallocate rather than
            is_std_allocator_allocate where appropriate.
            (potential_constant_expression_1): Likewise.
    gcc/testsuite/
            * g++.dg/cpp26/feat-cxx26.C: Adjust __cpp_trivial_union checking.
            * g++.dg/cpp26/trivial-union3.C: New test.
            * g++.dg/cpp26/trivial-union4.C: New test.
            * g++.dg/cpp26/trivial-union5.C: New test.
            * g++.dg/cpp26/trivial-union6.C: New test.
            * g++.dg/cpp26/within-lifetime3.C: Remove #if 0 and #endif.
            * g++.dg/cpp26/within-lifetime8.C: New test.
            * g++.dg/cpp26/within-lifetime9.C: New test.
            * g++.dg/cpp29/feat-cxx29.C: Adjust __cpp_trivial_union checking.
    libstdc++-v3/
            * include/bits/version.def (start_lifetime): New.
            * include/bits/version.h: Regenerate.
            * include/bits/stl_construct.h (std::start_lifetime): New function
            template.
            * include/std/memory: Define __glibcxx_want_start_lifetime before
            including bits/version.h.
            * src/c++23/std.cc.in: Add export std::start_lifetime.

    Reviewed-by: Jason Merrill <[email protected]>

Reply via email to