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

--- Comment #3 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-16 branch has been updated by Marek Polacek
<[email protected]>:

https://gcc.gnu.org/g:368f72c019d68fec8b496bb4c964cce0d5a0865d

commit r16-9830-g368f72c019d68fec8b496bb4c964cce0d5a0865d
Author: Marek Polacek <[email protected]>
Date:   Thu Oct 1 13:53:32 2026 -0400

    c++/reflection: fix extract-ref [PR127232]

    A couple of problems here:

    [meta.reflection.extract]/5.3 says "If r represents a variable, then
    either that variable is usable in constant expressions or its lifetime
    began within the core constant expression currently under evaluation."
    but I was wrongly using is_constant_expression.  That led to a crash
    because we passed a type to build_address.  For "is usable..." we want
    decl_constant_var_p and for the "its lifetime began..." I'm adding a new
    function.  Using cxx_eval_constant_expression for non-reference
    variables wouldn't work since evaluating a variable as a glvalue always
    succeeds, and as a prvalue fails for e.g. an uninitialized variable
    whose lifetime did begin.

    With this patch, a variable that isn't usable in constant expressions
    throws.  Thus the extract2.C and extract3.C changes; one can use
    object_of to get the object instead.

    Also, DECL_INITIAL of a PARM_DECL is not an initializer but DECL_ARG_TYPE.
    So we need cxx_eval_constant_expression to handle e.g.:

      int g;
      consteval void h (const int &p)
      {
        std::meta::extract<const int &> (^^p);
      }
      consteval { h (g); }

    where we need to get g from the PARM_DECL p, and return "(const int &) &g".

    With cxx_eval_constant_expression with vc_glvalue, the
    maybe_get_reference_referent call is no longer necessary.

    The result should be wrapped in a NOP_EXPR otherwise e.g.

     template <const int &> struct X { };
     same_type<X<g>, X<extract<const int &> (object_of (^^g))>> s1;

    fails: we returned a pointer rather than a value of reference type T.

    This adds a new XFAIL because we don't have P2686 yet.

    It seems that object_of will need similar tweaks but that's for another
    patch.

            PR c++/127232

    gcc/cp/ChangeLog:

            * constexpr.cc (constexpr_global_ctx::in_eval_lifetime_p): New.
            (cxx_constexpr_in_eval_lifetime_p): New.
            * cp-tree.h (cxx_constexpr_in_eval_lifetime_p): Declare.
            * reflect.cc (extract_ref): Check decl_constant_var_p and
            cxx_constexpr_in_eval_lifetime_p instead of
            is_constant_expression.  Use cxx_eval_constant_expression
            instead of DECL_INITIAL for references.  Adjust the checking
            assert.  Drop the maybe_get_reference_referent call.  Build
            a NOP_EXPR around the result.

    gcc/testsuite/ChangeLog:

            * g++.dg/reflect/extract2.C: Adjust dg-error.
            * g++.dg/reflect/extract3.C: Add dg-error.  Add tests using
            object_of.
            * g++.dg/reflect/extract13.C: New test.
            * g++.dg/reflect/extract14.C: New test.

    Reviewed-by: Jason Merrill <[email protected]>
    (cherry picked from commit 947ff08bff31425cdcb02b445f135a1ece869873)

Reply via email to