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