Removing extended lvalues

Joseph S. Myers jsm@polyomino.org.uk
Sat Jan 17 20:55:00 GMT 2004


This mainline patch removes extended lvalues, since they are
deprecated in 3.4.  As a side-effect some constant expression cases
may be handled slightly better (an XFAIL in gcc.dg/array-5.c is
removed as GCC now recognises [(2, 2)] as meaning a VLA).

There are some changes in fold-const.c, which is supposed to be
language-independent.  After this patch it no longer references
pedantic directly at all.  It does however reference pedantic_lvalues
because other languages such as C++ and Fortran keep this set at false
unconditionally and this might correspond to various requirements in
their standards for some things to be lvalues.  (Fortran sets it to
false explicitly; treelang sets it to pedantic; other languages leave
it at false unconditionally.)  In any case, (a) it is clearly a bug
for pedantic ever to affect optimisation, as it might in fold-const.c,
(b) language-independent code should not concern itself with
language-specific concepts such as pedantic.  Properly it should not
concern itself with what's an lvalue either; each language should keep
track of that as parser state and apply the appropriate lvalueness to
the return value of fold, rather than fold using non_lvalue itself
either.  That however would be a bigger change to all supported
languages, though it can be done keeping lvalueness in trees: fold
would be wrapped to have an extra argument specifying whether the
result is an lvalue.

Bootstrapped with no regressions on i686-pc-linux-gnu.  OK to commit
(the fold-const.c changes)?

2004-01-17  Joseph S. Myers  <jsm@polyomino.org.uk>

	* c-decl.c (c_init_decl_processing): Set pedantic_lvalues to
	true unconditionally.
	* c-typeck.c (unary_complex_lvalue, pedantic_lvalue_warning):
	Remove.
	(build_unary_op, build_modify_expr): Don't handle extended
	lvalues.
	(build_component_ref, build_conditional_expr): Call non_lvalue
	instead of pedantic_non_lvalue).
	(build_c_cast): Don't conditional use of non_lvalue on pedantic.
	* fold-const.c (fold): Don't check pedantic directly for
	COMPOUND_EXPR.  Ensure that results for COMPOUND_EXPR are
	passed to pedantic_non_lvalue.
	* doc/extend.texi: Remove documentation of extended lvalues.

testsuite:
2004-01-17  Joseph S. Myers  <jsm@polyomino.org.uk>

	* gcc.c-torture/compile/981022-1.c: Remove.
	* gcc.dg/array-5.c: Remove XFAIL.
	* gcc.dg/sequence-pt-1.c: Remove test using extended lvalues.
	* gcc.dg/cast-lvalue-1.c, gcc.dg/compound-lvalue-1.c,
	gcc.dg/cond-lvalue-1.c: Update.
	* gcc.dg/cast-lvalue-2.c: New test.

diff -rupN GCC.orig/gcc/c-decl.c GCC/gcc/c-decl.c
--- GCC.orig/gcc/c-decl.c	2004-01-13 08:27:58.000000000 +0000
+++ GCC/gcc/c-decl.c	2004-01-17 16:24:18.000000000 +0000
@@ -2282,7 +2282,7 @@ c_init_decl_processing (void)
 
   input_location = save_loc;
 
-  pedantic_lvalues = pedantic;
+  pedantic_lvalues = true;
 
   make_fname_decl = c_make_fname_decl;
   start_fname_decls ();
diff -rupN GCC.orig/gcc/c-typeck.c GCC/gcc/c-typeck.c
--- GCC.orig/gcc/c-typeck.c	2004-01-16 10:14:29.000000000 +0000
+++ GCC/gcc/c-typeck.c	2004-01-16 21:33:08.000000000 +0000
@@ -60,8 +60,6 @@ static tree default_function_array_conve
 static tree lookup_field (tree, tree);
 static tree convert_arguments (tree, tree, tree, tree);
 static tree pointer_diff (tree, tree);
-static tree unary_complex_lvalue (enum tree_code, tree, int);
-static void pedantic_lvalue_warning (enum tree_code);
 static tree internal_build_compound_expr (tree, int);
 static tree convert_for_assignment (tree, tree, const char *, tree, tree,
 				    int);
