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