This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Patch to deprecate casts as lvalues for C


This version of the patch (minus the already committed extend.texi and
libobjc changes) includes a change to obstack.h merged from the
version applied to gnulib (the GCC version can't actually be fully
merged from the gnulib one until libiberty no longer need support K&R
C).  Bootstrapped with no regressions on i686-pc-linux-gnu.  OK to
commit this change to obstack.h?

include:
2003-10-22  Joseph S. Myers  <jsm@polyomino.org.uk>

	* obstack.h: Merge the following change from gnulib:
	2003-10-21  Paul Eggert  <eggert@twinsun.com>
	* obstack.h (obstack_1grow_fast): Properly parenthesize arg.
	(obstack_ptr_grow_fast, obstack_int_grow_fast):
	Don't use lvalue casts, as GCC plans to remove support for them
	in GCC 3.5.  Reported by Joseph S. Myers.  This bug
	was also present in the non-GCC version, indicating that this
	code had always been buggy and had never been widely used.
	(obstack_1grow, obstack_ptr_grow, obstack_int_grow, obstack_blank):
	Use the fast variant of each macro, rather than copying the
	definiens of the fast variant; that way, we'll be more likely to
	catch future bugs in the fast variants.

gcc:
2003-10-22  Joseph S. Myers  <jsm@polyomino.org.uk>

	* c-typeck.c (pedantic_lvalue_warning): Unconditionally warn of
	deprecation of casts as lvalues.
	* fixinc/inclhack.def (obstack_lvalue_cast): New fix.
	* fixinc/fixincl.x: Regenerate.
	* fixinc/tests/base/obstack.h: New test.

gcc/testsuite:
2003-10-22  Joseph S. Myers  <jsm@polyomino.org.uk>

	* gcc.dg/cast-lvalue-1.c: New test.

--- GCC/gcc/c-typeck.c.orig	2003-10-06 12:25:11.000000000 +0000
+++ GCC/gcc/c-typeck.c	2003-10-20 09:47:25.000000000 +0000
@@ -2585,19 +2585,20 @@
 static void
 pedantic_lvalue_warning (enum tree_code code)
 {
-  if (pedantic)
-    switch (code)
-      {
-      case COND_EXPR:
+  switch (code)
+    {
+    case COND_EXPR:
+      if (pedantic)
 	pedwarn ("ISO C forbids use of conditional expressions as lvalues");
-	break;
-      case COMPOUND_EXPR:
+      break;
+    case COMPOUND_EXPR:
+      if (pedantic)
 	pedwarn ("ISO C forbids use of compound expressions as lvalues");
-	break;
-      default:
-	pedwarn ("ISO C forbids use of cast expressions as lvalues");
-	break;
-      }
+      break;
+    default:
+      pedwarn ("use of cast expressions as lvalues is deprecated");
+      break;
+    }
 }
 
 /* Warn about storing in something that is `const'.  */
