OSDN Git Service

* cp-tree.h (enum cp_lvalue_kind_flags): Add clk_rvalueref.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 12 Jul 2009 19:19:15 +0000 (19:19 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 12 Jul 2009 19:19:15 +0000 (19:19 +0000)
* tree.c (lvalue_p_1): Return it.  Remove
treat_class_rvalues_as_lvalues parm.
(real_lvalue_p): Disallow pseudo-lvalues here.
(lvalue_or_rvalue_with_address_p): New fn.
* call.c (initialize_reference): Use it instead of real_lvalue_p.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149534 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/rv10.C [new file with mode: 0644]

index cff424f..d3fceab 100644 (file)
@@ -1,5 +1,13 @@
 2009-07-12  Jason Merrill  <jason@redhat.com>
 
+       PR c++/37206
+       * cp-tree.h (enum cp_lvalue_kind_flags): Add clk_rvalueref.
+       * tree.c (lvalue_p_1): Return it.  Remove
+       treat_class_rvalues_as_lvalues parm.
+       (real_lvalue_p): Disallow pseudo-lvalues here.
+       (lvalue_or_rvalue_with_address_p): New fn.
+       * call.c (initialize_reference): Use it instead of real_lvalue_p.
+
        PR c++/40689
        * init.c (build_new_1): Handle initializer list as array initializer.
        (build_vec_init): Likewise.
index f0d624e..5edeb3a 100644 (file)
@@ -7622,7 +7622,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
        expr = error_mark_node;
       else
        {
-         if (!real_lvalue_p (expr))
+         if (!lvalue_or_rvalue_with_address_p (expr))
            {
              tree init;
              var = set_up_extended_ref_temp (decl, expr, cleanup, &init);
index 24351b4..933da19 100644 (file)
@@ -3509,9 +3509,10 @@ enum tag_types {
 enum cp_lvalue_kind_flags {
   clk_none = 0,     /* Things that are not an lvalue.  */
   clk_ordinary = 1, /* An ordinary lvalue.  */
-  clk_class = 2,    /* An rvalue of class-type.  */
-  clk_bitfield = 4, /* An lvalue for a bit-field.  */
-  clk_packed = 8    /* An lvalue for a packed field.  */
+  clk_rvalueref = 2,/* An rvalue formed using an rvalue reference */
+  clk_class = 4,    /* An rvalue of class-type.  */
+  clk_bitfield = 8, /* An lvalue for a bit-field.  */
+  clk_packed = 16   /* An lvalue for a packed field.  */
 };
 
 /* This type is used for parameters and variables which hold
@@ -4884,6 +4885,7 @@ extern tree copy_binfo                            (tree, tree, tree,
                                                 tree *, int);
 extern int member_p                            (const_tree);
 extern cp_lvalue_kind real_lvalue_p            (tree);
+extern bool lvalue_or_rvalue_with_address_p    (const_tree);
 extern bool builtin_valid_in_constant_expr_p    (const_tree);
 extern tree build_min                          (enum tree_code, tree, ...);
 extern tree build_min_nt                       (enum tree_code, ...);
index 644e53c..6981388 100644 (file)
@@ -44,7 +44,7 @@ static tree build_cplus_array_type_1 (tree, tree);
 static int list_hash_eq (const void *, const void *);
 static hashval_t list_hash_pieces (tree, tree, tree);
 static hashval_t list_hash (const void *);
-static cp_lvalue_kind lvalue_p_1 (const_tree, int);
+static cp_lvalue_kind lvalue_p_1 (const_tree);
 static tree build_target_expr (tree, tree);
 static tree count_trees_r (tree *, int *, void *);
 static tree verify_stmt_tree_r (tree *, int *, void *);
@@ -55,12 +55,10 @@ static tree handle_com_interface_attribute (tree *, tree, tree, int, bool *);
 static tree handle_init_priority_attribute (tree *, tree, tree, int, bool *);
 
 /* If REF is an lvalue, returns the kind of lvalue that REF is.
-   Otherwise, returns clk_none.  If TREAT_CLASS_RVALUES_AS_LVALUES is
-   nonzero, rvalues of class type are considered lvalues.  */
+   Otherwise, returns clk_none.  */
 
 static cp_lvalue_kind
-lvalue_p_1 (const_tree ref,
-           int treat_class_rvalues_as_lvalues)
+lvalue_p_1 (const_tree ref)
 {
   cp_lvalue_kind op1_lvalue_kind = clk_none;
   cp_lvalue_kind op2_lvalue_kind = clk_none;
@@ -72,8 +70,7 @@ lvalue_p_1 (const_tree ref,
   if (TREE_CODE (ref) == INDIRECT_REF
       && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0)))
          == REFERENCE_TYPE)
-    return lvalue_p_1 (TREE_OPERAND (ref, 0),
-                       treat_class_rvalues_as_lvalues);
+    return lvalue_p_1 (TREE_OPERAND (ref, 0));
 
   if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
     {
@@ -82,12 +79,7 @@ lvalue_p_1 (const_tree ref,
          && TREE_CODE (ref) != PARM_DECL
          && TREE_CODE (ref) != VAR_DECL
          && TREE_CODE (ref) != COMPONENT_REF)
-       {
-         if (CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (ref))))
-           return treat_class_rvalues_as_lvalues ? clk_class : clk_none;
-         else
-           return clk_none;
-       }
+       return clk_rvalueref;
 
       /* lvalue references and named rvalue references are lvalues.  */
       return clk_ordinary;
@@ -108,12 +100,10 @@ lvalue_p_1 (const_tree ref,
     case WITH_CLEANUP_EXPR:
     case REALPART_EXPR:
     case IMAGPART_EXPR:
-      return lvalue_p_1 (TREE_OPERAND (ref, 0),
-                        treat_class_rvalues_as_lvalues);
+      return lvalue_p_1 (TREE_OPERAND (ref, 0));
 
     case COMPONENT_REF:
-      op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
-                                   treat_class_rvalues_as_lvalues);
+      op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0));
       /* Look at the member designator.  */
       if (!op1_lvalue_kind)
        ;
