Skip site navigation (1)Skip section navigation (2)
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>