--- GCC/gcc/testsuite/gcc.dg/cast-lvalue-1.c	2002-08-26 16:21:36.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/cast-lvalue-1.c	2003-10-20 09:52:41.000000000 +0000
@@ -0,0 +1,12 @@
+/* Test for deprecation of casts as lvalues.  */
+/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+int x;
+
+void
+foo (void)
+{
+  (char) x = 1; /* { dg-warning "lvalue" "cast as lvalue deprecated" } */
+}
--- GCC/gcc/fixinc/inclhack.def.orig	2003-10-15 08:05:56.000000000 +0000
+++ GCC/gcc/fixinc/inclhack.def	2003-10-20 21:24:45.000000000 +0000
@@ -1978,6 +1978,31 @@
 
 
 /*
+ *  obstack.h used casts as lvalues.
+ *
+ *  We need to change postincrements of casted pointers (which are
+ *  then dereferenced and assigned into) of the form
+ *
+ *    *((TYPE*)PTRVAR)++ = (VALUE)
+ *
+ *  into expressions like
+ *
+ *    ((*((TYPE*)PTRVAR) = (VALUE)), (PTRVAR += sizeof (TYPE)))
+ *
+ *  which is correct for the cases used in obstack.h since PTRVAR is
+ *  of type char * and the value of the expression is not used.
+ */
+fix = {
+    hackname  = obstack_lvalue_cast;
+    files     = obstack.h;
+    select    = '\*\(\(([^()]*)\*\)(.*)\)\+\+ = \(([^()]*)\)';
+    c_fix     = format;
+    c_fix_arg = "((*((%1*)%2) = (%3)), (%2 += sizeof (%1)))";
+    test_text = "*((void **) (h)->next_free)++ = (aptr)";
+};
+
+
+/*
  *  sys/lc_core.h on some versions of OSF1/4.x pollutes the namespace by
  *  defining regex.h related types.  This causes libg++ build and usage
  *  failures.  Fixing this correctly requires checking and modifying 3 files.
--- GCC/gcc/fixinc/tests/base/obstack.h	2002-08-26 16:21:36.000000000 +0000
+++ GCC/gcc/fixinc/tests/base/obstack.h	2003-10-20 20:00:25.000000000 +0000
@@ -0,0 +1,14 @@
+/*  DO NOT EDIT THIS FILE.
+
+    It has been auto-edited by fixincludes from:
+
+	"fixinc/tests/inc/obstack.h"
+
+    This had to be done to correct non-standard usages in the
+    original, manufacturer supplied header file.  */
+
+
+
+#if defined( OBSTACK_LVALUE_CAST_CHECK )
+((*((void **) (h)->next_free) = (aptr)), ( (h)->next_free += sizeof (void *)))
+#endif  /* OBSTACK_LVALUE_CAST_CHECK */
--- GCC/include/obstack.h.orig	2003-10-20 18:05:55.000000000 +0000
+++ GCC/include/obstack.h	2003-10-22 09:26:39.000000000 +0000
@@ -343,7 +343,7 @@
 
 #endif
 
-#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)
+#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar))
 
 #define obstack_blank_fast(h,n) ((h)->next_free += (n))
 
