From fcb3f76e49122610579aff6585c27613be286f99 Mon Sep 17 00:00:00 2001 From: mmitchel Date: Tue, 6 Sep 2005 14:55:06 +0000 Subject: [PATCH] * 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. * 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 | 14 ++++++++++++++ gcc/cp/call.c | 2 +- gcc/cp/cp-tree.h | 3 ++- gcc/cp/init.c | 9 ++++----- gcc/cp/rtti.c | 2 +- gcc/cp/tree.c | 20 ++++++++++++++++++++ gcc/cp/typeck.c | 12 +++++------- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/g++.dg/expr/cast6.C | 6 ++++++ gcc/testsuite/g++.dg/init/new15.C | 19 +++++++++++++++++++ 10 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/g++.dg/expr/cast6.C create mode 100644 gcc/testsuite/g++.dg/init/new15.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4c200d751a6..50ce226f834 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +2005-09-06 Mark Mitchell + + * 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 * decl.c (check_elaborated_type_specifier): Remove redundant check. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 9f277cdc84a..fab01fc95f7 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 4d5d618950e..2803f51da27 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 8a8dc782ca3..50b0bcabb46 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 % 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 e0069388dd7..6d60d4c0359 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 ddc0b514c99..9c28f13f306 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 d8dce75c38d..67f631a31e5 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 2d8c0ffc9e5..87af08ca7b2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2005-09-06 Mark Mitchell + + * g++.dg/expr/cast6.C: New test. + + PR c++/9782 + * g++.dg/init/new15.C: New test. + 2005-09-06 Keith Besaw * 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 00000000000..434a046691e --- /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 00000000000..17cf8a80b68 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/new15.C @@ -0,0 +1,19 @@ +// PR c++/9782 + +extern "C" void printf(char *, ...); + +template +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]; +} -- 2.11.4.GIT