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