aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2021-03-02 23:59:00 -0500
committerJason Merrill <jason@redhat.com>2021-03-03 08:47:03 -0500
commit74aee6d20872e8d87558eb5bf601042e3ed3fb2a (patch)
tree7c77a9a101ce563964138373cf31b0c8a6aa2f2f /gcc/cp
parent5bc3a2bc8a810e7a9a51d7069463f1f460d6a588 (diff)
downloadgcc-74aee6d20872e8d87558eb5bf601042e3ed3fb2a.zip
gcc-74aee6d20872e8d87558eb5bf601042e3ed3fb2a.tar.gz
gcc-74aee6d20872e8d87558eb5bf601042e3ed3fb2a.tar.bz2
c++: C++17 and decltype of multi-operator expression [PR95675]
A call that is the immediate operand of decltype has special semantics: no temporary is produced, so it's OK for the return type to be e.g. incomplete. But we were treating (e | f) the same way, which confused overload resolution when we then tried to evaluate ... | g. Fixed by making build_temp do what its name says, and force the C++17 temporary materialization conversion. gcc/cp/ChangeLog: PR c++/95675 * call.c (build_temp): Wrap a CALL_EXPR in a TARGET_EXPR if it didn't get one before. gcc/testsuite/ChangeLog: PR c++/95675 * g++.dg/cpp0x/decltype-call5.C: New test. * g++.dg/cpp0x/decltype-call6.C: New test.
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/call.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 0ba0e19..b00334d 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7291,6 +7291,14 @@ build_temp (tree expr, tree type, int flags,
&& !type_has_nontrivial_copy_init (TREE_TYPE (expr)))
return get_target_expr_sfinae (expr, complain);
+ /* In decltype, we might have decided not to wrap this call in a TARGET_EXPR.
+ But it turns out to be a subexpression, so perform temporary
+ materialization now. */
+ if (TREE_CODE (expr) == CALL_EXPR
+ && CLASS_TYPE_P (type)
+ && same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (expr)))
+ expr = build_cplus_new (type, expr, complain);
+
savew = warningcount + werrorcount, savee = errorcount;
releasing_vec args (make_tree_vector_single (expr));
expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,