* cp-tree.h (rvalue): New function.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 6 Sep 2005 14:55:06 +0000 (14:55 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 6 Sep 2005 14:55:06 +0000 (14:55 +0000)
* call.c (build_conditional_expr): Use it.
* init.c (build_new_1): Likewise.
* rtti.c (build_dynamic_cast_1): Likewise.
* tree.c (rvalue): New function.
* typeck.c (build_unary_op): Use it.
(build_static_cast_1): Likewise.

* g++.dg/expr/cast6.C: New test.

PR c++/9782
* init.c (build_new_1): Make sure the entire array type is
complete, not just its element types.

PR c++/9782
* g++.dg/init/new15.C: New test.

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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/init.c
gcc/cp/rtti.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/expr/cast6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/init/new15.C [new file with mode: 0644]

index 4c200d7..50ce226 100644 (file)
@@ -1,3 +1,17 @@
+2005-09-06  Mark Mitchell  <mark@codesourcery.com>
+
+       * cp-tree.h (rvalue): New function.
+       * call.c (build_conditional_expr): Use it.
+       * init.c (build_new_1): Likewise.
+       * rtti.c (build_dynamic_cast_1): Likewise.
+       * tree.c (rvalue): New function.
+       * typeck.c (build_unary_op): Use it.
+       (build_static_cast_1): Likewise.
+
+       PR c++/9782
+       * init.c (build_new_1): Make sure the entire array type is
+       complete, not just its element types.
+
 2005-09-06  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
        * decl.c (check_elaborated_type_specifier): Remove redundant check.
index 9f277cd..fab01fc 100644 (file)
@@ -3486,7 +3486,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
   /* If this expression is an rvalue, but might be mistaken for an
      lvalue, we must add a NON_LVALUE_EXPR.  */
   if (!lvalue_p && real_lvalue_p (result))
-    result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result);
+    result = rvalue (result);
 
   return result;
 }
index 4d5d618..2803f51 100644 (file)
@@ -4263,7 +4263,8 @@ extern int cp_cannot_inline_tree_fn               (tree*);
 extern tree cp_add_pending_fn_decls            (void*,tree);
 extern int cp_auto_var_in_fn_p                 (tree,tree);
 extern tree fold_if_not_in_template            (tree);
-
+extern tree rvalue                              (tree);
+   
 /* in typeck.c */
 extern int string_conv_p                       (tree, tree, int);
 extern tree cp_truthvalue_conversion           (tree);
index 8a8dc78..50b0bca 100644 (file)
@@ -1838,6 +1838,9 @@ build_new_1 (tree exp)
        }
     }
 
+  if (!complete_type_or_else (type, exp))
+    return error_mark_node;
+
   /* If our base type is an array, then make sure we know how many elements
      it has.  */
   for (elt_type = type;
@@ -1846,9 +1849,6 @@ build_new_1 (tree exp)
     nelts = cp_build_binary_op (MULT_EXPR, nelts,
                                array_type_nelts_top (elt_type));
 
-  if (!complete_type_or_else (elt_type, exp))
-    return error_mark_node;
-
   if (TREE_CODE (elt_type) == VOID_TYPE)
     {
       error ("invalid type %<void%> for new");
@@ -2227,8 +2227,7 @@ build_new_1 (tree exp)
   rval = build_nop (pointer_type, rval);
 
   /* A new-expression is never an lvalue.  */
-  if (real_lvalue_p (rval))
-    rval = build1 (NON_LVALUE_EXPR, TREE_TYPE (rval), rval);
+  rval = rvalue (rval);
 
   return rval;
 }
index e006938..6d60d4c 100644 (file)
@@ -555,7 +555,7 @@ build_dynamic_cast_1 (tree type, tree expr)
        expr = build_base_path (PLUS_EXPR, convert_from_reference (expr),
                                binfo, 0);
        if (TREE_CODE (exprtype) == POINTER_TYPE)
-         expr = non_lvalue (expr);
+         expr = rvalue (expr);
        return expr;
       }
   }
index ddc0b51..9c28f13 100644 (file)
@@ -365,6 +365,26 @@ get_target_expr (tree init)
   return build_target_expr_with_type (init, TREE_TYPE (init));
 }
 
+/* EXPR is being used in an rvalue context.  Return a version of EXPR
+   that is marked as an rvalue.  */
+
+tree
+rvalue (tree expr)
+{
+  tree type;
+  if (real_lvalue_p (expr))
+    {
+      type = TREE_TYPE (expr);
+      /* [basic.lval]
+        
+         Non-class rvalues always have cv-unqualified types.  */
+      if (!CLASS_TYPE_P (type))
+       type = TYPE_MAIN_VARIANT (type);
+      expr = build1 (NON_LVALUE_EXPR, type, expr);
+    }
+  return expr;
+}
+
 \f
 static tree
 build_cplus_array_type_1 (tree elt_type, tree index_type)
index d8dce75..67f631a 100644 (file)
@@ -3768,8 +3768,7 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
 
            /* Make sure the result is not an lvalue: a unary plus or minus
               expression is always a rvalue.  */
-           if (real_lvalue_p (arg))
-             arg = build1 (NON_LVALUE_EXPR, TREE_TYPE (arg), arg);
+           arg = rvalue (arg);
          }
       }
       break;
@@ -4016,9 +4015,9 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
              tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
              arg = build1 (CONVERT_EXPR, type, arg);
            }
-         else if (lvalue_p (arg))
+         else
            /* Don't let this be an lvalue.  */
-           return non_lvalue (arg);
+           arg = rvalue (arg);
          return arg;
        }
 
@@ -4666,9 +4665,8 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
 
         If T is a reference type, the result is an lvalue; otherwise,
         the result is an rvalue.  */
-      if (TREE_CODE (type) != REFERENCE_TYPE
-         && real_lvalue_p (result))
-       result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result);
+      if (TREE_CODE (type) != REFERENCE_TYPE)
+       result = rvalue (result);
       return result;
     }
 
index 2d8c0ff..87af08c 100644 (file)
@@ -1,3 +1,10 @@
+2005-09-06  Mark Mitchell  <mark@codesourcery.com>
+
+       * g++.dg/expr/cast6.C: New test.
+
+       PR c++/9782
+       * g++.dg/init/new15.C: New test.
+
 2005-09-06  Keith Besaw  <kbesaw@us.ibm.com>
 
        * gcc.dg/vect/Os-vect-95.c: New test.
diff --git a/gcc/testsuite/g++.dg/expr/cast6.C b/gcc/testsuite/g++.dg/expr/cast6.C
new file mode 100644 (file)
index 0000000..434a046
--- /dev/null
@@ -0,0 +1,6 @@
+void f(int &);
+void f(const int &);
+int main() {
+  volatile int x = 2;
+  f((int)x);
+}
diff --git a/gcc/testsuite/g++.dg/init/new15.C b/gcc/testsuite/g++.dg/init/new15.C
new file mode 100644 (file)
index 0000000..17cf8a8
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/9782
+
+extern "C" void printf(char *, ...);
+
+template <int>
+struct A {
+  A() {printf("A::A()\n");}
+};
+
+
+struct B {
+  B() {printf("B::B()\n");}
+};
+
+
+int main () {
+  new A<0>[1][1];
+  new B   [1][1];
+}