Commit d18a8251 by Mark Mitchell Committed by Mark Mitchell

Remove cast-as-lvalue extension.

	* call.c (build_conditional_expr): Correct formatting.
	(convert_like_real): Use lvalue_p, not non_cast_lvalue_p.
	(initialize_real): Use real_lvalue_p, not real_non_cast_lvalue_p.
	* cp-tree.h (non_cast_lvalue_p): Remove.
	(real_non_cast_lvalue_p): Remove.
	(non_cast_lvalue_or_else): Remove.
	* tree.c (lvalue_p_1): Remove allow_cast_as_lvalue parameter.
	(real_lvalue_p): Adjust call to lvalue_p_1.
	(non_cast_lvalue_p): Remove.
	(non_cast_lvalue_or_else): Remove.
	(lvalue_p): Adjust call to lvalue_p_1.
	(lvalue_or_else): Simplify.
	* typeck.c (build_unary_op): Use lvalue_or_else, not
	non_cast_lvalue_or_else.
	(build_static_cast): Use real_lvalue_p, not real_non_cast_lvalue_p.

	* doc/extend.texi: Document removal of cast-as-lvalue extension in
	C++.

	* g++.dg/expr/lval1.C: New test.
	* g++.dg/ext/lvcast.C: Remove.

From-SVN: r71051
parent c5ef564b
2003-09-04 Mark Mitchell <mark@codesourcery.com>
* doc/extend.texi: Document removal of cast-as-lvalue extension in
C++.
2003-09-04 Nicolas Roche <roche@act-europe.fr>
* gcc.c (process_command): Fix typo.
......
2003-09-04 Mark Mitchell <mark@codesourcery.com>
Remove cast-as-lvalue extension.
* call.c (build_conditional_expr): Correct formatting.
(convert_like_real): Use lvalue_p, not non_cast_lvalue_p.
(initialize_real): Use real_lvalue_p, not real_non_cast_lvalue_p.
* cp-tree.h (non_cast_lvalue_p): Remove.
(real_non_cast_lvalue_p): Remove.
(non_cast_lvalue_or_else): Remove.
* tree.c (lvalue_p_1): Remove allow_cast_as_lvalue parameter.
(real_lvalue_p): Adjust call to lvalue_p_1.
(non_cast_lvalue_p): Remove.
(non_cast_lvalue_or_else): Remove.
(lvalue_p): Adjust call to lvalue_p_1.
(lvalue_or_else): Simplify.
* typeck.c (build_unary_op): Use lvalue_or_else, not
non_cast_lvalue_or_else.
(build_static_cast): Use real_lvalue_p, not real_non_cast_lvalue_p.
2003-09-03 DJ Delorie <dj@redhat.com>
* decl.c (finish_function): Pass fndecl to aggregate_value_p.
......
......@@ -3193,8 +3193,9 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
If the second and third operands are lvalues and have the same
type, the result is of that type and is an lvalue. */
if (real_lvalue_p (arg2) && real_lvalue_p (arg3) &&
same_type_p (arg2_type, arg3_type))
if (real_lvalue_p (arg2)
&& real_lvalue_p (arg3)
&& same_type_p (arg2_type, arg3_type))
{
result_type = arg2_type;
goto valid_operands;
......@@ -4126,7 +4127,7 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner,
tree ref_type = totype;
/* If necessary, create a temporary. */
if (NEED_TEMPORARY_P (convs) || !non_cast_lvalue_p (expr))
if (NEED_TEMPORARY_P (convs) || !lvalue_p (expr))
{
tree type = TREE_TYPE (TREE_OPERAND (convs, 0));
......@@ -6089,7 +6090,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
base_conv_type = NULL_TREE;
/* Perform the remainder of the conversion. */
expr = convert_like (conv, expr);
if (!real_non_cast_lvalue_p (expr))
if (!real_lvalue_p (expr))
{
tree init;
tree type;
......
......@@ -4168,9 +4168,6 @@ extern tree canonical_type_variant (tree);
extern tree copy_base_binfos (tree, tree, tree);
extern int member_p (tree);
extern cp_lvalue_kind real_lvalue_p (tree);
extern int non_cast_lvalue_p (tree);
extern cp_lvalue_kind real_non_cast_lvalue_p (tree);
extern int non_cast_lvalue_or_else (tree, const char *);
extern tree build_min (enum tree_code, tree,
...);
extern tree build_min_nt (enum tree_code, ...);
......
......@@ -41,7 +41,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 (tree, int, int);
static cp_lvalue_kind lvalue_p_1 (tree, int);
static tree no_linkage_helper (tree *, int *, void *);
static tree mark_local_for_remap_r (tree *, int *, void *);
static tree cp_unsave_r (tree *, int *, void *);
......@@ -60,8 +60,7 @@ static tree handle_init_priority_attribute (tree *, tree, tree, int, bool *);
static cp_lvalue_kind
lvalue_p_1 (tree ref,
int treat_class_rvalues_as_lvalues,
int allow_cast_as_lvalue)
int treat_class_rvalues_as_lvalues)
{
cp_lvalue_kind op1_lvalue_kind = clk_none;
cp_lvalue_kind op2_lvalue_kind = clk_none;
......@@ -85,21 +84,11 @@ lvalue_p_1 (tree ref,
case REALPART_EXPR:
case IMAGPART_EXPR:
return lvalue_p_1 (TREE_OPERAND (ref, 0),
treat_class_rvalues_as_lvalues,
allow_cast_as_lvalue);
case NOP_EXPR:
if (allow_cast_as_lvalue)
return lvalue_p_1 (TREE_OPERAND (ref, 0),
treat_class_rvalues_as_lvalues,
allow_cast_as_lvalue);
else
return clk_none;
treat_class_rvalues_as_lvalues);
case COMPONENT_REF:
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
treat_class_rvalues_as_lvalues,
allow_cast_as_lvalue);
treat_class_rvalues_as_lvalues);
if (!op1_lvalue_kind
/* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
situations. */
......@@ -140,20 +129,16 @@ lvalue_p_1 (tree ref,
case MAX_EXPR:
case MIN_EXPR:
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
treat_class_rvalues_as_lvalues,
allow_cast_as_lvalue);
treat_class_rvalues_as_lvalues);
op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
treat_class_rvalues_as_lvalues,
allow_cast_as_lvalue);
treat_class_rvalues_as_lvalues);
break;
case COND_EXPR:
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
treat_class_rvalues_as_lvalues,
allow_cast_as_lvalue);
treat_class_rvalues_as_lvalues);
op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 2),
treat_class_rvalues_as_lvalues,
allow_cast_as_lvalue);
treat_class_rvalues_as_lvalues);
break;
case MODIFY_EXPR:
......@@ -161,8 +146,7 @@ lvalue_p_1 (tree ref,
case COMPOUND_EXPR:
return lvalue_p_1 (TREE_OPERAND (ref, 1),
treat_class_rvalues_as_lvalues,
allow_cast_as_lvalue);
treat_class_rvalues_as_lvalues);
case TARGET_EXPR:
return treat_class_rvalues_as_lvalues ? clk_class : clk_none;
......@@ -205,27 +189,15 @@ lvalue_p_1 (tree ref,
return op1_lvalue_kind;
}
/* If REF is an lvalue, returns the kind of lvalue that REF is.
Otherwise, returns clk_none. Lvalues can be assigned, unless they
have TREE_READONLY, or unless they are FUNCTION_DECLs. Lvalues can
have their address taken, unless they have DECL_REGISTER. */
cp_lvalue_kind
real_lvalue_p (tree ref)
{
return lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/ 0, /*cast*/ 1);
}
/* Returns the kind of lvalue that REF is, in the sense of
[basic.lval]. This function should really be named lvalue_p; it
computes the C++ definition of lvalue. */
cp_lvalue_kind
real_non_cast_lvalue_p (tree ref)
real_lvalue_p (tree ref)
{
return lvalue_p_1 (ref,
/*treat_class_rvalues_as_lvalues=*/0,
/*allow_cast_as_lvalue=*/0);
/*treat_class_rvalues_as_lvalues=*/0);
}
/* This differs from real_lvalue_p in that class rvalues are
......@@ -235,14 +207,7 @@ int
lvalue_p (tree ref)
{
return
(lvalue_p_1 (ref, /*class rvalue ok*/ 1, /*cast*/ 1) != clk_none);
}
int
non_cast_lvalue_p (tree ref)
{
return
(lvalue_p_1 (ref, /*class rvalue ok*/ 1, /*cast*/ 0) != clk_none);
(lvalue_p_1 (ref, /*class rvalue ok*/ 1) != clk_none);
}
/* Return nonzero if REF is an lvalue valid for this language;
......@@ -251,21 +216,12 @@ non_cast_lvalue_p (tree ref)
int
lvalue_or_else (tree ref, const char* string)
{
int ret = lvalue_p_1 (ref, /* class rvalue ok */ 1, /* cast ok */ 1);
int win = (ret != clk_none);
if (! win)
error ("non-lvalue in %s", string);
return win;
}
int
non_cast_lvalue_or_else (tree ref, const char* string)
{
int ret = lvalue_p_1 (ref, /* class rvalue ok */ 1, /* cast ok */ 0);
int win = (ret != clk_none);
if (! win)
if (!lvalue_p (ref))
{
error ("non-lvalue in %s", string);
return win;
return 0;
}
return 1;
}
/* Build a TARGET_EXPR, initializing the DECL with the VALUE. */
......
......@@ -3967,7 +3967,7 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
is an error. */
else if (TREE_CODE (argtype) != FUNCTION_TYPE
&& TREE_CODE (argtype) != METHOD_TYPE
&& !non_cast_lvalue_or_else (arg, "unary `&'"))
&& !lvalue_or_else (arg, "unary `&'"))
return error_mark_node;
if (argtype != error_mark_node)
......@@ -4391,7 +4391,7 @@ build_static_cast (tree type, tree expr)
if (TREE_CODE (type) == REFERENCE_TYPE
&& CLASS_TYPE_P (TREE_TYPE (type))
&& CLASS_TYPE_P (intype)
&& real_non_cast_lvalue_p (expr)
&& real_lvalue_p (expr)
&& DERIVED_FROM_P (intype, TREE_TYPE (type))
&& can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)),
build_pointer_type (TYPE_MAIN_VARIANT
......
......@@ -1071,9 +1071,9 @@ Compound expressions, conditional expressions and casts are allowed as
lvalues provided their operands are lvalues. This means that you can take
their addresses or store values into them.
Standard C++ allows compound expressions and conditional expressions as
lvalues, and permits casts to reference type, so use of this extension
is deprecated for C++ code.
Standard C++ allows compound expressions and conditional expressions
as lvalues, and permits casts to reference type, so use of this
extension is not supported for C++ code.
For example, a compound expression can be assigned, provided the last
expression in the sequence is an lvalue. These two expressions are
......
2003-09-04 Mark Mitchell <mark@codesourcery.com>
* g++.dg/expr/lval1.C: New test.
* g++.dg/ext/lvcast.C: Remove.
2003-09-03 Roger Sayle <roger@eyesopen.com>
PR optimization/11700.
......
// Copyright (C) 2002 Free Software Foundation
// Contributed by Matt Austern <austern@apple.com>
// { dg-do compile }
// { dg-options -fpermissive }
void f ()
{
int n;
(char) n = 1;
(char) n = 1; // { dg-error "" }
}
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