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