On Thu, 11 Dec 2025, Egas Ribeiro wrote:

> 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.

Good catch!  Sounds right to me, but I'll defer to Jason.

(Just realized that the need to do convert_from_reference within a
template seems to contradict the rule that templated trees should
represent the syntactic not semantic form...)

> 
> 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/cpp/implicit-func-cast.C: New test.
> 
> Signed-off-by: Egas Ribeiro <[email protected]>
> ---
>  gcc/cp/typeck2.cc                                  | 2 +-
>  gcc/testsuite/g++.dg/template/implicit-func-cast.C | 9 +++++++++
>  2 files changed, 10 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/g++.dg/template/implicit-func-cast.C
> 
> diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc
> index d77de9212ed..e59bd08a1c7 100644
> --- a/gcc/cp/typeck2.cc
> +++ b/gcc/cp/typeck2.cc
> @@ -2629,7 +2629,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 00000000000..1be7ed9aee7
> --- /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));
> +}
> -- 
> 2.52.0
> 
> 

Reply via email to