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. */