@@ -164,35 +154,28 @@ lvalue_p_1 (const_tree ref,
       if (TREE_SIDE_EFFECTS (TREE_OPERAND (ref, 0))
          || TREE_SIDE_EFFECTS (TREE_OPERAND (ref, 1)))
        return clk_none;
-      op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
-                                   treat_class_rvalues_as_lvalues);
-      op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
-                                   treat_class_rvalues_as_lvalues);
+      op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0));
+      op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1));
       break;
 
     case COND_EXPR:
       op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1)
                                    ? TREE_OPERAND (ref, 1)
-                                   : TREE_OPERAND (ref, 0),
-                                   treat_class_rvalues_as_lvalues);
-      op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 2),
-                                   treat_class_rvalues_as_lvalues);
+                                   : TREE_OPERAND (ref, 0));
+      op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 2));
       break;
 
     case MODIFY_EXPR:
       return clk_ordinary;
 
     case COMPOUND_EXPR:
-      return lvalue_p_1 (TREE_OPERAND (ref, 1),
-                        treat_class_rvalues_as_lvalues);
+      return lvalue_p_1 (TREE_OPERAND (ref, 1));
 
     case TARGET_EXPR:
-      return treat_class_rvalues_as_lvalues ? clk_class : clk_none;
+      return clk_class;
 
     case VA_ARG_EXPR:
-      return (treat_class_rvalues_as_lvalues
-             && CLASS_TYPE_P (TREE_TYPE (ref))
-             ? clk_class : clk_none);
+      return (CLASS_TYPE_P (TREE_TYPE (ref)) ? clk_class : clk_none);
 
     case CALL_EXPR:
       /* Any class-valued call would be wrapped in a TARGET_EXPR.  */
@@ -209,8 +192,7 @@ lvalue_p_1 (const_tree ref,
         with a BASELINK.  */
       /* This CONST_CAST is okay because BASELINK_FUNCTIONS returns
         its argument unmodified and we assign it to a const_tree.  */
-      return lvalue_p_1 (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref)),
-                        treat_class_rvalues_as_lvalues);
+      return lvalue_p_1 (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref)));
 
     case NON_DEPENDENT_EXPR:
       /* We must consider NON_DEPENDENT_EXPRs to be lvalues so that
@@ -246,18 +228,33 @@ lvalue_p_1 (const_tree ref,
 cp_lvalue_kind
 real_lvalue_p (tree ref)
 {
-  return lvalue_p_1 (ref,
-                    /*treat_class_rvalues_as_lvalues=*/0);
+  cp_lvalue_kind kind = lvalue_p_1 (ref);
+  if (kind & (clk_rvalueref|clk_class))
+    return clk_none;
+  else
+    return kind;
 }
 
-/* This differs from real_lvalue_p in that class rvalues are
-   considered lvalues.  */
+/* This differs from real_lvalue_p in that class rvalues are considered
+   lvalues.  */
 
 bool
 lvalue_p (const_tree ref)
 {
-  return
-    (lvalue_p_1 (ref, /*class rvalue ok*/ 1) != clk_none);
+  return (lvalue_p_1 (ref) != clk_none);
+}
+
+/* This differs from real_lvalue_p in that rvalues formed by dereferencing
+   rvalue references are considered rvalues.  */
+
+bool
+lvalue_or_rvalue_with_address_p (const_tree ref)
+{
+  cp_lvalue_kind kind = lvalue_p_1 (ref);
+  if (kind & clk_class)
+    return false;
+  else
+    return (kind != clk_none);
 }
 
 /* Test whether DECL is a builtin that may appear in a
index a12a5d2..7fdbcf4 100644 (file)
@@ -1,5 +1,10 @@
 2009-07-12  Jason Merrill  <jason@redhat.com>
 
+       PR c++/37206
+       * g++.dg/cpp0x/rv10.C: New.
+
+2009-07-12  Jason Merrill  <jason@redhat.com>
+
        PR c++/40689
        * g++.dg/cpp0x/initlist20.C: New.
        * g++.dg/cpp0x/initlist21.C: New.
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv10.C b/gcc/testsuite/g++.dg/cpp0x/rv10.C
new file mode 100644 (file)
index 0000000..5e78b1d
--- /dev/null
@@ -0,0 +1,15 @@
+// { dg-options "-std=gnu++0x" }
+
+struct A
+{
+  A() = default;
+  A(const A&) = delete;
+};
+
+A&& f();
+void h(A&&);
+void g()
+{
+  A&& arr = f();
+  h(f());
+}