https://gcc.gnu.org/g:ea80d5b13dd9c4fdf979234ae24d5d9559402135

commit r17-1630-gea80d5b13dd9c4fdf979234ae24d5d9559402135
Author: Marek Polacek <[email protected]>
Date:   Fri Jun 12 09:43:52 2026 -0400

    c++/reflection: crash with can_substitute and fn returning ref [PR125764]
    
    Here we crash in convert_from_reference because it gets a FUNCTION_TYPE
    int&().  Since its return type is a reference, it passes the c_f_r check:
    
      if (TREE_TYPE (val)
          && TYPE_REF_P (TREE_TYPE (val)))
    
    and we crash inside that block.
    
    The call isn't needed since r17-1271:
    
      return convert_nontype_argument (type, convert_from_reference (arg),
                      complain);
    
    but we can also avoid calling it on TYPE_P because the function is meant
    for expressions only.
    
            PR c++/125764
    
    gcc/cp/ChangeLog:
    
            * reflect.cc (eval_can_substitute): Don't call
            convert_from_reference on types.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/reflect/can_substitute3.C: New test.
    
    Reviewed-by: Patrick Palka <[email protected]>

Diff:
---
 gcc/cp/reflect.cc                              |  3 ++-
 gcc/testsuite/g++.dg/reflect/can_substitute3.C | 10 ++++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc
index e0b7312c795f..8dccf5e99a05 100644
--- a/gcc/cp/reflect.cc
+++ b/gcc/cp/reflect.cc
@@ -5524,7 +5524,8 @@ eval_can_substitute (location_t loc, const constexpr_ctx 
*ctx,
        return throw_exception (loc, ctx,
                                "invalid argument to can_substitute",
                                fun, non_constant_p, jump_target);
-      a = convert_from_reference (a);
+      if (!TYPE_P (a))
+       a = convert_from_reference (a);
       TREE_VEC_ELT (rvec, i) = a;
     }
   if (DECL_TYPE_TEMPLATE_P (r) || DECL_TEMPLATE_TEMPLATE_PARM_P (r))
diff --git a/gcc/testsuite/g++.dg/reflect/can_substitute3.C 
b/gcc/testsuite/g++.dg/reflect/can_substitute3.C
new file mode 100644
index 000000000000..98b8fbb315f9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/can_substitute3.C
@@ -0,0 +1,10 @@
+// PR c++/125764
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+
+#include <meta>
+
+template <typename T>
+struct S {};
+
+static_assert(can_substitute(^^S, {^^int&()}));

Reply via email to