diff options
author | Zack Weinberg <zackw@panix.com> | 2019-03-11 10:59:27 -0400 |
---|---|---|
committer | Zack Weinberg <zackw@panix.com> | 2019-03-13 09:39:43 -0400 |
commit | 711a322a235d4c8177713f11aa59156603b94aeb (patch) | |
tree | da372c772ef10860d5a70d788e23cab4bedaf866 /posix | |
parent | 7c6513082b787a7d36ab7d75720b48f8a216089c (diff) | |
download | glibc-711a322a235d4c8177713f11aa59156603b94aeb.tar glibc-711a322a235d4c8177713f11aa59156603b94aeb.tar.gz glibc-711a322a235d4c8177713f11aa59156603b94aeb.tar.bz2 glibc-711a322a235d4c8177713f11aa59156603b94aeb.zip |
Use a proper C tokenizer to implement the obsolete typedefs test.
The test for obsolete typedefs in installed headers was implemented
using grep, and could therefore get false positives on e.g. “ulong”
in a comment. It was also scanning all of the headers included by
our headers, and therefore testing headers we don’t control, e.g.
Linux kernel headers.
This patch splits the obsolete-typedef test from
scripts/check-installed-headers.sh to a separate program,
scripts/check-obsolete-constructs.py. Being implemented in Python,
it is feasible to make it tokenize C accurately enough to avoid false
positives on the contents of comments and strings. It also only
examines $(headers) in each subdirectory--all the headers we install,
but not any external dependencies of those headers. Headers whose
installed name starts with finclude/ are ignored, on the assumption
that they contain Fortran.
It is also feasible to make the new test understand the difference
between _defining_ the obsolete typedefs and _using_ the obsolete
typedefs, which means posix/{bits,sys}/types.h no longer need to be
exempted. This uncovered an actual bug in bits/types.h: __quad_t and
__u_quad_t were being used to define __S64_TYPE, __U64_TYPE,
__SQUAD_TYPE and __UQUAD_TYPE. These are changed to __int64_t and
__uint64_t respectively. This is a safe change, despite the comments
in bits/types.h claiming a difference between __quad_t and __int64_t,
because those comments are incorrect. In all current ABIs, both
__quad_t and __int64_t are ‘long’ when ‘long’ is a 64-bit type, and
‘long long’ when ‘long’ is a 32-bit type, and similarly for __u_quad_t
and __uint64_t. (Changing the types to be what the comments say they
are would be an ABI break, as it affects C++ name mangling.) This
patch includes a minimal change to make the comments not completely
wrong.
sys/types.h was defining the legacy BSD u_intN_t typedefs using a
construct that was not necessarily consistent with how the C99 uintN_t
typedefs are defined, and is also too complicated for the new script to
understand (it lexes C relatively accurately, but it does not attempt
to expand preprocessor macros, nor does it do any actual parsing).
This patch cuts all of that out and uses bits/types.h's __uintN_t typedefs
to define u_intN_t instead. This is verified to not change the ABI on
any supported architecture, via the c++-types test, which means u_intN_t
and uintN_t were, in fact, consistent on all supported architectures.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* scripts/check-obsolete-constructs.py: New test script.
* scripts/check-installed-headers.sh: Remove tests for
obsolete typedefs, superseded by check-obsolete-constructs.py.
* Rules: Run scripts/check-obsolete-constructs.py over $(headers)
as a special test. Update commentary.
* posix/bits/types.h (__SQUAD_TYPE, __S64_TYPE): Define as __int64_t.
(__UQUAD_TYPE, __U64_TYPE): Define as __uint64_t.
Update commentary.
* posix/sys/types.h (__u_intN_t): Remove.
(u_int8_t): Typedef using __uint8_t.
(u_int16_t): Typedef using __uint16_t.
(u_int32_t): Typedef using __uint32_t.
(u_int64_t): Typedef using __uint64_t.
Diffstat (limited to 'posix')
-rw-r--r-- | posix/bits/types.h | 10 | ||||
-rw-r--r-- | posix/sys/types.h | 33 |
2 files changed, 13 insertions, 30 deletions
diff --git a/posix/bits/types.h b/posix/bits/types.h index 27e065c3be..0de6c59bb4 100644 --- a/posix/bits/types.h +++ b/posix/bits/types.h @@ -87,7 +87,7 @@ __extension__ typedef unsigned long long int __uintmax_t; 32 -- "natural" 32-bit type (always int) 64 -- "natural" 64-bit type (long or long long) LONG32 -- 32-bit type, traditionally long - QUAD -- 64-bit type, always long long + QUAD -- 64-bit type, traditionally long long WORD -- natural type of __WORDSIZE bits (int or long) LONGWORD -- type of __WORDSIZE bits, traditionally long @@ -113,14 +113,14 @@ __extension__ typedef unsigned long long int __uintmax_t; #define __SLONGWORD_TYPE long int #define __ULONGWORD_TYPE unsigned long int #if __WORDSIZE == 32 -# define __SQUAD_TYPE __quad_t -# define __UQUAD_TYPE __u_quad_t +# define __SQUAD_TYPE __int64_t +# define __UQUAD_TYPE __uint64_t # define __SWORD_TYPE int # define __UWORD_TYPE unsigned int # define __SLONG32_TYPE long int # define __ULONG32_TYPE unsigned long int -# define __S64_TYPE __quad_t -# define __U64_TYPE __u_quad_t +# define __S64_TYPE __int64_t +# define __U64_TYPE __uint64_t /* We want __extension__ before typedef's that use nonstandard base types such as `long long' in C89 mode. */ # define __STD_TYPE __extension__ typedef diff --git a/posix/sys/types.h b/posix/sys/types.h index 27129c5c23..0e37b1ce6a 100644 --- a/posix/sys/types.h +++ b/posix/sys/types.h @@ -154,37 +154,20 @@ typedef unsigned int uint; #include <bits/stdint-intn.h> -#if !__GNUC_PREREQ (2, 7) - /* These were defined by ISO C without the first `_'. */ -typedef unsigned char u_int8_t; -typedef unsigned short int u_int16_t; -typedef unsigned int u_int32_t; -# if __WORDSIZE == 64 -typedef unsigned long int u_int64_t; -# else -__extension__ typedef unsigned long long int u_int64_t; -# endif - -typedef int register_t; - -#else - -/* For GCC 2.7 and later, we can use specific type-size attributes. */ -# define __u_intN_t(N, MODE) \ - typedef unsigned int u_int##N##_t __attribute__ ((__mode__ (MODE))) - -__u_intN_t (8, __QI__); -__u_intN_t (16, __HI__); -__u_intN_t (32, __SI__); -__u_intN_t (64, __DI__); +typedef __uint8_t u_int8_t; +typedef __uint16_t u_int16_t; +typedef __uint32_t u_int32_t; +typedef __uint64_t u_int64_t; +#if __GNUC_PREREQ (2, 7) typedef int register_t __attribute__ ((__mode__ (__word__))); - +#else +typedef int register_t; +#endif /* Some code from BIND tests this macro to see if the types above are defined. */ -#endif #define __BIT_TYPES_DEFINED__ 1 |