Date: Sat, 10 Apr 2010 07:17:28 +1000 (EST) From: Peter Jeremy <peterjeremy@acm.org> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/145590: [patch] SIG_ATOMIC_{MIN, MAX} does not match sig_atomic_t on 64-bit archs Message-ID: <201004092117.o39LHSPm016637@server.vk2pj.dyndns.org> Resent-Message-ID: <201004092120.o39LK1Lu073606@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 145590 >Category: bin >Synopsis: [patch] SIG_ATOMIC_{MIN,MAX} does not match sig_atomic_t on 64-bit archs >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Apr 09 21:20:01 UTC 2010 >Closed-Date: >Last-Modified: >Originator: Peter Jeremy >Release: FreeBSD 8.0-STABLE amd64 >Organization: n/a >Environment: System: FreeBSD server.vk2pj.dyndns.org 8.0-STABLE FreeBSD 8.0-STABLE #3: Mon Apr 5 10:18:04 EST 2010 root@server.vk2pj.dyndns.org:/var/obj/usr/src/sys/server amd64 System: FreeBSD sb1500.vk2pj.dyndns.org 8.0-STABLE FreeBSD 8.0-STABLE #0: Sun Feb 14 19:09:44 EST 2010 root@sb1500.vk2pj.dyndns.org:/usr/obj/usr/src/sys/sb1500 sparc64 >Description: The SIG_ATOMIC_{MIN,MAX} macros in <inttypes.h> should reflect the minimum and maximum limits for sig_atomic_t. Currently in FreeBSD, SIG_ATOMIC_{MIN,MAX} are always defined as INT32_{MIN,MAX} but sig_atomic_t is defined as 'int' on i386, mips and powerpc and 'long' on amd64, arm, ia64, sparc64 and sun4v. This combination is incorrect on amd64, ia64, sparc64 and sun4v and potentially incorrect on arm (where 'long' appears to be able to be defined as either 32 or 64 bits). This causes at least some GNU configure scripts to report that stdint.h does not conform to C99. >How-To-Repeat: On amd64 and sparc64 (and presumably on ia64 and sun4v, though I can't test there): $ cd /usr/ports/archivers/gcpio && make configure will report: checking whether stdint.h conforms to C99... no The following code is a slightly cut-down version of the failing test script in the gcpio configure script: -------- 8-< ------- #define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */ #define __STDC_CONSTANT_MACROS 1 /* to make it work also in C++ mode */ #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ #include <stdint.h> #include <stddef.h> #include <signal.h> # include <stdio.h> # include <time.h> # include <wchar.h> #ifdef INT8_MAX int8_t a1 = INT8_MAX; int8_t a1min = INT8_MIN; #endif #ifdef INT16_MAX int16_t a2 = INT16_MAX; int16_t a2min = INT16_MIN; #endif #ifdef INT32_MAX int32_t a3 = INT32_MAX; int32_t a3min = INT32_MIN; #endif #ifdef INT64_MAX int64_t a4 = INT64_MAX; int64_t a4min = INT64_MIN; #endif #ifdef UINT8_MAX uint8_t b1 = UINT8_MAX; #else typedef int b1[(unsigned char) -1 != 255 ? 1 : -1]; #endif #ifdef UINT16_MAX uint16_t b2 = UINT16_MAX; #endif #ifdef UINT32_MAX uint32_t b3 = UINT32_MAX; #endif #ifdef UINT64_MAX uint64_t b4 = UINT64_MAX; #endif int_least8_t c1 = INT8_C (0x7f); int_least8_t c1max = INT_LEAST8_MAX; int_least8_t c1min = INT_LEAST8_MIN; int_least16_t c2 = INT16_C (0x7fff); int_least16_t c2max = INT_LEAST16_MAX; int_least16_t c2min = INT_LEAST16_MIN; int_least32_t c3 = INT32_C (0x7fffffff); int_least32_t c3max = INT_LEAST32_MAX; int_least32_t c3min = INT_LEAST32_MIN; int_least64_t c4 = INT64_C (0x7fffffffffffffff); int_least64_t c4max = INT_LEAST64_MAX; int_least64_t c4min = INT_LEAST64_MIN; uint_least8_t d1 = UINT8_C (0xff); uint_least8_t d1max = UINT_LEAST8_MAX; uint_least16_t d2 = UINT16_C (0xffff); uint_least16_t d2max = UINT_LEAST16_MAX; uint_least32_t d3 = UINT32_C (0xffffffff); uint_least32_t d3max = UINT_LEAST32_MAX; uint_least64_t d4 = UINT64_C (0xffffffffffffffff); uint_least64_t d4max = UINT_LEAST64_MAX; int_fast8_t e1 = INT_FAST8_MAX; int_fast8_t e1min = INT_FAST8_MIN; int_fast16_t e2 = INT_FAST16_MAX; int_fast16_t e2min = INT_FAST16_MIN; int_fast32_t e3 = INT_FAST32_MAX; int_fast32_t e3min = INT_FAST32_MIN; int_fast64_t e4 = INT_FAST64_MAX; int_fast64_t e4min = INT_FAST64_MIN; uint_fast8_t f1 = UINT_FAST8_MAX; uint_fast16_t f2 = UINT_FAST16_MAX; uint_fast32_t f3 = UINT_FAST32_MAX; uint_fast64_t f4 = UINT_FAST64_MAX; #ifdef INTPTR_MAX intptr_t g = INTPTR_MAX; intptr_t gmin = INTPTR_MIN; #endif #ifdef UINTPTR_MAX uintptr_t h = UINTPTR_MAX; #endif intmax_t i = INTMAX_MAX; uintmax_t j = UINTMAX_MAX; #include <limits.h> /* for CHAR_BIT */ #define TYPE_MINIMUM(t) ((t) ((t) 0 < (t) -1 ? (t) 0 : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))) #define TYPE_MAXIMUM(t) ((t) ((t) 0 < (t) -1 ? (t) -1 : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))) struct s { int check_PTRDIFF: PTRDIFF_MIN == TYPE_MINIMUM (ptrdiff_t) && PTRDIFF_MAX == TYPE_MAXIMUM (ptrdiff_t) ? 1 : -1; /* Detect bug in FreeBSD 6.0 / ia64. */ int check_SIG_ATOMIC: SIG_ATOMIC_MIN == TYPE_MINIMUM (sig_atomic_t) && SIG_ATOMIC_MAX == TYPE_MAXIMUM (sig_atomic_t) ? 1 : -1; int check_SIZE: SIZE_MAX == TYPE_MAXIMUM (size_t) ? 1 : -1; int check_WCHAR: WCHAR_MIN == TYPE_MINIMUM (wchar_t) && WCHAR_MAX == TYPE_MAXIMUM (wchar_t) ? 1 : -1; /* Detect bug in mingw. */ int check_WINT: WINT_MIN == TYPE_MINIMUM (wint_t) && WINT_MAX == TYPE_MAXIMUM (wint_t) ? 1 : -1; /* Detect bugs in glibc 2.4 and Solaris 10 stdint.h, among others. */ int check_UINT8_C: (-1 < UINT8_C (0)) == (-1 < (uint_least8_t) 0) ? 1 : -1; int check_UINT16_C: (-1 < UINT16_C (0)) == (-1 < (uint_least16_t) 0) ? 1 : -1; /* Detect bugs in OpenBSD 3.9 stdint.h. */ #ifdef UINT8_MAX int check_uint8: (uint8_t) -1 == UINT8_MAX ? 1 : -1; #endif #ifdef UINT16_MAX int check_uint16: (uint16_t) -1 == UINT16_MAX ? 1 : -1; #endif #ifdef UINT32_MAX int check_uint32: (uint32_t) -1 == UINT32_MAX ? 1 : -1; #endif #ifdef UINT64_MAX int check_uint64: (uint64_t) -1 == UINT64_MAX ? 1 : -1; #endif int check_uint_least8: (uint_least8_t) -1 == UINT_LEAST8_MAX ? 1 : -1; int check_uint_least16: (uint_least16_t) -1 == UINT_LEAST16_MAX ? 1 : -1; int check_uint_least32: (uint_least32_t) -1 == UINT_LEAST32_MAX ? 1 : -1; int check_uint_least64: (uint_least64_t) -1 == UINT_LEAST64_MAX ? 1 : -1; int check_uint_fast8: (uint_fast8_t) -1 == UINT_FAST8_MAX ? 1 : -1; int check_uint_fast16: (uint_fast16_t) -1 == UINT_FAST16_MAX ? 1 : -1; int check_uint_fast32: (uint_fast32_t) -1 == UINT_FAST32_MAX ? 1 : -1; int check_uint_fast64: (uint_fast64_t) -1 == UINT_FAST64_MAX ? 1 : -1; int check_uintptr: (uintptr_t) -1 == UINTPTR_MAX ? 1 : -1; int check_uintmax: (uintmax_t) -1 == UINTMAX_MAX ? 1 : -1; int check_size: (size_t) -1 == SIZE_MAX ? 1 : -1; }; int main () { ; return 0; } -------- 8-< ------- >Fix: The following patch converts SIG_ATOMIC_{MIN,MAX} to 64-bit on amd64, ia64, sparc64 and sun4v, and converts sig_atomic_t to 'int' on arm (avoiding confusion over the size of long). I have tested this fix against the above script on amd64 and sparc64. I have not tried a buildworld but nothing in the FreeBSD base system or kernel references the SIG_ATOMIC_{MIN,MAX} macros. One of the arm experts may be able to verify whether this is the appropriate fix for arm. The patch is relative to /usr/src/sys Index: amd64/include/_stdint.h =================================================================== RCS file: /usr/ncvs/src/sys/amd64/include/_stdint.h,v retrieving revision 1.3 diff -u -r1.3 _stdint.h --- amd64/include/_stdint.h 18 May 2004 16:04:56 -0000 1.3 +++ amd64/include/_stdint.h 9 Apr 2010 20:52:31 -0000 @@ -150,8 +150,8 @@ #define PTRDIFF_MAX INT64_MAX /* Limits of sig_atomic_t. */ -#define SIG_ATOMIC_MIN INT32_MIN -#define SIG_ATOMIC_MAX INT32_MAX +#define SIG_ATOMIC_MIN INT64_MIN +#define SIG_ATOMIC_MAX INT64_MAX /* Limit of size_t. */ #define SIZE_MAX UINT64_MAX Index: arm/include/signal.h =================================================================== RCS file: /usr/ncvs/src/sys/arm/include/signal.h,v retrieving revision 1.7 diff -u -r1.7 signal.h --- arm/include/signal.h 20 Aug 2005 16:44:40 -0000 1.7 +++ arm/include/signal.h 9 Apr 2010 20:52:31 -0000 @@ -37,7 +37,7 @@ #include <sys/cdefs.h> -typedef long sig_atomic_t; +typedef int sig_atomic_t; #if __BSD_VISIBLE Index: ia64/include/_stdint.h =================================================================== RCS file: /usr/ncvs/src/sys/ia64/include/_stdint.h,v retrieving revision 1.2 diff -u -r1.2 _stdint.h --- ia64/include/_stdint.h 18 May 2004 16:04:57 -0000 1.2 +++ ia64/include/_stdint.h 9 Apr 2010 20:52:31 -0000 @@ -150,8 +150,8 @@ #define PTRDIFF_MAX INT64_MAX /* Limits of sig_atomic_t. */ -#define SIG_ATOMIC_MIN INT32_MIN -#define SIG_ATOMIC_MAX INT32_MAX +#define SIG_ATOMIC_MIN INT64_MIN +#define SIG_ATOMIC_MAX INT64_MAX /* Limit of size_t. */ #define SIZE_MAX UINT64_MAX Index: sparc64/include/_stdint.h =================================================================== RCS file: /usr/ncvs/src/sys/sparc64/include/_stdint.h,v retrieving revision 1.2 diff -u -r1.2 _stdint.h --- sparc64/include/_stdint.h 18 May 2004 16:04:57 -0000 1.2 +++ sparc64/include/_stdint.h 9 Apr 2010 20:52:26 -0000 @@ -150,8 +150,8 @@ #define PTRDIFF_MAX INT64_MAX /* Limits of sig_atomic_t. */ -#define SIG_ATOMIC_MIN INT32_MIN -#define SIG_ATOMIC_MAX INT32_MAX +#define SIG_ATOMIC_MIN INT64_MIN +#define SIG_ATOMIC_MAX INT64_MAX /* Limit of size_t. */ #define SIZE_MAX UINT64_MAX Index: sun4v/include/_stdint.h =================================================================== RCS file: /usr/ncvs/src/sys/sun4v/include/_stdint.h,v retrieving revision 1.1 diff -u -r1.1 _stdint.h --- sun4v/include/_stdint.h 5 Oct 2006 06:14:25 -0000 1.1 +++ sun4v/include/_stdint.h 9 Apr 2010 20:52:31 -0000 @@ -150,8 +150,8 @@ #define PTRDIFF_MAX INT64_MAX /* Limits of sig_atomic_t. */ -#define SIG_ATOMIC_MIN INT32_MIN -#define SIG_ATOMIC_MAX INT32_MAX +#define SIG_ATOMIC_MIN INT64_MIN +#define SIG_ATOMIC_MAX INT64_MAX /* Limit of size_t. */ #define SIZE_MAX UINT64_MAX >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201004092117.o39LHSPm016637>