* tree.c (lvalue_kind): Rename from lvalue_p_1, make nonstatic.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 28 Sep 2010 21:20:32 +0000 (21:20 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 28 Sep 2010 21:20:32 +0000 (21:20 +0000)
(real_lvalue_p): Take const_tree.
* cp-tree.h: Adjust.
* typeck.c (lvalue_or_else): Make temporary arg a permerror.
(cp_build_addr_expr_1): Likewise.

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

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/rv-lvalue-req.C
gcc/testsuite/g++.dg/ext/complit11.C
gcc/testsuite/g++.old-deja/g++.law/temps1.C

index 1776ee6..175bc98 100644 (file)
@@ -1,3 +1,11 @@
+2010-09-28  Jason Merrill  <jason@redhat.com>
+
+       * tree.c (lvalue_kind): Rename from lvalue_p_1, make nonstatic.
+       (real_lvalue_p): Take const_tree.
+       * cp-tree.h: Adjust.
+       * typeck.c (lvalue_or_else): Make temporary arg a permerror.
+       (cp_build_addr_expr_1): Likewise.
+
 2010-09-28  Iain Sandoe  <iains@gcc.gnu.org>
        
        Partially merged from apple/trunk branch on FSF servers:
index 2ff0973..7e671a8 100644 (file)
@@ -5345,7 +5345,8 @@ extern void cp_set_underlying_type                (tree);
 extern tree copy_binfo                         (tree, tree, tree,
                                                 tree *, int);
 extern int member_p                            (const_tree);
-extern cp_lvalue_kind real_lvalue_p            (tree);
+extern cp_lvalue_kind real_lvalue_p            (const_tree);
+extern cp_lvalue_kind lvalue_kind              (const_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, ...);
index d52387b..ddfb354 100644 (file)
@@ -40,7 +40,6 @@ static tree bot_replace (tree *, int *, void *);
 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);
 static tree build_target_expr (tree, tree);
 static tree count_trees_r (tree *, int *, void *);
 static tree verify_stmt_tree_r (tree *, int *, void *);
@@ -53,8 +52,8 @@ 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.  */
 
-static cp_lvalue_kind
-lvalue_p_1 (const_tree ref)
+cp_lvalue_kind
+lvalue_kind (const_tree ref)
 {
   cp_lvalue_kind op1_lvalue_kind = clk_none;
   cp_lvalue_kind op2_lvalue_kind = clk_none;
@@ -66,7 +65,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));
+    return lvalue_kind (TREE_OPERAND (ref, 0));
 
   if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
     {
@@ -96,10 +95,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));
+      return lvalue_kind (TREE_OPERAND (ref, 0));
 
     case COMPONENT_REF:
-      op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0));
+      op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
       /* Look at the member designator.  */
       if (!op1_lvalue_kind)
        ;
@@ -156,22 +155,22 @@ 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));
-      op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1));
+      op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
+      op2_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 1));
       break;
 
     case COND_EXPR:
-      op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1)
+      op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 1)
                                    ? TREE_OPERAND (ref, 1)
                                    : TREE_OPERAND (ref, 0));
-      op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 2));
+      op2_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 2));
       break;
 
     case MODIFY_EXPR:
       return clk_ordinary;
 
     case COMPOUND_EXPR:
-      return lvalue_p_1 (TREE_OPERAND (ref, 1));
+      return lvalue_kind (TREE_OPERAND (ref, 1));
 
     case TARGET_EXPR:
       return clk_class;
@@ -194,7 +193,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)));
+      return lvalue_kind (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref)));
 
     case NON_DEPENDENT_EXPR:
       /* We must consider NON_DEPENDENT_EXPRs to be lvalues so that
@@ -232,9 +231,9 @@ lvalue_p_1 (const_tree ref)
    computes the C++ definition of lvalue.  */
 
 cp_lvalue_kind