@@ -1303,7 +1301,7 @@ build_component_ref (tree datum, tree co
   tree ref;
 
   /* If DATUM is a COMPOUND_EXPR, move our reference inside it.
-     If pedantic ensure that the arguments are not lvalues; otherwise,
+     Ensure that the arguments are not lvalues; otherwise,
      if the component is an array, it would wrongly decay to a pointer in
      C89 mode.
      We cannot do this with a COND_EXPR, because in a conditional expression
@@ -1316,7 +1314,7 @@ build_component_ref (tree datum, tree co
       {
 	tree value = build_component_ref (TREE_OPERAND (datum, 1), component);
 	return build (COMPOUND_EXPR, TREE_TYPE (value),
-		      TREE_OPERAND (datum, 0), pedantic_non_lvalue (value));
+		      TREE_OPERAND (datum, 0), non_lvalue (value));
       }
     default:
       break;
@@ -2287,12 +2285,6 @@ build_unary_op (enum tree_code code, tre
     case POSTINCREMENT_EXPR:
     case PREDECREMENT_EXPR:
     case POSTDECREMENT_EXPR:
-      /* Handle complex lvalues (when permitted)
-	 by reduction to simpler cases.  */
-
-      val = unary_complex_lvalue (code, arg, 0);
-      if (val != 0)
-	return val;
 
       /* Increment or decrement the real part of the value,
 	 and don't change the imaginary part.  */
@@ -2360,57 +2352,6 @@ build_unary_op (enum tree_code code, tre
 
 	inc = convert (argtype, inc);
 
-	/* Handle incrementing a cast-expression.  */
-
-	while (1)
-	  switch (TREE_CODE (arg))
-	    {
-	    case NOP_EXPR:
-	    case CONVERT_EXPR:
-	    case FLOAT_EXPR:
-	    case FIX_TRUNC_EXPR:
-	    case FIX_FLOOR_EXPR:
-	    case FIX_ROUND_EXPR:
-	    case FIX_CEIL_EXPR:
-	      pedantic_lvalue_warning (CONVERT_EXPR);
-	      /* If the real type has the same machine representation
-		 as the type it is cast to, we can make better output
-		 by adding directly to the inside of the cast.  */
-	      if ((TREE_CODE (TREE_TYPE (arg))
-		   == TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0))))
-		  && (TYPE_MODE (TREE_TYPE (arg))
-		      == TYPE_MODE (TREE_TYPE (TREE_OPERAND (arg, 0)))))
-		arg = TREE_OPERAND (arg, 0);
-	      else
-		{
-		  tree incremented, modify, value;
-		  if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
-		    value = boolean_increment (code, arg);
-		  else
-		    {
-		      arg = stabilize_reference (arg);
-		      if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
-			value = arg;
-		      else
-			value = save_expr (arg);
-		      incremented = build (((code == PREINCREMENT_EXPR
-					     || code == POSTINCREMENT_EXPR)
-					    ? PLUS_EXPR : MINUS_EXPR),
-					   argtype, value, inc);
-		      TREE_SIDE_EFFECTS (incremented) = 1;
-		      modify = build_modify_expr (arg, NOP_EXPR, incremented);
-		      value = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value);
-		    }
-		  TREE_USED (value) = 1;
-		  return value;
-		}
-	      break;
-
-	    default:
-	      goto give_up;
-	    }
-      give_up:
-
 	/* Complain about anything else that is not a true lvalue.  */
 	if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
 				    || code == POSTINCREMENT_EXPR)
@@ -2457,12 +2398,6 @@ build_unary_op (enum tree_code code, tre
 				  TREE_OPERAND (arg, 1), 1);
 	}
 