@@ -411,7 +411,7 @@
 ({ struct obstack *__o = (OBSTACK);					\
    if (__o->next_free + 1 > __o->chunk_limit)				\
      _obstack_newchunk (__o, 1);					\
-   *(__o->next_free)++ = (datum);					\
+   obstack_1grow_fast (__o, datum);					\
    (void) 0; })
 
 /* These assume that the obstack alignment is good enough for pointers or ints,
@@ -423,19 +423,28 @@
 ({ struct obstack *__o = (OBSTACK);					\
    if (__o->next_free + sizeof (void *) > __o->chunk_limit)		\
      _obstack_newchunk (__o, sizeof (void *));				\
-   *((void **)__o->next_free)++ = ((void *)datum);			\
-   (void) 0; })
+   obstack_ptr_grow_fast (__o, datum); })
 
 # define obstack_int_grow(OBSTACK,datum)				\
 __extension__								\
 ({ struct obstack *__o = (OBSTACK);					\
    if (__o->next_free + sizeof (int) > __o->chunk_limit)		\
      _obstack_newchunk (__o, sizeof (int));				\
-   *((int *)__o->next_free)++ = ((int)datum);				\
+   obstack_int_grow_fast (__o, datum); })
+
+# define obstack_ptr_grow_fast(OBSTACK,aptr)				\
+__extension__								\
+({ struct obstack *__o1 = (OBSTACK);					\
+   *(const void **) __o1->next_free = (aptr);				\
+   __o1->next_free += sizeof (const void *);				\
    (void) 0; })
 
-# define obstack_ptr_grow_fast(h,aptr) (*((void **) (h)->next_free)++ = (void *)aptr)
-# define obstack_int_grow_fast(h,aint) (*((int *) (h)->next_free)++ = (int) aint)
+# define obstack_int_grow_fast(OBSTACK,aint)				\
+__extension__								\
+({ struct obstack *__o1 = (OBSTACK);					\
+   *(int *) __o1->next_free = (aint);					\
+   __o1->next_free += sizeof (int);					\
+   (void) 0; })
 
 # define obstack_blank(OBSTACK,length)					\
 __extension__								\
@@ -443,7 +452,7 @@
    int __len = (length);						\
    if (__o->chunk_limit - __o->next_free < __len)			\
      _obstack_newchunk (__o, __len);					\
-   __o->next_free += __len;						\
+   obstack_blank_fast (__o, __len);					\
    (void) 0; })
 
 # define obstack_alloc(OBSTACK,length)					\
@@ -530,26 +539,29 @@
 # define obstack_1grow(h,datum)						\
 ( (((h)->next_free + 1 > (h)->chunk_limit)				\
    ? (_obstack_newchunk ((h), 1), 0) : 0),				\
-  (*((h)->next_free)++ = (datum)))
+  obstack_1grow_fast (h, datum))
 
 # define obstack_ptr_grow(h,datum)					\
 ( (((h)->next_free + sizeof (char *) > (h)->chunk_limit)		\
    ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0),		\
-  (*((char **) (((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *) datum)))
+  obstack_ptr_grow_fast (h, datum))
 
 # define obstack_int_grow(h,datum)					\
 ( (((h)->next_free + sizeof (int) > (h)->chunk_limit)			\
    ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0),			\
-  (*((int *) (((h)->next_free+=sizeof(int))-sizeof(int))) = ((int) datum)))
+  obstack_int_grow_fast (h, datum))
+
+# define obstack_ptr_grow_fast(h,aptr)					\
+  (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
 
-# define obstack_ptr_grow_fast(h,aptr) (*((char **) (h)->next_free)++ = (char *) aptr)
-# define obstack_int_grow_fast(h,aint) (*((int *) (h)->next_free)++ = (int) aint)
+# define obstack_int_grow_fast(h,aint)					\
+  (((int *) ((h)->next_free += sizeof (int)))[-1] = (aptr))
 
 # define obstack_blank(h,length)					\
 ( (h)->temp = (length),							\
   (((h)->chunk_limit - (h)->next_free < (h)->temp)			\
    ? (_obstack_newchunk ((h), (h)->temp), 0) : 0),			\
-  ((h)->next_free += (h)->temp))
+  obstack_blank_fast (h, (h)->temp))
 
 # define obstack_alloc(h,length)					\
  (obstack_blank ((h), (length)), obstack_finish ((h)))
--- changes.html.orig	2003-10-15 08:04:56.000000000 +0000
+++ changes.html	2003-10-20 09:57:17.000000000 +0000
@@ -76,6 +76,16 @@
 	a correct implementation of <code>#import</code> and
         <code>#pragma once</code>.
 	These two directives have therefore been un-deprecated.</li>
+    <li>The cast-as-lvalue extension has been removed for C++ and
+        deprecated for C and Objective-C.  In particular,
+        code like this:
+        <pre>
+        int i;
+        (char) i = 5;
+        </pre>
+        <p>is no longer accepted for C++ and will not be accepted for
+        C and Objective-C in a future version.</p></li>
+
   </ul>
 
 <h3>C++</h3>
@@ -212,14 +222,6 @@
 	<code>f</code>.  The default arguments for <code>g</code> must
 	be visible at the point where it is called.</p></li>
 
-    <li>The cast-as-lvalue extension has been removed.  In particular,
-        code like this:
-        <pre>
-        int i;
-        (char) i = 5;
-        </pre>
-        <p>is no longer accepted.</p></li>
-
     <li>The C++ ABI Section 3.3.3 specifications for the array
         construction routines <code>__cxa_vec_new2</code> and
         <code>__cxa_vec_new3</code> were changed to return

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]