]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Fix ICE with functional cast to reference in template [PR123044]
authorEgas Ribeiro <egas.g.ribeiro@tecnico.ulisboa.pt>
Thu, 11 Dec 2025 13:30:49 +0000 (13:30 +0000)
committerJason Merrill <jason@redhat.com>
Fri, 19 Dec 2025 11:13:44 +0000 (18:13 +0700)
When processing a functional cast to a reference type in a template
context, build_functional_cast_1 wasn't calling convert_from_reference.
This left the expression with a reference type, which later triggered
an assertion in implicit_conversion from r15-6709 that expects
expression types to already be dereferenced.

In contrast, cp_build_c_cast already calls convert_from_reference on
the result in template contexts, so C-style casts like (R)x worked
correctly.

The fix makes functional casts consistent with C-style casts by
calling convert_from_reference before returning in the template
processing path.

PR c++/123044

gcc/cp/ChangeLog:

* typeck2.cc (build_functional_cast_1): Call convert_from_reference
on template CAST_EXPR to match C-style cast behavior.

gcc/testsuite/ChangeLog:

* g++.dg/template/implicit-func-cast.C: New test.

Signed-off-by: Egas Ribeiro <egas.g.ribeiro@tecnico.ulisboa.pt>
Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/typeck2.cc
gcc/testsuite/g++.dg/template/implicit-func-cast.C [new file with mode: 0644]

index 3da74e8b0680c7b7eba92f729c0d05ecf3b74905..b090e83c69718b1c1c8e0d8b55ecabdc601a8d8b 100644 (file)
@@ -2630,7 +2630,7 @@ build_functional_cast_1 (location_t loc, tree exp, tree parms,
       t = build_min (CAST_EXPR, type, parms);
       /* We don't know if it will or will not have side effects.  */
       TREE_SIDE_EFFECTS (t) = 1;
-      return t;
+      return convert_from_reference (t);
     }
 
   if (! MAYBE_CLASS_TYPE_P (type))
diff --git a/gcc/testsuite/g++.dg/template/implicit-func-cast.C b/gcc/testsuite/g++.dg/template/implicit-func-cast.C
new file mode 100644 (file)
index 0000000..1be7ed9
--- /dev/null
@@ -0,0 +1,9 @@
+// { dg-do compile }
+
+typedef int& R;
+
+template <typename T>
+void foo (T x)
+{
+  foo (R (x));
+}