This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
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