diff options
author | Jason Merrill <jason@redhat.com> | 2009-07-12 15:19:15 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-07-12 15:19:15 -0400 |
commit | df5c89cb75836adc825e218cdb4307364889902e (patch) | |
tree | f66df5c05f93e0914a3aa2b839403fc721add63c | |
parent | 25357d1ee0ce69a5b1c194e7e1c7b6437c189b01 (diff) | |
download | gcc-df5c89cb75836adc825e218cdb4307364889902e.zip gcc-df5c89cb75836adc825e218cdb4307364889902e.tar.gz gcc-df5c89cb75836adc825e218cdb4307364889902e.tar.bz2 |
cp-tree.h (enum cp_lvalue_kind_flags): Add clk_rvalueref.
* cp-tree.h (enum cp_lvalue_kind_flags): Add clk_rvalueref.
* tree.c (lvalue_p_1): Return it. Remove
treat_class_rvalues_as_lvalues parm.
(real_lvalue_p): Disallow pseudo-lvalues here.
(lvalue_or_rvalue_with_address_p): New fn.
* call.c (initialize_reference): Use it instead of real_lvalue_p.
From-SVN: r149534
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/call.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 8 | ||||
-rw-r--r-- | gcc/cp/tree.c | 75 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/rv10.C | 15 |
6 files changed, 70 insertions, 43 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cff424f..d3fceab 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2009-07-12 Jason Merrill <jason@redhat.com> + PR c++/37206 + * cp-tree.h (enum cp_lvalue_kind_flags): Add clk_rvalueref. + * tree.c (lvalue_p_1): Return it. Remove + treat_class_rvalues_as_lvalues parm. + (real_lvalue_p): Disallow pseudo-lvalues here. + (lvalue_or_rvalue_with_address_p): New fn. + * call.c (initialize_reference): Use it instead of real_lvalue_p. + PR c++/40689 * init.c (build_new_1): Handle initializer list as array initializer. (build_vec_init): Likewise. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f0d624e..5edeb3a 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -7622,7 +7622,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup) expr = error_mark_node; else { - if (!real_lvalue_p (expr)) + if (!lvalue_or_rvalue_with_address_p (expr)) { tree init; var = set_up_extended_ref_temp (decl, expr, cleanup, &init); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 24351b4..933da19 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3509,9 +3509,10 @@ enum tag_types { enum cp_lvalue_kind_flags { clk_none = 0, /* Things that are not an lvalue. */ clk_ordinary = 1, /* An ordinary lvalue. */ - clk_class = 2, /* An rvalue of class-type. */ - clk_bitfield = 4, /* An lvalue for a bit-field. */ - clk_packed = 8 /* An lvalue for a packed field. */ + clk_rvalueref = 2,/* An rvalue formed using an rvalue reference */ + clk_class = 4, /* An rvalue of class-type. */ + clk_bitfield = 8, /* An lvalue for a bit-field. */ + clk_packed = 16 /* An lvalue for a packed field. */ }; /* This type is used for parameters and variables which hold @@ -4884,6 +4885,7 @@ extern tree copy_binfo (tree, tree, tree, tree *, int); extern int member_p (const_tree); extern cp_lvalue_kind real_lvalue_p (tree); +extern bool lvalue_or_rvalue_with_address_p (const_tree); extern bool builtin_valid_in_constant_expr_p (const_tree); extern tree build_min (enum tree_code, tree, ...); extern tree build_min_nt (enum tree_code, ...); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 644e53c..6981388 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -44,7 +44,7 @@ static tree build_cplus_array_type_1 (tree, tree); static int list_hash_eq (const void *, const void *); static hashval_t list_hash_pieces (tree, tree, tree); static hashval_t list_hash (const void *); -static cp_lvalue_kind lvalue_p_1 (const_tree, int); +static cp_lvalue_kind lvalue_p_1 (const_tree); static tree build_target_expr (tree, tree); static tree count_trees_r (tree *, int *, void *); static tree verify_stmt_tree_r (tree *, int *, void *); @@ -55,12 +55,10 @@ static tree handle_com_interface_attribute (tree *, tree, tree, int, bool *); static tree handle_init_priority_attribute (tree *, tree, tree, int, bool *); /* If REF is an lvalue, returns the kind of lvalue that REF is. - Otherwise, returns clk_none. If TREAT_CLASS_RVALUES_AS_LVALUES is - nonzero, rvalues of class type are considered lvalues. */ + Otherwise, returns clk_none. */ static cp_lvalue_kind -lvalue_p_1 (const_tree ref, - int treat_class_rvalues_as_lvalues) +lvalue_p_1 (const_tree ref) { cp_lvalue_kind op1_lvalue_kind = clk_none; cp_lvalue_kind op2_lvalue_kind = clk_none; @@ -72,8 +70,7 @@ lvalue_p_1 (const_tree ref, if (TREE_CODE (ref) == INDIRECT_REF && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == REFERENCE_TYPE) - return lvalue_p_1 (TREE_OPERAND (ref, 0), - treat_class_rvalues_as_lvalues); + return lvalue_p_1 (TREE_OPERAND (ref, 0)); if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE) { @@ -82,12 +79,7 @@ lvalue_p_1 (const_tree ref, && TREE_CODE (ref) != PARM_DECL && TREE_CODE (ref) != VAR_DECL && TREE_CODE (ref) != COMPONENT_REF) - { - if (CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (ref)))) - return treat_class_rvalues_as_lvalues ? clk_class : clk_none; - else - return clk_none; - } + return clk_rvalueref; /* lvalue references and named rvalue references are lvalues. */ return clk_ordinary; @@ -108,12 +100,10 @@ lvalue_p_1 (const_tree ref, case WITH_CLEANUP_EXPR: case REALPART_EXPR: case IMAGPART_EXPR: - return lvalue_p_1 (TREE_OPERAND (ref, 0), - treat_class_rvalues_as_lvalues); + return lvalue_p_1 (TREE_OPERAND (ref, 0)); case COMPONENT_REF: - op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0), - treat_class_rvalues_as_lvalues); + op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0)); /* Look at the member designator. */ if (!op1_lvalue_kind) ; @@ -164,35 +154,28 @@ lvalue_p_1 (const_tree ref, if (TREE_SIDE_EFFECTS (TREE_OPERAND (ref, 0)) || TREE_SIDE_EFFECTS (TREE_OPERAND (ref, 1))) return clk_none; - op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0), - treat_class_rvalues_as_lvalues); - op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1), - treat_class_rvalues_as_lvalues); + op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0)); + op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1)); break; case COND_EXPR: op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1) ? TREE_OPERAND (ref, 1) - : TREE_OPERAND (ref, 0), - treat_class_rvalues_as_lvalues); - op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 2), - treat_class_rvalues_as_lvalues); + : TREE_OPERAND (ref, 0)); + op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 2)); break; case MODIFY_EXPR: return clk_ordinary; case COMPOUND_EXPR: - return lvalue_p_1 (TREE_OPERAND (ref, 1), - treat_class_rvalues_as_lvalues); + return lvalue_p_1 (TREE_OPERAND (ref, 1)); case TARGET_EXPR: - return treat_class_rvalues_as_lvalues ? clk_class : clk_none; + return clk_class; case VA_ARG_EXPR: - return (treat_class_rvalues_as_lvalues - && CLASS_TYPE_P (TREE_TYPE (ref)) - ? clk_class : clk_none); + return (CLASS_TYPE_P (TREE_TYPE (ref)) ? clk_class : clk_none); case CALL_EXPR: /* Any class-valued call would be wrapped in a TARGET_EXPR. */ @@ -209,8 +192,7 @@ lvalue_p_1 (const_tree ref, with a BASELINK. */ /* This CONST_CAST is okay because BASELINK_FUNCTIONS returns its argument unmodified and we assign it to a const_tree. */ - return lvalue_p_1 (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref)), - treat_class_rvalues_as_lvalues); + return lvalue_p_1 (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref))); case NON_DEPENDENT_EXPR: /* We must consider NON_DEPENDENT_EXPRs to be lvalues so that @@ -246,18 +228,33 @@ lvalue_p_1 (const_tree ref, cp_lvalue_kind real_lvalue_p (tree ref) { - return lvalue_p_1 (ref, - /*treat_class_rvalues_as_lvalues=*/0); + cp_lvalue_kind kind = lvalue_p_1 (ref); + if (kind & (clk_rvalueref|clk_class)) + return clk_none; + else + return kind; } -/* This differs from real_lvalue_p in that class rvalues are - considered lvalues. */ +/* This differs from real_lvalue_p in that class rvalues are considered + lvalues. */ bool lvalue_p (const_tree ref) { - return - (lvalue_p_1 (ref, /*class rvalue ok*/ 1) != clk_none); + return (lvalue_p_1 (ref) != clk_none); +} + +/* This differs from real_lvalue_p in that rvalues formed by dereferencing + rvalue references are considered rvalues. */ + +bool +lvalue_or_rvalue_with_address_p (const_tree ref) +{ + cp_lvalue_kind kind = lvalue_p_1 (ref); + if (kind & clk_class) + return false; + else + return (kind != clk_none); } /* Test whether DECL is a builtin that may appear in a diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a12a5d2..7fdbcf4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2009-07-12 Jason Merrill <jason@redhat.com> + PR c++/37206 + * g++.dg/cpp0x/rv10.C: New. + +2009-07-12 Jason Merrill <jason@redhat.com> + PR c++/40689 * g++.dg/cpp0x/initlist20.C: New. * g++.dg/cpp0x/initlist21.C: New. diff --git a/gcc/testsuite/g++.dg/cpp0x/rv10.C b/gcc/testsuite/g++.dg/cpp0x/rv10.C new file mode 100644 index 0000000..5e78b1d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/rv10.C @@ -0,0 +1,15 @@ +// { dg-options "-std=gnu++0x" } + +struct A +{ + A() = default; + A(const A&) = delete; +}; + +A&& f(); +void h(A&&); +void g() +{ + A&& arr = f(); + h(f()); +} |