aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2010-09-28 17:20:32 -0400
committerJason Merrill <jason@gcc.gnu.org>2010-09-28 17:20:32 -0400
commit4e9ca9b0c8ad1cc353c70bb798fc5d2bc18f1013 (patch)
treea08eb32bd94ddf4c8fe5242e91eb836a62ccc265 /gcc
parent374fd2f5c87344707bf436f9e1d09b9789c1b104 (diff)
downloadgcc-4e9ca9b0c8ad1cc353c70bb798fc5d2bc18f1013.zip
gcc-4e9ca9b0c8ad1cc353c70bb798fc5d2bc18f1013.tar.gz
gcc-4e9ca9b0c8ad1cc353c70bb798fc5d2bc18f1013.tar.bz2
tree.c (lvalue_kind): Rename from lvalue_p_1, make nonstatic.
* 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. From-SVN: r164704
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/tree.c31
-rw-r--r--gcc/cp/typeck.c37
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/rv-lvalue-req.C10
-rw-r--r--gcc/testsuite/g++.dg/ext/complit11.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/temps1.C3
8 files changed, 67 insertions, 31 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1776ee6..175bc98 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 2ff0973..7e671a8 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 d52387b..ddfb3542 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 c25a177..eff6704 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 1b1ec7f..18f9f96 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 ba1c306..a8f424d 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 2cff6cd..0662543 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 2e6a419..bd344b4 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 }