-      /* Handle complex lvalues (when permitted)
-	 by reduction to simpler cases.  */
-      val = unary_complex_lvalue (code, arg, flag);
-      if (val != 0)
-	return val;
-
       /* Anything not already handled and not a true memory reference
 	 or a non-lvalue array is an error.  */
       else if (typecode != FUNCTION_TYPE && !flag
@@ -2580,67 +2515,6 @@ lvalue_or_else (tree ref, const char *ms
   return win;
 }
 
-/* Apply unary lvalue-demanding operator CODE to the expression ARG
-   for certain kinds of expressions which are not really lvalues
-   but which we can accept as lvalues.  If FLAG is nonzero, then
-   non-lvalues are OK since we may be converting a non-lvalue array to
-   a pointer in C99.
-
-   If ARG is not a kind of expression we can handle, return zero.  */
-
-static tree
-unary_complex_lvalue (enum tree_code code, tree arg, int flag)
-{
-  /* Handle (a, b) used as an "lvalue".  */
-  if (TREE_CODE (arg) == COMPOUND_EXPR)
-    {
-      tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0);
-
-      /* If this returns a function type, it isn't really being used as
-	 an lvalue, so don't issue a warning about it.  */
-      if (TREE_CODE (TREE_TYPE (arg)) != FUNCTION_TYPE && !flag)
-	pedantic_lvalue_warning (COMPOUND_EXPR);
-
-      return build (COMPOUND_EXPR, TREE_TYPE (real_result),
-		    TREE_OPERAND (arg, 0), real_result);
-    }
-
-  /* Handle (a ? b : c) used as an "lvalue".  */
-  if (TREE_CODE (arg) == COND_EXPR)
-    {
-      if (!flag)
-	pedantic_lvalue_warning (COND_EXPR);
-      if (TREE_CODE (TREE_TYPE (arg)) != FUNCTION_TYPE && !flag)
-	pedantic_lvalue_warning (COMPOUND_EXPR);
-
-      return (build_conditional_expr
-	      (TREE_OPERAND (arg, 0),
-	       build_unary_op (code, TREE_OPERAND (arg, 1), flag),
-	       build_unary_op (code, TREE_OPERAND (arg, 2), flag)));
-    }
-
-  return 0;
-}
-
-/* If pedantic, warn about improper lvalue.   CODE is either COND_EXPR
-   COMPOUND_EXPR, or CONVERT_EXPR (for casts).  */
-
-static void
-pedantic_lvalue_warning (enum tree_code code)
-{
-  switch (code)
-    {
-    case COND_EXPR:
-      pedwarn ("use of conditional expressions as lvalues is deprecated");
-      break;
-    case COMPOUND_EXPR:
-      pedwarn ("use of compound expressions as lvalues is deprecated");
-      break;
-    default:
-      pedwarn ("use of cast expressions as lvalues is deprecated");
-      break;
-    }
-}
 
 /* Warn about storing in something that is `const'.  */
 
@@ -2901,7 +2775,7 @@ build_conditional_expr (tree ifexp, tree
     op2 = convert_and_check (result_type, op2);
 
   if (TREE_CODE (ifexp) == INTEGER_CST)
-    return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1);
+    return non_lvalue (integer_zerop (ifexp) ? op2 : op1);
 
   return fold (build (COND_EXPR, result_type, ifexp, op1, op2));
 }
@@ -3158,14 +3032,14 @@ build_c_cast (tree type, tree expr)
 	}
     }
 
