aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog14
-rw-r--r--gcc/cp/call.c2
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/init.c9
-rw-r--r--gcc/cp/rtti.c2
-rw-r--r--gcc/cp/tree.c20
-rw-r--r--gcc/cp/typeck.c12
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/expr/cast6.C6
-rw-r--r--gcc/testsuite/g++.dg/init/new15.C19
10 files changed, 79 insertions, 15 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4c200d7..50ce226 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 9f277cd..fab01fc 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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;
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4d5d618..2803f51 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 8a8dc78..50b0bca 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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;
}
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index e006938..6d60d4c 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -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;
}
}
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index ddc0b51..9c28f13 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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;
+}
+
static tree
build_cplus_array_type_1 (tree elt_type, tree index_type)
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index d8dce75..67f631a 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2d8c0ff..87af08c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..434a046
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/cast6.C
@@ -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
index 0000000..17cf8a8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/new15.C
@@ -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];
+}