From 29c42daf675f1f54b9de6f956d9ae08d6bf294c2 Mon Sep 17 00:00:00 2001 From: mmitchel Date: Thu, 4 Sep 2003 07:16:43 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@71051 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 5 +++ gcc/cp/ChangeLog | 19 ++++++++++ gcc/cp/call.c | 9 +++-- gcc/cp/cp-tree.h | 5 +-- gcc/cp/tree.c | 80 +++++++++------------------------------ gcc/cp/typeck.c | 4 +- gcc/doc/extend.texi | 6 +-- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/expr/lval1.C | 7 ++++ gcc/testsuite/g++.dg/ext/lvcast.C | 11 ------ 10 files changed, 65 insertions(+), 86 deletions(-) create mode 100644 gcc/testsuite/g++.dg/expr/lval1.C delete mode 100644 gcc/testsuite/g++.dg/ext/lvcast.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index acbd799..f078ad4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2003-09-04 Mark Mitchell + + * doc/extend.texi: Document removal of cast-as-lvalue extension in + C++. + 2003-09-04 Nicolas Roche * gcc.c (process_command): Fix typo. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index dafa9c5..50fe265 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,22 @@ +2003-09-04 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. + 2003-09-03 DJ Delorie * decl.c (finish_function): Pass fndecl to aggregate_value_p. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 9e46282..35a8226 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index cf4b8ce..50228e2 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4167,10 +4167,7 @@ extern int zero_init_p (tree); 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 cp_lvalue_kind real_lvalue_p (tree); extern tree build_min (enum tree_code, tree, ...); extern tree build_min_nt (enum tree_code, ...); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 532d8b9..71742a7 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -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) - error ("non-lvalue in %s", string); - return win; + if (!lvalue_p (ref)) + { + error ("non-lvalue in %s", string); + return 0; + } + return 1; } /* Build a TARGET_EXPR, initializing the DECL with the VALUE. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 564b337..2a21a00 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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 diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 0edf2cf..6664e1c 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d417f83..562ed09 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-09-04 Mark Mitchell + + * g++.dg/expr/lval1.C: New test. + * g++.dg/ext/lvcast.C: Remove. + 2003-09-03 Roger Sayle PR optimization/11700. diff --git a/gcc/testsuite/g++.dg/expr/lval1.C b/gcc/testsuite/g++.dg/expr/lval1.C new file mode 100644 index 0000000..bed47d8 --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/lval1.C @@ -0,0 +1,7 @@ +// Contributed by Matt Austern + +void f () +{ + int n; + (char) n = 1; // { dg-error "" } +} diff --git a/gcc/testsuite/g++.dg/ext/lvcast.C b/gcc/testsuite/g++.dg/ext/lvcast.C deleted file mode 100644 index efff04e..0000000 --- a/gcc/testsuite/g++.dg/ext/lvcast.C +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (C) 2002 Free Software Foundation -// Contributed by Matt Austern - -// { dg-do compile } -// { dg-options -fpermissive } - -void f () -{ - int n; - (char) n = 1; -} -- 2.7.4