From: Jason Merrill Date: Thu, 6 May 2021 02:25:45 +0000 (-0400) Subject: c++: avoid non-TARGET_EXPR class prvalues X-Git-Tag: basepoints/gcc-13~7694 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fc178519771db508c03611cff4a1466cf67fce1d;p=thirdparty%2Fgcc.git 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. --- diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 57bac05fe70b..d985e4e8eda9 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 a08867aea628..122dadf976fd 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 0f416bec35b5..f8c9456d7204 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 3a20cd33fdc2..4ccd7a314f52 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 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 50d0f1e6a62a..5af47ce89a94 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))