diff options
| -rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
| -rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
| -rw-r--r-- | gcc/cp/tree.c | 63 | ||||
| -rw-r--r-- | gcc/cp/typeck.c | 2 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
| -rw-r--r-- | gcc/testsuite/g++.dg/ext/lvaddr.C | 10 | ||||
| -rw-r--r-- | gcc/testsuite/g++.dg/ext/lvcast.C | 11 | 
7 files changed, 85 insertions, 17 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cb95b6d33b7..def395ea126 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +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-22  Mark Mitchell  <mark@codesourcery.com>  	* typeck.c (build_class_member_access_expr): Handle COMPOUND_EXPR diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 44a52fc8e78..ef4f171829b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4184,6 +4184,7 @@ extern tree canonical_type_variant              PARAMS ((tree));  extern void unshare_base_binfos			PARAMS ((tree));  extern int member_p				PARAMS ((tree));  extern cp_lvalue_kind real_lvalue_p		PARAMS ((tree)); +extern int non_cast_lvalue_or_else		PARAMS ((tree, const char *));  extern tree build_min				PARAMS ((enum tree_code, tree,  							 ...));  extern tree build_min_nt			PARAMS ((enum tree_code, ...)); 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; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 624b379cf71..8535cde4ae7 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4268,7 +4268,7 @@ build_unary_op (code, xarg, noconvert)  	 is an error.  */        else if (TREE_CODE (argtype) != FUNCTION_TYPE  	       && TREE_CODE (argtype) != METHOD_TYPE -	       && !lvalue_or_else (arg, "unary `&'")) +	       && !non_cast_lvalue_or_else (arg, "unary `&'"))  	return error_mark_node;        if (argtype != error_mark_node) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 00a92134d45..f509299f6e5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2002-08-24  Matt Austern  <austern@apple.com> + +	* g++.dg/ext/lvaddr.C: New test. +	* g++.dg/ext/lvcast.C: New test. +	  2002-08-22  Mark Mitchell  <mark@codesourcery.com>  	* testsuite/g++.dg/inherit/cond1.C: New test. diff --git a/gcc/testsuite/g++.dg/ext/lvaddr.C b/gcc/testsuite/g++.dg/ext/lvaddr.C new file mode 100644 index 00000000000..184afce900b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/lvaddr.C @@ -0,0 +1,10 @@ +// Copyright (C) 2002 Free Software Foundation +// Contributed by Matt Austern <austern@apple.com> + +// { dg-do compile } + +void f() +{ +  int n; +  char* p = &(char) n;		// { dg-error "non-lvalue" } +} diff --git a/gcc/testsuite/g++.dg/ext/lvcast.C b/gcc/testsuite/g++.dg/ext/lvcast.C new file mode 100644 index 00000000000..efff04ec089 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/lvcast.C @@ -0,0 +1,11 @@ +// 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; +}  | 

