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

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

https://gcc.gnu.org/g:127bd0f40827d7472cebacd2093d3379ec25dbd7

commit r17-4197-g127bd0f40827d7472cebacd2093d3379ec25dbd7
Author: Marek Polacek <[email protected]>
Date:   Tue Aug 4 16:10:55 2026 -0400

    c++/reflection: P4101, Consteval-only values [PR125820]

    <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4101r1.html>
    changes the consteval-only type model to a consteval-only values model.
    A null reflection is no longer consteval-only.

    So, for instance, this is now OK:

      std::meta::info i;
      auto foo (std::meta::info i) { return i; } // not consteval

    but

      std::meta::info type = ^^int;

    is still ill-formed, provided it's not in an immediate function context

    I suppose for users the change is not that dramatic, but our
    implementation had to change quite a bit.

    For one thing, we now need to be able to handle null reflections in the
    ME.  This is done by removing META_TYPE and using LANG_TYPE instead.
    In dwarf2out, LANG_TYPE already maps to DW_TAG_unspecified_type
    so we should get "decltype(^^int)" in debug info.

    To be able to detect invalid code like the bare:

      ^^int;

    and to allow code like:

      int i = (^^int, 42); // namespace scope

    convert_to_void no longer throws away discarded-value expressions.  But
    the modules and analyzer code sort of depended on these being
    discarded.  Obviously, first we have to check for consteval-only values
    and only then can we discard them.  But we need to do the discarding
    before maybe_save_constexpr_fundef; otherwise we'd have to add a separate
    walk for the copy.  I moved the discarding into cp_fold_r.  Consteval-only
    values are now checked right before the discarding and in cp_genericize_r.

    As mentioned above, a null reflection can get into the ME, but REFLECT_EXPR
    still can't.  rewrite_null_reflection rewrites REFLECT_EXPRs representing
    a null reflection to zero.

    The gcov-24.C change is arguably a fix, caused by adding a location to
    the CONVERT_EXPR in convert_to_void.  genericize_c_loop has

      location_t incr_locus = expr_loc_or_loc (incr, start_locus);
      protected_set_expr_location_if_unset (incr, start_locus);

    where incr is the CONVERT_EXPR.  Previously its location was
UNKNOWN_LOCATION
    so _if_unset set start_locus, but now the increment stays on line 41.

    Taking the address of a consteval function is no longer prohibited outside
    an immediate function context, provided the result initializes a constexpr
    variable.  I didn't want to inflate the patch with testsuite changes for
all
    the consteval tests that will need to be updated once this is resolved.

            PR c++/125820
            PR c++/124249
            PR c++/124414

    gcc/cp/ChangeLog:

            * constexpr.cc (cxx_eval_binary_expression): Check
            REFLECTION_TYPE_P instead of REFLECT_EXPR_P.
            (check_bit_cast_type): Also detect REFLECTION_TYPE_P.
            (cxx_eval_outermost_constant_expr): Delete consteval-only
            smuggling detection code.
            (potential_constant_expression_1) <case CONVERT_EXPR>: Recurse
            with want_rval=false for discarded-value expressions.
            * constraint.cc (satisfy_atom): Check require_constant_expression
            before calling cxx_constant_value.  Set result to error_mark_node
            otherwise.
            * cp-gimplify.cc (cp_gimplify_expr) <case CALL_EXPR>: Don't call
            consteval_only_p and check_out_of_consteval_use.
            (wipe_consteval_only_r): Remove.
            (cp_fold_immediate_r): Don't detect invalid uses of consteval-only
            types here.  Set *stmt_p to error_mark_node if the consteval call
            was invalid.
            <case IF_STMT>: Don't call wipe_consteval_only_r.
            (cp_fold_r) <case CONVERT_EXPR>: New, remove discarded-value
            expressions.
            (cp_genericize_r) <case ADDR_EXPR>: Call