-  /* Pedantically, don't let (void *) (FOO *) 0 be a null pointer constant.  */
-  if (pedantic && TREE_CODE (value) == INTEGER_CST
+  /* Don't let (void *) (FOO *) 0 be a null pointer constant.  */
+  if (TREE_CODE (value) == INTEGER_CST
       && TREE_CODE (expr) == INTEGER_CST
       && TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE)
     value = non_lvalue (value);
 
-  /* If pedantic, don't let a cast be an lvalue.  */
-  if (value == expr && pedantic)
+  /* Don't let a cast be an lvalue.  */
+  if (value == expr)
     value = non_lvalue (value);
 
   return value;
@@ -3216,45 +3090,6 @@ build_modify_expr (tree lhs, enum tree_c
 
   newrhs = rhs;
 
-  /* Handle control structure constructs used as "lvalues".  */
-
-  switch (TREE_CODE (lhs))
-    {
-      /* Handle (a, b) used as an "lvalue".  */
-    case COMPOUND_EXPR:
-      pedantic_lvalue_warning (COMPOUND_EXPR);
-      newrhs = build_modify_expr (TREE_OPERAND (lhs, 1), modifycode, rhs);
-      if (TREE_CODE (newrhs) == ERROR_MARK)
-	return error_mark_node;
-      return build (COMPOUND_EXPR, lhstype,
-		    TREE_OPERAND (lhs, 0), newrhs);
-
-      /* Handle (a ? b : c) used as an "lvalue".  */
-    case COND_EXPR:
-      pedantic_lvalue_warning (COND_EXPR);
-      rhs = save_expr (rhs);
-      {
-	/* Produce (a ? (b = rhs) : (c = rhs))
-	   except that the RHS goes through a save-expr
-	   so the code to compute it is only emitted once.  */
-	tree cond
-	  = build_conditional_expr (TREE_OPERAND (lhs, 0),
-				    build_modify_expr (TREE_OPERAND (lhs, 1),
-						       modifycode, rhs),
-				    build_modify_expr (TREE_OPERAND (lhs, 2),
-						       modifycode, rhs));
-	if (TREE_CODE (cond) == ERROR_MARK)
-	  return cond;
-	/* Make sure the code to compute the rhs comes out
-	   before the split.  */
-	return build (COMPOUND_EXPR, TREE_TYPE (lhs),
-		      /* But cast it to void to avoid an "unused" error.  */
-		      convert (void_type_node, rhs), cond);
-      }
-    default:
-      break;
-    }
-
   /* If a binary op has been requested, combine the old LHS value with the RHS
      producing the value we should actually store into the LHS.  */
 
@@ -3264,42 +3099,6 @@ build_modify_expr (tree lhs, enum tree_c
       newrhs = build_binary_op (modifycode, lhs, rhs, 1);
     }
 
-  /* Handle a cast used as an "lvalue".
-     We have already performed any binary operator using the value as cast.
-     Now convert the result to the cast type of the lhs,
-     and then true type of the lhs and store it there;
-     then convert result back to the cast type to be the value
-     of the assignment.  */
-
-  switch (TREE_CODE (lhs))
-    {
-    case NOP_EXPR:
-    case CONVERT_EXPR:
-    case FLOAT_EXPR:
-    case FIX_TRUNC_EXPR:
-    case FIX_FLOOR_EXPR:
-    case FIX_ROUND_EXPR:
-    case FIX_CEIL_EXPR:
-      newrhs = default_function_array_conversion (newrhs);
-      {
-	tree inner_lhs = TREE_OPERAND (lhs, 0);
-	tree result;
-	result = build_modify_expr (inner_lhs, NOP_EXPR,
-				    convert (TREE_TYPE (inner_lhs),
-					     convert (lhstype, newrhs)));
-	if (TREE_CODE (result) == ERROR_MARK)
-	  return result;
-	pedantic_lvalue_warning (CONVERT_EXPR);
-	return convert (TREE_TYPE (lhs), result);
-      }
-
-    default:
-      break;
-    }
-
-  /* Now we have handled acceptable kinds of LHS that are not truly lvalues.
-     Reject anything strange now.  */
-
   if (!lvalue_or_else (lhs, "invalid lvalue in assignment"))
     return error_mark_node;
 
diff -rupN GCC.orig/gcc/doc/extend.texi GCC/gcc/doc/extend.texi
--- GCC.orig/gcc/doc/extend.texi	2004-01-07 22:20:16.000000000 +0000
+++ GCC/gcc/doc/extend.texi	2004-01-16 22:48:01.000000000 +0000
@@ -429,7 +429,6 @@ extensions, accepted by GCC in C89 mode 
 * Nested Functions::    As in Algol and Pascal, lexical scoping of functions.
 * Constructing Calls::	Dispatching a call to another function.
 * Typeof::              @code{typeof}: referring to the type of an expression.
-* Lvalues::             Using @samp{?:}, @samp{,} and casts in lvalues.
 * Conditionals::        Omitting the middle operand of a @samp{?:} expression.
 * Long Long::		Double-word integers---@code{long long int}.
 * Complex::             Data types for complex numbers.
@@ -1060,94 +1059,6 @@ typedef typeof(@var{expr}) @var{T};
 @noindent
 This will work with all versions of GCC@.
 
-@node Lvalues
-@section Generalized Lvalues
-@cindex compound expressions as lvalues
-@cindex expressions, compound, as lvalues
-@cindex conditional expressions as lvalues
-@cindex expressions, conditional, as lvalues
-@cindex casts as lvalues
-@cindex generalized lvalues
-@cindex lvalues, generalized
-@cindex extensions, @code{?:}
-@cindex @code{?:} extensions
-
-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.  All these extensions are
-deprecated.
-
-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
-equivalent:
-
-@example
-(a, b) += 5
-a, (b += 5)
-@end example
-
-Similarly, the address of the compound expression can be taken.  These two
-expressions are equivalent:
-
-@example
-&(a, b)
-a, &b
-@end example
-
-A conditional expression is a valid lvalue if its type is not void and the
-true and false branches are both valid lvalues.  For example, these two
-expressions are equivalent:
-
-@example
-(a ? b : c) = 5
-(a ? b = 5 : (c = 5))
-@end example
-
-A cast is a valid lvalue if its operand is an lvalue.  This extension
-is deprecated.  A simple
-assignment whose left-hand side is a cast works by converting the
-right-hand side first to the specified type, then to the type of the
-inner left-hand side expression.  After this is stored, the value is
-converted back to the specified type to become the value of the
-assignment.  Thus, if @code{a} has type @code{char *}, the following two
-expressions are equivalent:
-
-@example
-(int)a = 5
-(int)(a = (char *)(int)5)
-@end example
-
-An assignment-with-arithmetic operation such as @samp{+=} applied to a cast
-performs the arithmetic using the type resulting from the cast, and then
-continues as in the previous case.  Therefore, these two expressions are
-equivalent:
-
-@example
-(int)a += 5
-(int)(a = (char *)(int) ((int)a + 5))
-@end example
-
-You cannot take the address of an lvalue cast, because the use of its
-address would not work out coherently.  Suppose that @code{&(int)f} were
-permitted, where @code{f} has type @code{float}.  Then the following
-statement would try to store an integer bit-pattern where a floating
-point number belongs:
-
-@example
-*&(int)f = 1;
-@end example
-
-This is quite different from what @code{(int)f = 1} would do---that
-would convert 1 to floating point and store it.  Rather than cause this
-inconsistency, we think it is better to prohibit use of @samp{&} on a cast.
-
-If you really do want an @code{int *} pointer with the address of
-@code{f}, you can simply write @code{(int *)&f}.
-
 @node Conditionals
 @section Conditionals with Omitted Operands
 @cindex conditional expressions, extensions
diff -rupN GCC.orig/gcc/fold-const.c GCC/gcc/fold-const.c
--- GCC.orig/gcc/fold-const.c	2004-01-16 10:14:30.000000000 +0000
+++ GCC/gcc/fold-const.c	2004-01-17 16:29:34.000000000 +0000
@@ -8170,12 +8170,12 @@ fold (tree expr)
     case COMPOUND_EXPR:
       /* When pedantic, a compound expression can be neither an lvalue
 	 nor an integer constant expression.  */
-      if (TREE_SIDE_EFFECTS (arg0) || pedantic)
+      if (TREE_SIDE_EFFECTS (arg0) || TREE_CONSTANT (arg1))
 	return t;
       /* Don't let (0, 0) be null pointer constant.  */
       if (integer_zerop (arg1))
-	return build1 (NOP_EXPR, type, arg1);
-      return convert (type, arg1);
+	return pedantic_non_lvalue (build1 (NOP_EXPR, type, arg1));
+      return pedantic_non_lvalue (convert (type, arg1));
 
     case COMPLEX_EXPR:
       if (wins)
diff -rupN GCC.orig/gcc/testsuite/gcc.c-torture/compile/981022-1.c GCC/gcc/testsuite/gcc.c-torture/compile/981022-1.c
--- GCC.orig/gcc/testsuite/gcc.c-torture/compile/981022-1.c	2003-10-04 07:36:26.000000000 +0000
+++ GCC/gcc/testsuite/gcc.c-torture/compile/981022-1.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,9 +0,0 @@
-/* This tests a combination of two gcc extensions.  Omitting the middle
-   operand of ?: and using ?: as an lvalue.  */
-int x, y;
-
-int main ()
-{
-  (x ?: y) = 0; /* { dg-bogus "lvalue" "" { xfail *-*-* } } */
-  return 0;
-}
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/array-5.c GCC/gcc/testsuite/gcc.dg/array-5.c
--- GCC.orig/gcc/testsuite/gcc.dg/array-5.c	2001-09-17 16:38:59.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/array-5.c	2004-01-17 19:38:28.000000000 +0000
@@ -37,6 +37,6 @@ void func(int n, int m)
        expression, and thus A is a VLA.  */
     int a[6][(2, 2)];
     int (*p)[3];
-    p = a; /* { dg-bogus "incompatible" "bad vla handling" { xfail *-*-* } } */
+    p = a; /* { dg-bogus "incompatible" "bad vla handling" } */
   }
 }
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/cast-lvalue-1.c GCC/gcc/testsuite/gcc.dg/cast-lvalue-1.c
--- GCC.orig/gcc/testsuite/gcc.dg/cast-lvalue-1.c	2003-10-22 22:22:52.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/cast-lvalue-1.c	2004-01-16 20:50:40.000000000 +0000
@@ -8,5 +8,6 @@ int x;
 void
 foo (void)
 {
-  (char) x = 1; /* { dg-warning "lvalue" "cast as lvalue deprecated" } */
+  (char) x = 1; /* { dg-bogus "warning" "warning in place of error" } */
 }
