On 2/4/26 6:20 PM, Jakub Jelinek wrote:
Hi!
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.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK.
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.
--- gcc/cp/reflect.cc.jj 2026-02-03 09:19:16.220986590 +0100
+++ gcc/cp/reflect.cc 2026-02-04 01:32:24.151662970 +0100
@@ -3001,12 +3001,18 @@ eval_parameters_of (location_t loc, cons
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);
}
--- gcc/testsuite/g++.dg/reflect/parameters_of7.C.jj 2026-02-04 01:06:06.830384595 +0100
+++ gcc/testsuite/g++.dg/reflect/parameters_of7.C 2026-02-04
01:29:45.826247899 +0100
@@ -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);
Jakub