[gcc r11-7645] c++: Fix up calls to immediate functions returning reference [PR99507]
Jakub Jelinek
jakub@gcc.gnu.org
Fri Mar 12 09:12:11 GMT 2021
https://gcc.gnu.org/g:425afe1f0c907e6469cef1672160c9c95177e71a
commit r11-7645-g425afe1f0c907e6469cef1672160c9c95177e71a
Author: Jakub Jelinek <jakub@redhat.com>
Date: Fri Mar 12 10:11:24 2021 +0100
c++: Fix up calls to immediate functions returning reference [PR99507]
build_cxx_call calls convert_from_reference at the end, so if an immediate
function returns a reference, we were constant evaluating not just that
call, but that call wrapped in an INDIRECT_REF. That unfortunately means
it can constant evaluate to something non-addressable, so if code later
needs to take its address it will fail.
The following patch fixes that by undoing the convert_from_reference
wrapping for the cxx_constant_value evaluation and readdding it ad the end.
2021-03-12 Jakub Jelinek <jakub@redhat.com>
PR c++/99507
* call.c (build_over_call): For immediate evaluation of functions
that return references, undo convert_from_reference effects before
calling cxx_constant_value and call convert_from_reference
afterwards.
* g++.dg/cpp2a/consteval19.C: New test.
Diff:
---
gcc/cp/call.c | 4 ++++
gcc/testsuite/g++.dg/cpp2a/consteval19.C | 6 ++++++
2 files changed, 10 insertions(+)
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 7d12fea60f2..33278b57038 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -9504,6 +9504,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
if (immediate_invocation_p (fndecl, nargs))
{
tree obj_arg = NULL_TREE;
+ /* Undo convert_from_reference called by build_cxx_call. */
+ if (REFERENCE_REF_P (call))
+ call = TREE_OPERAND (call, 0);
if (DECL_CONSTRUCTOR_P (fndecl))
obj_arg = cand->first_arg ? cand->first_arg : (*args)[0];
if (obj_arg && is_dummy_object (obj_arg))
@@ -9527,6 +9530,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
call = cxx_constant_value (call, obj_arg);
if (obj_arg && !error_operand_p (call))
call = build2 (INIT_EXPR, void_type_node, obj_arg, call);
+ call = convert_from_reference (call);
}
}
return call;
diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval19.C b/gcc/testsuite/g++.dg/cpp2a/consteval19.C
new file mode 100644
index 00000000000..d742f59070f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/consteval19.C
@@ -0,0 +1,6 @@
+// PR c++/99507
+// { dg-do compile { target c++20 } }
+
+constexpr int i{0};
+consteval const int &iref () { return i; }
+const int *a{&iref ()};
More information about the Gcc-cvs
mailing list