aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2021-05-05 22:25:45 -0400
committerJason Merrill <jason@redhat.com>2021-05-07 12:09:38 -0400
commitfc178519771db508c03611cff4a1466cf67fce1d (patch)
treef89f6573fcc112ba773d574c5b9fe38a0f767e1a /gcc
parent14ed21f8749ae359690d9c4a69ca38cc45d0d1b0 (diff)
downloadgcc-fc178519771db508c03611cff4a1466cf67fce1d.zip
gcc-fc178519771db508c03611cff4a1466cf67fce1d.tar.gz
gcc-fc178519771db508c03611cff4a1466cf67fce1d.tar.bz2
c++: avoid non-TARGET_EXPR class prvalues
Around PR98469 I asked Jakub to wrap a class BIT_CAST_EXPR in TARGET_EXPR; SPACESHIP_EXPR needs the same thing. The dummy CAST_EXPR created in can_convert is another instance of a non-TARGET_EXPR prvalue, so let's use the declval-like build_stub_object there instead. gcc/cp/ChangeLog: * cp-tree.h (build_stub_object): Declare. * method.c (build_stub_object): No longer static. * call.c (can_convert): Use it. * tree.c (build_dummy_object): Adjust comment. * typeck.c (cp_build_binary_op): Wrap SPACESHIP_EXPR in a TARGET_EXPR.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/call.c2
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/method.c2
-rw-r--r--gcc/cp/tree.c3
-rw-r--r--gcc/cp/typeck.c2
5 files changed, 7 insertions, 3 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 57bac05..d985e4e 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -12177,7 +12177,7 @@ can_convert (tree to, tree from, tsubst_flags_t complain)
/* implicit_conversion only considers user-defined conversions
if it has an expression for the call argument list. */
if (CLASS_TYPE_P (from) || CLASS_TYPE_P (to))
- arg = build1 (CAST_EXPR, from, NULL_TREE);
+ arg = build_stub_object (from);
return can_convert_arg (to, from, arg, LOOKUP_IMPLICIT, complain);
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a08867a..122dadf 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6968,6 +6968,7 @@ extern tree get_copy_ctor (tree, tsubst_flags_t);
extern tree get_copy_assign (tree);
extern tree get_default_ctor (tree);
extern tree get_dtor (tree, tsubst_flags_t);
+extern tree build_stub_object (tree);
extern tree strip_inheriting_ctors (tree);
extern tree inherited_ctor_binfo (tree);
extern bool base_ctor_omit_inherited_parms (tree);
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 0f416be..f8c9456 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1793,7 +1793,7 @@ build_stub_type (tree type, int quals, bool rvalue)
/* Build a dummy glvalue from dereferencing a dummy reference of type
REFTYPE. */
-static tree
+tree
build_stub_object (tree reftype)
{
if (!TYPE_REF_P (reftype))
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 3a20cd3..4ccd7a3 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -4175,7 +4175,8 @@ member_p (const_tree decl)
}
/* Create a placeholder for member access where we don't actually have an
- object that the access is against. */
+ object that the access is against. For a general declval<T> equivalent,
+ use build_stub_object instead. */
tree
build_dummy_object (tree type)
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 50d0f1e..5af47ce 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -5931,6 +5931,8 @@ cp_build_binary_op (const op_location_t &location,
if (!processing_template_decl)
{
+ if (resultcode == SPACESHIP_EXPR)
+ result = get_target_expr_sfinae (result, complain);
op0 = cp_fully_fold (op0);
/* Only consider the second argument if the first isn't overflowed. */
if (!CONSTANT_CLASS_P (op0) || TREE_OVERFLOW_P (op0))