+/* { dg-error "lvalue" "cast as lvalue" { target *-*-* } 11 } */
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/cast-lvalue-2.c GCC/gcc/testsuite/gcc.dg/cast-lvalue-2.c
--- GCC.orig/gcc/testsuite/gcc.dg/cast-lvalue-2.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/cast-lvalue-2.c	2004-01-16 20:51:45.000000000 +0000
@@ -0,0 +1,13 @@
+/* Test for error on casts as lvalues.  Casts to same type.  */
+/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+int x;
+
+void
+foo (void)
+{
+  (int) x = 1; /* { dg-bogus "warning" "warning in place of error" } */
+}
+/* { dg-error "lvalue" "cast as lvalue" { target *-*-*} 11 } */
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/compound-lvalue-1.c GCC/gcc/testsuite/gcc.dg/compound-lvalue-1.c
--- GCC.orig/gcc/testsuite/gcc.dg/compound-lvalue-1.c	2003-11-08 01:35:19.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/compound-lvalue-1.c	2004-01-16 20:50:44.000000000 +0000
@@ -8,5 +8,6 @@ int x, y;
 void
 foo (void)
 {
-  (x, y) = 1; /* { dg-warning "lvalue" "compound expression as lvalue deprecated" } */
+  (x, y) = 1; /* { dg-bogus "warning" "warning in place of error" } */
 }
