diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-28 21:20:32 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-28 21:20:32 +0000 |
commit | 0eb0b6cae0a628fd37975b2df3592028753bf077 (patch) | |
tree | a08eb32bd94ddf4c8fe5242e91eb836a62ccc265 | |
parent | a5f0832f539af9c2218d06da2767d172db30cfba (diff) | |
download | gcc-0eb0b6cae0a628fd37975b2df3592028753bf077.tar.gz |
* tree.c (lvalue_kind): Rename from lvalue_p_1, make nonstatic.
(real_lvalue_p): Take const_tree.
* cp-tree.h: Adjust.
* typeck.c (lvalue_or_else): Make temporary arg a permerror.
(cp_build_addr_expr_1): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164704 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/tree.c | 31 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 37 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/rv-lvalue-req.C | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/complit11.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.law/temps1.C | 3 |
8 files changed, 67 insertions, 31 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1776ee6fba8..175bc981942 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2010-09-28 Jason Merrill <jason@redhat.com> + + * tree.c (lvalue_kind): Rename from lvalue_p_1, make nonstatic. + (real_lvalue_p): Take const_tree. + * cp-tree.h: Adjust. + * typeck.c (lvalue_or_else): Make temporary arg a permerror. + (cp_build_addr_expr_1): Likewise. + 2010-09-28 Iain Sandoe <iains@gcc.gnu.org> Partially merged from apple/trunk branch on FSF servers: diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 2ff0973d691..7e671a8761c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5345,7 +5345,8 @@ extern void cp_set_underlying_type (tree); extern tree copy_binfo (tree, tree, tree, tree *, int); extern int member_p (const_tree); -extern cp_lvalue_kind real_lvalue_p (tree); +extern cp_lvalue_kind real_lvalue_p (const_tree); +extern cp_lvalue_kind lvalue_kind (const_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, ...); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index d52387b3b65..ddfb3542acf 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -40,7 +40,6 @@ static tree bot_replace (tree *, int *, void *); 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); static tree build_target_expr (tree, tree); static tree count_trees_r (tree *, int *, void *); static tree verify_stmt_tree_r (tree *, int *, void *); @@ -53,8 +52,8 @@ 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. */ -static cp_lvalue_kind -lvalue_p_1 (const_tree ref) +cp_lvalue_kind +lvalue_kind (const_tree ref) { cp_lvalue_kind op1_lvalue_kind = clk_none; cp_lvalue_kind op2_lvalue_kind = clk_none; @@ -66,7 +65,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)); + return lvalue_kind (TREE_OPERAND (ref, 0)); if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE) { @@ -96,10 +95,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)); + return lvalue_kind (TREE_OPERAND (ref, 0)); case COMPONENT_REF: - op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0)); + op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0)); /* Look at the member designator. */ if (!op1_lvalue_kind) ; @@ -156,22 +155,22 @@ 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)); - op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1)); + op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0)); + op2_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 1)); break; case COND_EXPR: - op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1) + op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 1) ? TREE_OPERAND (ref, 1) : TREE_OPERAND (ref, 0)); - op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 2)); + op2_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 2)); break; case MODIFY_EXPR: return clk_ordinary; case COMPOUND_EXPR: - return lvalue_p_1 (TREE_OPERAND (ref, 1)); + return lvalue_kind (TREE_OPERAND (ref, 1)); case TARGET_EXPR: return clk_class; @@ -194,7 +193,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))); + return lvalue_kind (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref))); case NON_DEPENDENT_EXPR: /* We must consider NON_DEPENDENT_EXPRs to be lvalues so that @@ -232,9 +231,9 @@ lvalue_p_1 (const_tree ref) computes the C++ definition of lvalue. */ cp_lvalue_kind -real_lvalue_p (tree ref) +real_lvalue_p (const_tree ref) { - cp_lvalue_kind kind = lvalue_p_1 (ref); + cp_lvalue_kind kind = lvalue_kind (ref); if (kind & (clk_rvalueref|clk_class)) return clk_none; else @@ -247,7 +246,7 @@ real_lvalue_p (tree ref) bool lvalue_p (const_tree ref) { - return (lvalue_p_1 (ref) != clk_none); + return (lvalue_kind (ref) != clk_none); } /* This differs from real_lvalue_p in that rvalues formed by dereferencing @@ -256,7 +255,7 @@ lvalue_p (const_tree ref) bool lvalue_or_rvalue_with_address_p (const_tree ref) { - cp_lvalue_kind kind = lvalue_p_1 (ref); + cp_lvalue_kind kind = lvalue_kind (ref); if (kind & clk_class) return false; else diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index c25a17708b4..eff670419f5 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4878,13 +4878,23 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain) if (TREE_CODE (argtype) != FUNCTION_TYPE && TREE_CODE (argtype) != METHOD_TYPE) { - bool win = strict_lvalue ? real_lvalue_p (arg) : lvalue_p (arg); - if (!win) + cp_lvalue_kind kind = lvalue_kind (arg); + if (kind == clk_none) { if (complain & tf_error) lvalue_error (lv_addressof); return error_mark_node; } + if (strict_lvalue && (kind & (clk_rvalueref|clk_class))) + { + if (!(complain & tf_error)) + return error_mark_node; + if (kind & clk_class) + /* Make this a permerror because we used to accept it. */ + permerror (input_location, "taking address of temporary"); + else + error ("taking address of xvalue (rvalue reference)"); + } } if (TREE_CODE (argtype) == REFERENCE_TYPE) @@ -8361,11 +8371,24 @@ non_reference (tree t) int lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain) { - int win = real_lvalue_p (ref); - - if (!win && (complain & tf_error)) - lvalue_error (use); + cp_lvalue_kind kind = lvalue_kind (ref); - return win; + if (kind == clk_none) + { + if (complain & tf_error) + lvalue_error (use); + return 0; + } + else if (kind & (clk_rvalueref|clk_class)) + { + if (!(complain & tf_error)) + return 0; + if (kind & clk_class) + /* Make this a permerror because we used to accept it. */ + permerror (input_location, "using temporary as lvalue"); + else + error ("using xvalue (rvalue reference) as lvalue"); + } + return 1; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1b1ec7f01ac..18f9f96fbb4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2010-09-28 Jason Merrill <jason@redhat.com> + * g++.dg/cpp0x/rv-lvalue-req.C: Adjust messages. + * g++.dg/ext/complit11.C: Likewise. + * g++.old-deja/g++.law/temps1.C: Likewise. + * g++.old-deja/g++.bugs/900121_02.C: Adjust for C++0x mode. * g++.old-deja/g++.mike/misc6.C: Likewise. diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-lvalue-req.C b/gcc/testsuite/g++.dg/cpp0x/rv-lvalue-req.C index ba1c306d9dc..a8f424df003 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv-lvalue-req.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv-lvalue-req.C @@ -4,9 +4,9 @@ template <class T> T&& declval(); int main() { - &declval<int>(); // { dg-error "lvalue" } - declval<int>() = declval<int>(); // { dg-error "lvalue" } - declval<int>()++; // { dg-error "lvalue" } - --declval<int>(); // { dg-error "lvalue" } - declval<int>() += 1; // { dg-error "lvalue" } + &declval<int>(); // { dg-error "xvalue" } + declval<int>() = declval<int>(); // { dg-error "xvalue" } + declval<int>()++; // { dg-error "xvalue" } + --declval<int>(); // { dg-error "xvalue" } + declval<int>() += 1; // { dg-error "xvalue" } } diff --git a/gcc/testsuite/g++.dg/ext/complit11.C b/gcc/testsuite/g++.dg/ext/complit11.C index 2cff6cd2eb4..0662543d941 100644 --- a/gcc/testsuite/g++.dg/ext/complit11.C +++ b/gcc/testsuite/g++.dg/ext/complit11.C @@ -6,7 +6,7 @@ struct A { int i; }; template<int t> void foo() { - ((struct A) { 0 }).i += 1; // { dg-error "lvalue required" } + ((struct A) { 0 }).i += 1; // { dg-error "temporary" } } void g(void) diff --git a/gcc/testsuite/g++.old-deja/g++.law/temps1.C b/gcc/testsuite/g++.old-deja/g++.law/temps1.C index 2e6a4195116..bd344b4190c 100644 --- a/gcc/testsuite/g++.old-deja/g++.law/temps1.C +++ b/gcc/testsuite/g++.old-deja/g++.law/temps1.C @@ -3,6 +3,7 @@ // temps file // Date: Mon, 07 Sep 1992 13:12:28 EDT // From: richard@ttt.kth.se +// { dg-options "-fpermissive" } struct foo { char *s; @@ -16,4 +17,4 @@ struct cookie }; cookie cat(&foo("apabepa"));// { dg-warning "deprecated conversion" "dep" } -// { dg-error "lvalue required" "lvalue" { target *-*-* } 18 } +// { dg-warning "taking address of temporary" "add" { target *-*-* } 19 } |