OSDN Git Service

* call.c (reference_binding): Rename lvalue_p to is_lvalue.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 1 Aug 2009 02:26:21 +0000 (02:26 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 1 Aug 2009 02:26:21 +0000 (02:26 +0000)
Do direct binding of "rvalues" in memory to rvalue references.
* tree.c (lvalue_p_1): Can't be both non-addressable lvalue and
"rvalue" in memory.
* typeck.c (build_static_cast_1): Do direct binding of memory
"rvalues" to rvalue references.
* cvt.c (cp_fold_convert): New.
* cp-tree.h: Declare it.

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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/tree.c
gcc/cp/typeck.c

index 1f57251..9a9de74 100644 (file)
@@ -1,5 +1,16 @@
 2009-07-31  Jason Merrill  <jason@redhat.com>
 
+       * call.c (reference_binding): Rename lvalue_p to is_lvalue.
+       Do direct binding of "rvalues" in memory to rvalue references.
+       * tree.c (lvalue_p_1): Can't be both non-addressable lvalue and
+       "rvalue" in memory.
+       * typeck.c (build_static_cast_1): Do direct binding of memory
+       "rvalues" to rvalue references.
+       * cvt.c (cp_fold_convert): New.
+       * cp-tree.h: Declare it.
+
+2009-07-31  Jason Merrill  <jason@redhat.com>
+
        * typeck.c (build_address): Do fold away ADDR_EXPR of INDIRECT_REF.
        * tree.c (rvalue): Use cp_build_qualified_type, not TYPE_MAIN_VARIANT.
 
index 0254ecb..144d07e 100644 (file)
@@ -1205,7 +1205,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
   tree tfrom;
   bool related_p;
   bool compatible_p;
-  cp_lvalue_kind lvalue_p = clk_none;
+  cp_lvalue_kind is_lvalue = clk_none;
 
   if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr))
     {
@@ -1218,7 +1218,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
   if (TREE_CODE (from) == REFERENCE_TYPE)
     {
       /* Anything with reference type is an lvalue.  */
-      lvalue_p = clk_ordinary;
+      is_lvalue = clk_ordinary;
       from = TREE_TYPE (from);
     }
 
@@ -1235,11 +1235,11 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
        }
     }
 
-  if (lvalue_p == clk_none && expr)
-    lvalue_p = real_lvalue_p (expr);
+  if (is_lvalue == clk_none && expr)
+    is_lvalue = real_lvalue_p (expr);
 
   tfrom = from;
-  if ((lvalue_p & clk_bitfield) != 0)
+  if ((is_lvalue & clk_bitfield) != 0)
     tfrom = unlowered_expr_type (expr);
 
   /* Figure out whether or not the types are reference-related and
@@ -1256,12 +1256,15 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
   /* Directly bind reference when target expression's type is compatible with
      the reference and expression is an lvalue. In DR391, the wording in
      [8.5.3/5 dcl.init.ref] is changed to also require direct bindings for
-     const and rvalue references to rvalues of compatible class type. */
+     const and rvalue references to rvalues of compatible class type.
+     We should also do direct bindings for non-class "rvalues" derived from
+     rvalue references.  */
   if (compatible_p
-      && (lvalue_p
-         || (!(flags & LOOKUP_NO_TEMP_BIND)
-             && (CP_TYPE_CONST_NON_VOLATILE_P(to) || TYPE_REF_IS_RVALUE (rto))
-             && CLASS_TYPE_P (from))))
+      && (is_lvalue
+         || (((CP_TYPE_CONST_NON_VOLATILE_P (to)
+               && !(flags & LOOKUP_NO_TEMP_BIND))
+              || TYPE_REF_IS_RVALUE (rto))
+             && (CLASS_TYPE_P (from) || (expr && lvalue_p (expr))))))
     {
       /* [dcl.init.ref]
 
@@ -1288,10 +1291,10 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
        conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto);
       else
        conv->rvaluedness_matches_p 
-          = (TYPE_REF_IS_RVALUE (rto) == !lvalue_p);
+          = (TYPE_REF_IS_RVALUE (rto) == !is_lvalue);
 
-      if ((lvalue_p & clk_bitfield) != 0
-         || ((lvalue_p & clk_packed) != 0 && !TYPE_PACKED (to)))
+      if ((is_lvalue & clk_bitfield) != 0
+         || ((is_lvalue & clk_packed) != 0 && !TYPE_PACKED (to)))
        /* For the purposes of overload resolution, we ignore the fact
           this expression is a bitfield or packed field. (In particular,
           [over.ics.ref] says specifically that a function with a
index dcad934..07e89d3 100644 (file)
@@ -4339,6 +4339,7 @@ extern tree force_rvalue                  (tree);
 extern tree ocp_convert                                (tree, tree, int, int);
 extern tree cp_convert                         (tree, tree);
 extern tree cp_convert_and_check                (tree, tree);
+extern tree cp_fold_convert                    (tree, tree);
 extern tree convert_to_void    (tree, const char */*implicit context*/,
                                  tsubst_flags_t);
 extern tree convert_force                      (tree, tree, int);
index c42d21c..cdc6a10 100644 (file)
@@ -539,7 +539,16 @@ force_rvalue (tree expr)
 
   return expr;
 }
+
 \f
+/* Fold away simple conversions, but make sure the result is an rvalue.  */
+
+tree
+cp_fold_convert (tree type, tree expr)
+{
+  return rvalue (fold_convert (type, expr));
+}
+
 /* C++ conversions, preference to static cast conversions.  */
 
 tree
index cbadf04..9e194fc 100644 (file)
@@ -214,10 +214,14 @@ lvalue_p_1 (const_tree ref)
   /* Otherwise, it's an lvalue, and it has all the odd properties
      contributed by either operand.  */
   op1_lvalue_kind = op1_lvalue_kind | op2_lvalue_kind;
-  /* It's not an ordinary lvalue if it involves either a bit-field or
-     a class rvalue.  */
+  /* It's not an ordinary lvalue if it involves any other kind.  */
   if ((op1_lvalue_kind & ~clk_ordinary) != clk_none)
     op1_lvalue_kind &= ~clk_ordinary;
+  /* It can't be both a pseudo-lvalue and a non-addressable lvalue.
+     A COND_EXPR of those should be wrapped in a TARGET_EXPR.  */
+  if ((op1_lvalue_kind & (clk_rvalueref|clk_class))
+      && (op1_lvalue_kind & (clk_bitfield|clk_packed)))
+    op1_lvalue_kind = clk_none;
   return op1_lvalue_kind;
 }
 
index 35c82d6..a956fdc 100644 (file)
@@ -5284,7 +5284,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
   if (TREE_CODE (type) == REFERENCE_TYPE
       && CLASS_TYPE_P (TREE_TYPE (type))
       && CLASS_TYPE_P (intype)
-      && real_lvalue_p (expr)
+      && (TYPE_REF_IS_RVALUE (type) || real_lvalue_p (expr))
       && DERIVED_FROM_P (intype, TREE_TYPE (type))
       && can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)),
                      build_pointer_type (TYPE_MAIN_VARIANT
@@ -5310,7 +5310,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
                              base, /*nonnull=*/false);
       /* Convert the pointer to a reference -- but then remember that
         there are no expressions with reference type in C++.  */
-      return convert_from_reference (build_nop (type, expr));
+      return convert_from_reference (cp_fold_convert (type, expr));
     }
 
   orig = expr;