diff options
author | Mark Mitchell <mark@codesourcery.com> | 2005-09-06 14:55:06 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2005-09-06 14:55:06 +0000 |
commit | 5cc53d4ece08f31e4b7dfeb563df42e3cec9f9e9 (patch) | |
tree | 4835a35a831281082968f68066f0ad2a45dddcec /gcc | |
parent | d102ae00ef70b537039d4cfb766a072ec576876a (diff) | |
download | gcc-5cc53d4ece08f31e4b7dfeb563df42e3cec9f9e9.zip gcc-5cc53d4ece08f31e4b7dfeb563df42e3cec9f9e9.tar.gz gcc-5cc53d4ece08f31e4b7dfeb563df42e3cec9f9e9.tar.bz2 |
re PR c++/9782 (constructor not called on higher-dimensional arrays of template types)
* 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.
From-SVN: r103947
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/cp/call.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/init.c | 9 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 2 | ||||
-rw-r--r-- | gcc/cp/tree.c | 20 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/expr/cast6.C | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/new15.C | 19 |
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]; +} |