check_out_of_consteval_use.
            <case BIND_EXPR>: Call rewrite_null_reflection before pruning.
            <case REFLECT_EXPR>: Detect invalid uses of consteval-only
            expressions.
            * cp-objcp-common.cc (cp_common_init_ts): Remove the META_TYPE
            marking.
            * cp-tree.def (META_TYPE): Remove.
            * cp-tree.h (REFLECTION_TYPE_P): Adjust to check if TYPE is
            meta_info_type_node.
            (rewrite_null_reflection): Declare.
            (consteval_only_p): No longer pure.
            (check_consteval_only_fn): Remove.
            * cvt.cc (convert_to_void): Don't call check_out_of_consteval_use
            here.  Don't remove discarded-value expressions here.  Use a
            location when building the CONVERT_EXPR.
            * cxx-pretty-print.cc (cxx_pretty_printer::simple_type_specifier)
            <case META_TYPE>: Remove.
            <case LANG_TYPE>: New.
            (cxx_pretty_printer::type_id) <case META_TYPE>: Remove.
            <case LANG_TYPE>: New.
            * decl.cc (wrapup_namespace_globals): Call
            rewrite_null_reflection on each element of statics.
            (cp_finish_decl): Don't call check_out_of_consteval_use.  Assert
            !consteval_only_p.
            (grokfndecl): Don't call check_consteval_only_fn.
            * decl2.cc (maybe_make_one_only): Don't return early for
            consteval_only_p.
            (mark_needed): Likewise.
            (prune_vars_needing_no_initialization): Don't prune
            consteval_only_p variables.
            (c_parse_final_cleanups): Call rewrite_null_reflection.
            * error.cc (dump_type) <case LANG_TYPE>: Handle
            REFLECTION_TYPE_P.
            <case META_TYPE>: Remove.
            (dump_type_prefix) <case META_TYPE>: Remove.
            (dump_type_suffix) <case META_TYPE>: Remove.
            (dump_expr): Use REFLECTION_TYPE_P.
            * init.cc (perform_member_init): Don't call
            check_out_of_consteval_use.
            * mangle.cc (write_type) <case META_TYPE>: Remove.
            <case LANG_TYPE>: Handle REFLECTION_TYPE_P.
            * module.cc (trees_out::type_node) <case META_TYPE>: Remove.
            <case LANG_TYPE>: New.
            (trees_in::tree_node) <case META_TYPE>: Remove.
            <case LANG_TYPE>: New.
            * name-lookup.cc (name_lookup::adl_type): Move the
            REFLECTION_TYPE_P handling to case LANG_TYPE.
            * pt.cc (tsubst) <case META_TYPE>: Remove.
            (unify) <case META_TYPE>: Remove.
            <case LANG_TYPE>: New.
            (instantiate_body): Don't call check_consteval_only_fn.
            * reflect.cc (init_reflection): Use LANG_TYPE instead of
            META_TYPE for meta_info_type_node.
            (null_reflection_p): Also accept the rewritten form.
            (rewrite_null_reflection): New.
            (consteval_only_p): Rewrite for P4101.
            (struct consteval_only_p_walker): Remove.
            (consteval_only_value_p): New.
            (consteval_only_p_walker::walk): Remove.
            (check_out_of_consteval_use_r): Walk INIT_EXPR.  Handle EXPR_STMT
            specially.
            (check_out_of_consteval_use): Remove the special VAR_P handling.
            (compare_reflections): Deal with null reflections first.
            (check_consteval_only_fn): Remove.
            * search.cc (check_final_overrider): Don't check
            consteval_only_p.
            * semantics.cc (cp_build_bit_cast): Likewise.
            * tree.cc (type_has_unique_obj_representations) <case LANG_TYPE>:
            New, handle REFLECTION_TYPE_P.
            * typeck.cc (cp_build_binary_op): Use REFLECTION_TYPE_P.
            (check_return_expr): Don't call check_out_of_consteval_use.
            * typeck2.cc (store_init_value): Check that an immediate object
            is associated with a constexpr variable.

    gcc/ChangeLog:

            * expr.cc (count_type_elements) <case LANG_TYPE>: Return 1.
            * tree.cc (wide_int_to_tree_1) <case LANG_TYPE>: New.
            (cache_integer_cst) <case LANG_TYPE>: New.

    libstdc++-v3/ChangeLog:

            * include/std/meta (std::meta::exception::what): Change it to
            constexpr.

    gcc/testsuite/ChangeLog:

            * g++.dg/cpp2a/concepts-uneval3.C: Add a dg-error.
            * g++.dg/gcov/gcov-24.C: Adjust expected output.
            * g++.dg/reflect/bit_cast.C: Remove dg-error.  Extend.
            * g++.dg/reflect/crash12.C: Remove dg-error.
            * g++.dg/reflect/crash18.C: Likewise.
            * g++.dg/reflect/diag3.C: Adjust expected output.
            * g++.dg/reflect/expr11.C: Likewise.
            * g++.dg/reflect/expr12.C: Likewise.
            * g++.dg/reflect/init10.C: Likewise.
            * g++.dg/reflect/init11.C: Likewise.
            * g++.dg/reflect/init12.C: Remove dg-error.
            * g++.dg/reflect/init16.C: Adjust expected output.
            * g++.dg/reflect/init19.C: Remove dg-error.
            * g++.dg/reflect/init4.C: Add an XFAIL.
            * g++.dg/reflect/init5.C: Remove dg-error.
            * g++.dg/reflect/init6.C: Adjust expected output.
            * g++.dg/reflect/init7.C: Likewise.
            * g++.dg/reflect/init9.C: Likewise.
            * g++.dg/reflect/override1.C: Likewise.
            * g++.dg/reflect/p2996-15.C: Remove dg-error.
            * g++.dg/reflect/parm3.C: Adjust expected output.
            * g++.dg/reflect/parm4.C: Likewise.
            * g++.dg/reflect/pr124012.C: Remove dg-error.
            * g++.dg/reflect/type12.C: Likewise.
            * g++.dg/reflect/type2.C: Adjust expected output.
            * g++.dg/reflect/bit_cast2.C: New test.
            * g++.dg/reflect/expr19.C: New test.
            * g++.dg/reflect/null7.C: New test.
            * g++.dg/reflect/type_trait19.C: New test.
            * g++.dg/reflect/typeinfo1.C: New test.
            * g++.dg/reflect/value1.C: New test.
            * g++.dg/reflect/value2.C: New test.
            * g++.dg/reflect/value3.C: New test.
            * g++.dg/reflect/value4.C: New test.
            * g++.dg/reflect/value5.C: New test.
            * g++.dg/reflect/value6.C: New test.
            * g++.dg/reflect/value7.C: New test.
            * g++.dg/reflect/value8.C: New test.
            * g++.dg/reflect/vector2.C: New test.

    Reviewed-by: Jason Merrill <[email protected]>
  • [Bug c++/124249] [reflection] w... cvs-commit at gcc dot gnu.org via Gcc-bugs

Reply via email to