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);

Reply via email to