[pushed] c++: avoid non-TARGET_EXPR class prvalues

Message ID 20210507160927.4125630-1-jason@redhat.com
State New
Headers show
Series
  • [pushed] c++: avoid non-TARGET_EXPR class prvalues
Related show

Commit Message

Marek Polacek via Gcc-patches May 7, 2021, 4:09 p.m.
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.

Tested x86_64-pc-linux-gnu, applying to trunk.

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.
---
 gcc/cp/cp-tree.h | 1 +
 gcc/cp/call.c    | 2 +-
 gcc/cp/method.c  | 2 +-
 gcc/cp/tree.c    | 3 ++-
 gcc/cp/typeck.c  | 2 ++
 5 files changed, 7 insertions(+), 3 deletions(-)


base-commit: 14ed21f8749ae359690d9c4a69ca38cc45d0d1b0
prerequisite-patch-id: bc368a9ce91fa5c1dcacbcaa3feb2c608a13570a
-- 
2.27.0

Patch

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a08867aea62..122dadf976f 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/call.c b/gcc/cp/call.c
index 8e455e59909..d2908b3b0cd 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -12175,7 +12175,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/method.c b/gcc/cp/method.c
index 0f416bec35b..f8c9456d720 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 3a20cd33fdc..4ccd7a314f5 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 50d0f1e6a62..5af47ce89a9 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))