diff options
| author | shebs <shebs@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-08-25 04:57:16 +0000 | 
|---|---|---|
| committer | shebs <shebs@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-08-25 04:57:16 +0000 | 
| commit | 3e5d979595c5dd72ad98fdffb3deae78547b939b (patch) | |
| tree | 7bb6f3b26e6d15d4a769a03c44e1525a5daa0f24 /gcc/cp/tree.c | |
| parent | fbb76a77a493ef347474beaab73bc49ec92bcff3 (diff) | |
| download | ppe42-gcc-3e5d979595c5dd72ad98fdffb3deae78547b939b.tar.gz ppe42-gcc-3e5d979595c5dd72ad98fdffb3deae78547b939b.zip  | |
2002-08-24  Matt Austern  <austern@apple.com>
        * tree.c (lvalue_p_1): Add argument for whether casts of lvalues
        are allowable.
        (real_lvalue_p): Update caller.
        (lvalue_p): Ditto.
        (non_cast_lvalue_or_else): New.
        * tree.h: Declare it.
        * typeck.c (build_unary_op): Use non_cast_lvalue_or_else.
2002-08-24  Matt Austern  <austern@apple.com>
        * g++.dg/ext/lvaddr.C: New test.
        * g++.dg/ext/lvcast.C: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@56560 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/tree.c')
| -rw-r--r-- | gcc/cp/tree.c | 63 | 
1 files changed, 47 insertions, 16 deletions
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 36305660372..6e092850762 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -39,7 +39,7 @@ static tree build_cplus_array_type_1 PARAMS ((tree, tree));  static int list_hash_eq PARAMS ((const void *, const void *));  static hashval_t list_hash_pieces PARAMS ((tree, tree, tree));  static hashval_t list_hash PARAMS ((const void *)); -static cp_lvalue_kind lvalue_p_1 PARAMS ((tree, int)); +static cp_lvalue_kind lvalue_p_1 PARAMS ((tree, int, int));  static tree no_linkage_helper PARAMS ((tree *, int *, void *));  static tree build_srcloc PARAMS ((const char *, int));  static tree mark_local_for_remap_r PARAMS ((tree *, int *, void *)); @@ -59,9 +59,10 @@ static tree handle_init_priority_attribute PARAMS ((tree *, tree, tree, int, boo     non-zero, rvalues of class type are considered lvalues.  */  static cp_lvalue_kind -lvalue_p_1 (ref, treat_class_rvalues_as_lvalues) +lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue)       tree ref;       int treat_class_rvalues_as_lvalues; +     int allow_cast_as_lvalue;  {    cp_lvalue_kind op1_lvalue_kind = clk_none;    cp_lvalue_kind op2_lvalue_kind = clk_none; @@ -84,16 +85,28 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues)      case WITH_CLEANUP_EXPR:      case REALPART_EXPR:      case IMAGPART_EXPR: -      /* This shouldn't be here, but there are lots of places in the compiler -         that are sloppy about tacking on NOP_EXPRs to the same type when -	 no actual conversion is happening.  */ -    case NOP_EXPR:        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 expression doesn't change the type, we consider it as an +	 lvalue even when cast_as_lvalue extension isn't selected. +	 That's because parts of the compiler are alleged to be sloppy +	 about sticking in NOP_EXPR node for no good reason. */ +      if (allow_cast_as_lvalue || +	  same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ref)), +		       TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (ref, 0))))) +	return lvalue_p_1 (TREE_OPERAND (ref, 0), +			   treat_class_rvalues_as_lvalues, +			   allow_cast_as_lvalue); +      else +	return clk_none;      case COMPONENT_REF:        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   	  /* The "field" can be a FUNCTION_DECL or an OVERLOAD in some  	     situations.  */ @@ -134,16 +147,20 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues)      case MAX_EXPR:      case MIN_EXPR:        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), -				    treat_class_rvalues_as_lvalues); +				    treat_class_rvalues_as_lvalues, +				    allow_cast_as_lvalue);        break;      case COND_EXPR:        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), -				    treat_class_rvalues_as_lvalues); +				    treat_class_rvalues_as_lvalues, +				    allow_cast_as_lvalue);        break;      case MODIFY_EXPR: @@ -151,7 +168,8 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues)      case COMPOUND_EXPR:        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:        return treat_class_rvalues_as_lvalues ? clk_class : clk_none; @@ -196,7 +214,7 @@ cp_lvalue_kind  real_lvalue_p (ref)       tree ref;  { -  return lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/0); +  return lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/ 0, /*cast*/ 1);  }  /* This differs from real_lvalue_p in that class rvalues are @@ -207,7 +225,7 @@ lvalue_p (ref)       tree ref;  {    return  -    (lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/1) != clk_none); +    (lvalue_p_1 (ref, /*class rvalue ok*/ 1, /*cast*/ 1) != clk_none);  }  /* Return nonzero if REF is an lvalue valid for this language; @@ -218,7 +236,20 @@ lvalue_or_else (ref, string)       tree ref;       const char *string;  { -  int win = lvalue_p (ref); +  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 (ref, string) +     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;  | 

