This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix <stdint.h> bugs


newlib's <stdint.h> has a series of failures to conform to C99.  This
patch fixes them; in some cases it uses macros that are proposed for
GCC 4.5 with my patch
<http://gcc.gnu.org/ml/gcc-patches/2008-11/msg00305.html> to get
correct values and types in all cases with new enough compilers,
falling back where possible to definitions as good as possible for
earlier compilers.

* The limits for [u]int32_t and [u]int_least32_t were defined to "int"
  / "unsigned int" values even when newlib generally prefers "long" /
  "unsigned long" for those types when both are the same width.

* The limits for the "fast" types did not agree with the logic
  generally preferring "int" for those types.

* Limits of intmax_t and uintmax_t were not defined.

* SIZE_MAX and the limits of ptrdiff_t were often of the wrong types;
  there's a lot of variation between targets on whether these types
  are "unsigned long" and "long", or "unsigned int" and "int", where
  those are the same width.

* Limits of wchar_t and wint_t were not defined.

* UINT8_C and UINT16_C wrongly expanded to unsigned values.  If the
  types uint_least8_t and uint_least16_t are narrower than int, they
  promote to signed int, and so these macros should expand to signed
  values.  (Note there were corrections to C99 in this area in TC1,
  and further corrections to the <stdint.h> specification in both TC2
  and TC3.)

OK to commit?

2008-11-28  Joseph Myers  <joseph@codesourcery.com>

	* libc/include/stdint.h (INT32_MIN, INT32_MAX, UINT32_MAX,
	INT_LEAST32_MIN, INT_LEAST32_MAX, UINT_LEAST32_MAX): Define to
	constants with "long" types where appropriate.
	(INT_FAST8_MIN, INT_FAST8_MAX, UINT_FAST8_MAX, INT_FAST16_MIN,
	INT_FAST16_MAX, UINT_FAST16_MAX, INT_FAST32_MIN, INT_FAST32_MAX,
	UINT_FAST32_MAX, INT_FAST64_MIN, INT_FAST64_MAX, UINT_FAST64_MAX):
	Correct to match logic for defining corresponding types.
	(INTMAX_MAX, INTMAX_MIN, UINTMAX_MAX): Define.
	(SIZE_MAX): Define using __SIZE_MAX__ if available.
	(PTRDIFF_MAX): Define using __PTRDIFF_MAX__ if available.
	(PTRDIFF_MIN): Define in terms of PTRDIFF_MAX.
	(WCHAR_MAX, WCHAR_MIN, WINT_MAX, WINT_MIN): Define.
	(UINT8_C, UINT16_C): Define to give signed values if corresponding
	types would promote to int.

Index: newlib/libc/include/stdint.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/include/stdint.h,v
retrieving revision 1.11
diff -u -r1.11 stdint.h
--- newlib/libc/include/stdint.h	2 May 2008 14:52:55 -0000	1.11
+++ newlib/libc/include/stdint.h	6 Nov 2008 22:07:56 -0000
@@ -6,10 +6,6 @@
  * is freely granted, provided that this notice is preserved.
  */
 
-/*
- * @todo - Add support for wint_t types.
- */
-
 #ifndef _STDINT_H
 #define _STDINT_H
 
@@ -286,15 +282,27 @@
 #endif
 
 #if __int32_t_defined
+#if __have_long32
+#define INT32_MIN 	 (-2147483647L-1)
+#define INT32_MAX 	 2147483647L
+#define UINT32_MAX       4294967295UL
+#else
 #define INT32_MIN 	 (-2147483647-1)
 #define INT32_MAX 	 2147483647
 #define UINT32_MAX       4294967295U
 #endif
+#endif
 
 #if __int_least32_t_defined
+#if __have_long32
+#define INT_LEAST32_MIN  (-2147483647L-1)
+#define INT_LEAST32_MAX  2147483647L
+#define UINT_LEAST32_MAX 4294967295UL
+#else
 #define INT_LEAST32_MIN  (-2147483647-1)
 #define INT_LEAST32_MAX  2147483647
 #define UINT_LEAST32_MAX 4294967295U
+#endif
 #else
 #error required type int_least32_t missing
 #endif
@@ -324,46 +332,121 @@
 #endif
 
 #if __int_fast8_t_defined
-#define INT_FAST8_MIN	INT8_MIN
-#define INT_FAST8_MAX	INT8_MAX
-#define UINT_FAST8_MAX	UINT8_MAX
+#if __STDINT_EXP(INT_MAX) >= 0x7f
+#define INT_FAST8_MIN	(-__STDINT_EXP(INT_MAX)-1)
+#define INT_FAST8_MAX	__STDINT_EXP(INT_MAX)
+#define UINT_FAST8_MAX	(__STDINT_EXP(INT_MAX)*2U+1U)
+#else
+#define INT_FAST8_MIN	INT_LEAST8_MIN
+#define INT_FAST8_MAX	INT_LEAST8_MAX
+#define UINT_FAST8_MAX	UINT_LEAST8_MAX
+#endif
 #endif
 
 #if __int_fast16_t_defined