+/* { dg-error "lvalue" "compound expression as lvalue" { target *-*-* } 11 } */
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/cond-lvalue-1.c GCC/gcc/testsuite/gcc.dg/cond-lvalue-1.c
--- GCC.orig/gcc/testsuite/gcc.dg/cond-lvalue-1.c	2003-11-05 17:50:29.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/cond-lvalue-1.c	2004-01-16 20:50:48.000000000 +0000
@@ -8,5 +8,6 @@ int x, y, z;
 void
 foo (void)
 {
-  (x ? y : z) = 1; /* { dg-warning "lvalue" "conditional expression as lvalue deprecated" } */
+  (x ? y : z) = 1; /* { dg-bogus "warning" "warning in place of error" } */
 }
+/* { dg-error "lvalue" "conditional expression as lvalue" { target *-*-* } 11 } */
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/sequence-pt-1.c GCC/gcc/testsuite/gcc.dg/sequence-pt-1.c
--- GCC.orig/gcc/testsuite/gcc.dg/sequence-pt-1.c	2001-03-08 03:13:44.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/sequence-pt-1.c	2004-01-17 19:42:44.000000000 +0000
@@ -58,7 +58,6 @@ foo (int a, int b, int n, int p, int *pt
   b = a, a = a++; /* { dg-warning "undefined" "sequence point warning" } */
   a = (b++ ? n : a) + b; /* { dg-warning "undefined" "sequence point warning" { xfail *-*-* } } */
   b ? a = a++ : a; /* { dg-warning "undefined" "sequence point warning" } */
-  b ? a : a = a++; /* { dg-warning "undefined" "sequence point warning" } */
   b && (a = a++); /* { dg-warning "undefined" "sequence point warning" } */
   (a = a++) && b; /* { dg-warning "undefined" "sequence point warning" } */
   b, (a = a++); /* { dg-warning "undefined" "sequence point warning" } */

-- 
Joseph S. Myers
jsm@polyomino.org.uk



More information about the Gcc-patches mailing list