https://gcc.gnu.org/g:93c0642bb54ee3205db666a47a06f87d6c50eff2

commit r16-6275-g93c0642bb54ee3205db666a47a06f87d6c50eff2
Author: Egas Ribeiro <[email protected]>
Date:   Thu Dec 11 13:30:49 2025 +0000

    c++: Fix ICE with functional cast to reference in template [PR123044]
    
    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 <[email protected]>
    Reviewed-by: Jason Merrill <[email protected]>

Diff:
---
 gcc/cp/typeck2.cc                                  | 2 +-
 gcc/testsuite/g++.dg/template/implicit-func-cast.C | 9 +++++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc
index 3da74e8b0680..b090e83c6971 100644
--- a/gcc/cp/typeck2.cc
+++ b/gcc/cp/typeck2.cc
@@ -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
index 000000000000..1be7ed9aee79
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/implicit-func-cast.C
@@ -0,0 +1,9 @@
+// { dg-do compile }
+
+typedef int& R;
+
+template <typename T>
+void foo (T x)
+{
+  foo (R (x));
+}

Reply via email to