[PATCH] ctype.h (another try)
Ian Wienand
ianw@gelato.unsw.edu.au
Tue Mar 25 23:49:00 GMT 2003
Hello,
A previous patch
(http://sources.redhat.com/ml/libc-alpha/2003-03/msg00379.html) to
stop the type punning errors in this file with gcc 3.3 was shown to be
incorrect, but it is still annoying me. As I understand it, gcc warns
when you do
something i;
void *ptr = &i;
void **ptr2ptr = &ptr;
somthing **ptr2 = (somthing **)ptr2ptr <- warning
because if you dereference ptr2ptr it's really void *, but gcc (and
probably the developer) would assume it's a something * and hence you
are in danger of accessing the same memory as two different types,
which breaks the type based aliasing rules.
i think by using a union you are explictly specifying your punning, so
gcc can know what you are up to and take account accordingly.
-i
ianw@gelato.unsw.edu.au
http://www.gelato.unsw.edu.au
-------------- next part --------------
Index: include/ctype.h
===================================================================
RCS file: /cvs/glibc/libc/include/ctype.h,v
retrieving revision 1.7
diff -u -r1.7 ctype.h
--- include/ctype.h 18 Mar 2003 00:37:46 -0000 1.7
+++ include/ctype.h 23 Mar 2003 23:29:36 -0000
@@ -25,31 +25,46 @@
CTYPE_EXTERN_INLINE const uint16_t ** __attribute__ ((const))
__ctype_b_loc (void)
{
- const uint16_t **tablep =
- (const uint16_t **) __libc_tsd_address (CTYPE_B);
- if (__builtin_expect (*tablep == NULL, 0))
- *tablep = (const uint16_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_CLASS) + 128;
- return tablep;
+ /* __libc_tsd_address returns a void **, therefore dereferencing it
+ gives a void *. Thus if we just cast this return to a const
+ unit16_t **, upon dereferecing the compiler would think it was a
+ unit16_t *, when it was declared as a void *. Thus type based
+ aliasing will be broken. Use a union.
+ */
+ union {
+ const uint16_t **t;
+ void **p;
+ } tablep;
+ tablep.p = __libc_tsd_address (CTYPE_B);
+ if (__builtin_expect (*tablep.p == NULL, 0))
+ *tablep.t = (const uint16_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_CLASS) + 128;
+ return tablep.t;
}
CTYPE_EXTERN_INLINE const int32_t ** __attribute__ ((const))
__ctype_toupper_loc (void)
{
- const int32_t **tablep =
- (const int32_t **) __libc_tsd_address (CTYPE_TOUPPER);
- if (__builtin_expect (*tablep == NULL, 0))
- *tablep = ((int32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TOUPPER) + 128);
- return tablep;
+ union {
+ const int32_t **t;
+ void **p;
+ } tablep;
+ tablep.p = __libc_tsd_address (CTYPE_TOUPPER);
+ if (__builtin_expect (*tablep.p == NULL, 0))
+ *tablep.t = ((int32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TOUPPER) + 128);
+ return tablep.t;
}
CTYPE_EXTERN_INLINE const int32_t ** __attribute__ ((const))
__ctype_tolower_loc (void)
{
- const int32_t **tablep =
- (const int32_t **) __libc_tsd_address (CTYPE_TOLOWER);
- if (__builtin_expect (*tablep == NULL, 0))
- *tablep = ((int32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TOLOWER) + 128);
- return tablep;
+ union {
+ const int32_t **t;
+ void **p;
+ } tablep;
+ tablep.p = __libc_tsd_address (CTYPE_TOLOWER);
+ if (__builtin_expect (*tablep.p == NULL, 0))
+ *tablep.t = ((int32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TOLOWER) + 128);
+ return tablep.t;
}
# endif /* Not NOT_IN_libc. */
More information about the Libc-alpha
mailing list