Commit 4e9ca9b0 by Jason Merrill Committed by Jason Merrill

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
parent 374fd2f5
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:
......
......@@ -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, ...);
......
......@@ -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
......
......@@ -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;
}
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.
......
......@@ -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" }
}
......@@ -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)
......
......@@ -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 }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment