https://gcc.gnu.org/g:8bc8aaed6c22fac5f66be11e92001665c20716ef
commit r16-7281-g8bc8aaed6c22fac5f66be11e92001665c20716ef Author: Jakub Jelinek <[email protected]> Date: Wed Feb 4 12:30:42 2026 +0100 c++: Fix up eval_parameters_of for function types [PR123913] eval_parameters_of was trying to share 3 lines of code between the function declaration and function type cases, but got it wrong in multiple ways for the latter. One thing is that we should override reflect_kind only for the function decl case to REFLECT_PARM, there we need to differentiate function parameter reflection vs. variable reflection, for function type it is just type. Another one is that we iterate over PARM_DECLs through DECL_CHAIN in the function decl case, but for types we iterate over the TREE_LIST nodes and the type is only TREE_VALUE of that. And last, but am not sure about that, maybe https://eel.is/c++draft/meta.reflection#queries-62.2 should be clarified, I think we want to apply dealias. We have notes like https://eel.is/c++draft/meta.reflection#queries-note-7 https://eel.is/c++draft/meta.reflection#traits-5 but those don't apply to type_of or parameters_of. And I think there was an agreement that meta fns which return reflection of a type don't return type aliases, but can't see it written explicitly except for the traits. 2026-02-04 Jakub Jelinek <[email protected]> PR c++/123913 PR c++/123964 * reflect.cc (eval_parameters_of): Fix up handling of function types. * g++.dg/reflect/parameters_of7.C: New test. Diff: --- gcc/cp/reflect.cc | 18 ++++++++++++------ gcc/testsuite/g++.dg/reflect/parameters_of7.C | 17 +++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc index 3cf4c31ad627..624414e23466 100644 --- a/gcc/cp/reflect.cc +++ b/gcc/cp/reflect.cc @@ -3001,12 +3001,18 @@ eval_parameters_of (location_t loc, const constexpr_ctx *ctx, tree r, r = maybe_get_first_fn (r); vec<constructor_elt, va_gc> *elts = nullptr; - tree args = (TREE_CODE (r) == FUNCTION_DECL - ? FUNCTION_FIRST_USER_PARM (r) - : TYPE_ARG_TYPES (r)); - for (tree arg = args; arg && arg != void_list_node; arg = TREE_CHAIN (arg)) - CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, - get_reflection_raw (loc, arg, REFLECT_PARM)); + if (TREE_CODE (r) == FUNCTION_DECL) + for (tree arg = FUNCTION_FIRST_USER_PARM (r); arg; arg = DECL_CHAIN (arg)) + CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, + get_reflection_raw (loc, arg, REFLECT_PARM)); + else + for (tree arg = TYPE_ARG_TYPES (r); arg && arg != void_list_node; + arg = TREE_CHAIN (arg)) + { + tree type = maybe_strip_typedefs (TREE_VALUE (arg)); + CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, + get_reflection_raw (loc, type)); + } return get_vector_of_info_elts (elts); } diff --git a/gcc/testsuite/g++.dg/reflect/parameters_of7.C b/gcc/testsuite/g++.dg/reflect/parameters_of7.C new file mode 100644 index 000000000000..e17dbcc13db0 --- /dev/null +++ b/gcc/testsuite/g++.dg/reflect/parameters_of7.C @@ -0,0 +1,17 @@ +// PR c++/123913 +// PR c++/123964 +// { dg-do compile { target c++26 } } +// { dg-additional-options "-freflection" } + +#include <meta> + +using I = long; +void foo (int, I) {} +using bar = void (int, I); + +constexpr auto a = std::meta::reflect_constant_array (parameters_of (^^foo)); +constexpr auto b = std::meta::reflect_constant_array (parameters_of (^^bar)); +static_assert (is_function_parameter (parameters_of (^^foo)[0])); +static_assert (is_function_parameter (parameters_of (^^foo)[1])); +static_assert (parameters_of (^^bar)[0] == ^^int); +static_assert (parameters_of (^^bar)[1] == ^^long);