-real_lvalue_p (tree ref)
+real_lvalue_p (const_tree ref)
 {
-  cp_lvalue_kind kind = lvalue_p_1 (ref);
+  cp_lvalue_kind kind = lvalue_kind (ref);
   if (kind & (clk_rvalueref|clk_class))
     return clk_none;
   else
@@ -247,7 +246,7 @@ real_lvalue_p (tree ref)
 bool
 lvalue_p (const_tree ref)
 {
-  return (lvalue_p_1 (ref) != clk_none);
+  return (lvalue_kind (ref) != clk_none);
 }
 
 /* This differs from real_lvalue_p in that rvalues formed by dereferencing
@@ -256,7 +255,7 @@ lvalue_p (const_tree ref)
 bool
 lvalue_or_rvalue_with_address_p (const_tree ref)
 {
-  cp_lvalue_kind kind = lvalue_p_1 (ref);
+  cp_lvalue_kind kind = lvalue_kind (ref);
   if (kind & clk_class)
     return false;
   else
index c25a177..eff6704 100644 (file)
@@ -4878,13 +4878,23 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
   if (TREE_CODE (argtype) != FUNCTION_TYPE
       && TREE_CODE (argtype) != METHOD_TYPE)
     {
-      bool win = strict_lvalue ? real_lvalue_p (arg) : lvalue_p (arg);
-      if (!win)
+      cp_lvalue_kind kind = lvalue_kind (arg);
+      if (kind == clk_none)
        {
          if (complain & tf_error)
            lvalue_error (lv_addressof);
          return error_mark_node;
        }
+      if (strict_lvalue && (kind & (clk_rvalueref|clk_class)))
+       {
+         if (!(complain & tf_error))
+           return error_mark_node;
+         if (kind & clk_class)
+           /* Make this a permerror because we used to accept it.  */
+           permerror (input_location, "taking address of temporary");
+         else
+           error ("taking address of xvalue (rvalue reference)");
+       }
     }
 
   if (TREE_CODE (argtype) == REFERENCE_TYPE)
@@ -8361,11 +8371,24 @@ non_reference (tree t)
 int
 lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain)
 {
-  int win = real_lvalue_p (ref);
-
-  if (!win && (complain & tf_error))
-    lvalue_error (use);
+  cp_lvalue_kind kind = lvalue_kind (ref);
 
-  return win;
+  if (kind == clk_none)
+    {
+      if (complain & tf_error)
+       lvalue_error (use);
+      return 0;
+    }
+  else if (kind & (clk_rvalueref|clk_class))
+    {
+      if (!(complain & tf_error))
+       return 0;
+      if (kind & clk_class)
+       /* Make this a permerror because we used to accept it.  */
+       permerror (input_location, "using temporary as lvalue");
+      else
+       error ("using xvalue (rvalue reference) as lvalue");
+    }
+  return 1;
 }
 
index 1b1ec7f..18f9f96 100644 (file)
@@ -1,5 +1,9 @@
 2010-09-28  Jason Merrill  <jason@redhat.com>
 
+       * g++.dg/cpp0x/rv-lvalue-req.C: Adjust messages.
+       * g++.dg/ext/complit11.C: Likewise.
+       * g++.old-deja/g++.law/temps1.C: Likewise.
+
        * g++.old-deja/g++.bugs/900121_02.C: Adjust for C++0x mode.
        * g++.old-deja/g++.mike/misc6.C: Likewise.
 
index ba1c306..a8f424d 100644 (file)
@@ -4,9 +4,9 @@ template <class T> T&& declval();
 
 int main()
 {
-  &declval<int>();                     // { dg-error "lvalue" }
-  declval<int>() = declval<int>();     // { dg-error "lvalue" }
-  declval<int>()++;                    // { dg-error "lvalue" }
-  --declval<int>();                    // { dg-error "lvalue" }
-  declval<int>() += 1;                 // { dg-error "lvalue" }
+  &declval<int>();                     // { dg-error "xvalue" }
+  declval<int>() = declval<int>();     // { dg-error "xvalue" }
+  declval<int>()++;                    // { dg-error "xvalue" }
+  --declval<int>();                    // { dg-error "xvalue" }
+  declval<int>() += 1;                 // { dg-error "xvalue" }
 }
index 2cff6cd..0662543 100644 (file)
@@ -6,7 +6,7 @@ struct A { int i; };
 template<int t>
 void foo()
 {
-    ((struct A) { 0 }).i += 1; // { dg-error "lvalue required" }
+    ((struct A) { 0 }).i += 1; // { dg-error "temporary" }
 }
 
 void g(void)
index 2e6a419..bd344b4 100644 (file)
@@ -3,6 +3,7 @@
 // temps file
 // Date: Mon, 07 Sep 1992 13:12:28 EDT
 // From: richard@ttt.kth.se 
+// { dg-options "-fpermissive" }
 struct foo
 {
   char *s;
@@ -16,4 +17,4 @@ struct cookie
 };
 
 cookie cat(&foo("apabepa"));// { dg-warning "deprecated conversion" "dep" }
-// { dg-error "lvalue required" "lvalue" { target *-*-* } 18 }
+// { dg-warning "taking address of temporary" "add" { target *-*-* } 19 }