-#define INT_FAST16_MIN	INT16_MIN
-#define INT_FAST16_MAX	INT16_MAX
-#define UINT_FAST16_MAX	UINT16_MAX
+#if __STDINT_EXP(INT_MAX) >= 0x7fff
+#define INT_FAST16_MIN	(-__STDINT_EXP(INT_MAX)-1)
+#define INT_FAST16_MAX	__STDINT_EXP(INT_MAX)
+#define UINT_FAST16_MAX	(__STDINT_EXP(INT_MAX)*2U+1U)
+#else
+#define INT_FAST16_MIN	INT_LEAST16_MIN
+#define INT_FAST16_MAX	INT_LEAST16_MAX
+#define UINT_FAST16_MAX	UINT_LEAST16_MAX
+#endif
 #endif
 
 #if __int_fast32_t_defined
-#define INT_FAST32_MIN	INT32_MIN
-#define INT_FAST32_MAX	INT32_MAX
-#define UINT_FAST32_MAX	UINT32_MAX
+#if __STDINT_EXP(INT_MAX) >= 0x7fffffff
+#define INT_FAST32_MIN	(-__STDINT_EXP(INT_MAX)-1)
+#define INT_FAST32_MAX	__STDINT_EXP(INT_MAX)
+#define UINT_FAST32_MAX	(__STDINT_EXP(INT_MAX)*2U+1U)
+#else
+#define INT_FAST32_MIN	INT_LEAST32_MIN
+#define INT_FAST32_MAX	INT_LEAST32_MAX
+#define UINT_FAST32_MAX	UINT_LEAST32_MAX
+#endif
 #endif
 
 #if __int_fast64_t_defined
-#define INT_FAST64_MIN	INT64_MIN
-#define INT_FAST64_MAX	INT64_MAX
-#define UINT_FAST64_MAX	UINT64_MAX
+#if __STDINT_EXP(INT_MAX) > 0x7fffffff
+#define INT_FAST64_MIN	(-__STDINT_EXP(INT_MAX)-1)
+#define INT_FAST64_MAX	__STDINT_EXP(INT_MAX)
+#define UINT_FAST64_MAX	(__STDINT_EXP(INT_MAX)*2U+1U)
+#else
+#define INT_FAST64_MIN	INT_LEAST64_MIN
+#define INT_FAST64_MAX	INT_LEAST64_MAX
+#define UINT_FAST64_MAX	UINT_LEAST64_MAX
+#endif
+#endif
+
+#ifdef __INTMAX_MAX__
+#define INTMAX_MAX __INTMAX_MAX__
+#define INTMAX_MIN (-INTMAX_MAX - 1)
+#elif defined(__INTMAX_TYPE__)
+/* All relevant GCC versions prefer long to long long for intmax_t.  */
+#define INTMAX_MAX INT64_MAX
+#define INTMAX_MIN INT64_MIN
+#endif
+
+#ifdef __UINTMAX_MAX__
+#define UINTMAX_MAX __UINTMAX_MAX__
+#elif defined(__UINTMAX_TYPE__)
+/* All relevant GCC versions prefer long to long long for intmax_t.  */
+#define UINTMAX_MAX UINT64_MAX
 #endif
 
 /* This must match size_t in stddef.h, currently long unsigned int */
+#ifdef __SIZE_MAX__
+#define SIZE_MAX __SIZE_MAX__
+#else
 #define SIZE_MAX (__STDINT_EXP(LONG_MAX) * 2UL + 1)
+#endif
 
 /* This must match sig_atomic_t in <signal.h> (currently int) */
 #define SIG_ATOMIC_MIN (-__STDINT_EXP(INT_MAX) - 1)
 #define SIG_ATOMIC_MAX __STDINT_EXP(INT_MAX)
 
 /* This must match ptrdiff_t  in <stddef.h> (currently long int) */
-#define PTRDIFF_MIN (-__STDINT_EXP(LONG_MAX) - 1L)
+#ifdef __PTRDIFF_MAX__
+#define PTRDIFF_MAX __PTRDIFF_MAX__
+#else
 #define PTRDIFF_MAX __STDINT_EXP(LONG_MAX)
+#endif
+#define PTRDIFF_MIN (-PTRDIFF_MAX - 1)
+
+#ifdef __WCHAR_MAX__
+#define WCHAR_MAX __WCHAR_MAX__
+#endif
+#ifdef __WCHAR_MIN__
+#define WCHAR_MIN __WCHAR_MIN__
+#endif
+
+/* wint_t is unsigned int on almost all GCC targets.  */
+#ifdef __WINT_MAX__
+#define WINT_MAX __WINT_MAX__
+#else
+#define WINT_MAX (__STDINT_EXP(INT_MAX) * 2U + 1U)
+#endif
+#ifdef __WINT_MIN__
+#define WINT_MIN __WINT_MIN__
+#else
+#define WINT_MIN 0U
+#endif
 
 /** Macros for minimum-width integer constant expressions */
 #define INT8_C(x)	x
+#if __STDINT_EXP(INT_MAX) > 0x7f
+#define UINT8_C(x)	x
+#else
 #define UINT8_C(x)	x##U
+#endif
 
 #define INT16_C(x)	x
+#if __STDINT_EXP(INT_MAX) > 0x7fff
+#define UINT16_C(x)	x
+#else
 #define UINT16_C(x)	x##U
+#endif
 
 #if __have_long32
 #define INT32_C(x)	x##L

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]