summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2010-09-28 21:20:32 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2010-09-28 21:20:32 +0000
commit0eb0b6cae0a628fd37975b2df3592028753bf077 (patch)
treea08eb32bd94ddf4c8fe5242e91eb836a62ccc265
parenta5f0832f539af9c2218d06da2767d172db30cfba (diff)
downloadgcc-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/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 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 }