changeset 9473:8c3f82d802ec

Don't insist on 'long long int' support in the preprocessor. It breaks too many things. For example, PRIdMAX still uses a 'long long int' format with the latest Sun compiler, even though HAVE_LONG_LONG_INT isn't defined due to that compiler's preprocessor problem. This causes the latest coreutils to dump core on Solaris 10 sparc with the Sun C compiler. Instead, fix the 2007-10-16 problem in a different way, by evaluating the troublesome expressions at configure-time, not at #if-time. * m4/longlong.m4 (_AC_TYPE_LONG_LONG_SNIPPET): Don't test the preprocessor. * m4/inttypes.m4 (gl_INTTYPES_H): Move the #if checks into compile-time C checks, done at 'configure'-time. (gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION): New macro. * modules/inttypes (Makefile): Substitute the new symbols that gl_INTTYPES_H now generates. * lib/inttypes.in.h: Don't use constants wider than 'long' in #if.
author Paul Eggert <eggert@cs.ucla.edu>
date Mon, 12 Nov 2007 15:50:17 -0800
parents 7e73893994b7
children 6266ba33b229
files ChangeLog lib/inttypes.in.h m4/inttypes.m4 m4/longlong.m4 modules/inttypes
diffstat 5 files changed, 104 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2007-11-12  Paul Eggert  <eggert@cs.ucla.edu>
+
+	Don't insist on 'long long int' support in the preprocessor.  It
+	breaks too many things.  For example, PRIdMAX still uses a 'long
+	long int' format with the latest Sun compiler, even though
+	HAVE_LONG_LONG_INT isn't defined due to that compiler's
+	preprocessor problem.  This causes the latest coreutils to dump
+	core on Solaris 10 sparc with the Sun C compiler.
+	Instead, fix the 2007-10-16 problem in a different way, by evaluating
+	the troublesome expressions at configure-time, not at #if-time.
+	* m4/longlong.m4 (_AC_TYPE_LONG_LONG_SNIPPET): Don't test the
+	preprocessor.
+	* m4/inttypes.m4 (gl_INTTYPES_H): Move the #if checks into
+	compile-time C checks, done at 'configure'-time.
+	(gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION): New macro.
+	* modules/inttypes (Makefile): Substitute the new symbols that
+	gl_INTTYPES_H now generates.
+	* lib/inttypes.in.h: Don't use constants wider than 'long' in #if.
+
 2007-11-12  Bruno Haible  <bruno@clisp.org>
 
 	Tests for Unicode character classification functions.
--- a/lib/inttypes.in.h
+++ b/lib/inttypes.in.h
@@ -165,7 +165,7 @@
 #  endif
 # endif
 # ifdef INT64_MAX
-#  if INT64_MAX == LONG_MAX
+#  if @INT64_MAX_EQ_LONG_MAX@
 #   define _PRI64_PREFIX "l"
 #  elif defined _MSC_VER || defined __MINGW32__
 #   define _PRI64_PREFIX "I64"
@@ -182,7 +182,7 @@
 #  endif
 # endif
 # ifdef UINT64_MAX
-#  if UINT64_MAX == ULONG_MAX
+#  if @UINT64_MAX_EQ_ULONG_MAX@
 #   define _PRIu64_PREFIX "l"
 #  elif defined _MSC_VER || defined __MINGW32__
 #   define _PRIu64_PREFIX "I64"
@@ -483,7 +483,7 @@
 
 # if !defined PRIdMAX || @PRI_MACROS_BROKEN@
 #  undef PRIdMAX
-#  if INTMAX_MAX > INT32_MAX
+#  if @INT32_MAX_LT_INTMAX_MAX@
 #   define PRIdMAX PRId64
 #  else
 #   define PRIdMAX "ld"
@@ -491,7 +491,7 @@
 # endif
 # if !defined PRIiMAX || @PRI_MACROS_BROKEN@
 #  undef PRIiMAX
-#  if INTMAX_MAX > INT32_MAX
+#  if @INT32_MAX_LT_INTMAX_MAX@
 #   define PRIiMAX PRIi64
 #  else
 #   define PRIiMAX "li"
@@ -499,7 +499,7 @@
 # endif
 # if !defined PRIoMAX || @PRI_MACROS_BROKEN@
 #  undef PRIoMAX
-#  if UINTMAX_MAX > UINT32_MAX
+#  if @UINT32_MAX_LT_UINTMAX_MAX@
 #   define PRIoMAX PRIo64
 #  else
 #   define PRIoMAX "lo"
@@ -507,7 +507,7 @@
 # endif
 # if !defined PRIuMAX || @PRI_MACROS_BROKEN@
 #  undef PRIuMAX
-#  if UINTMAX_MAX > UINT32_MAX
+#  if @UINT32_MAX_LT_UINTMAX_MAX@
 #   define PRIuMAX PRIu64
 #  else
 #   define PRIuMAX "lu"
@@ -515,7 +515,7 @@
 # endif
 # if !defined PRIxMAX || @PRI_MACROS_BROKEN@
 #  undef PRIxMAX
-#  if UINTMAX_MAX > UINT32_MAX
+#  if @UINT32_MAX_LT_UINTMAX_MAX@
 #   define PRIxMAX PRIx64
 #  else
 #   define PRIxMAX "lx"
@@ -523,7 +523,7 @@
 # endif
 # if !defined PRIXMAX || @PRI_MACROS_BROKEN@
 #  undef PRIXMAX
-#  if UINTMAX_MAX > UINT32_MAX
+#  if @UINT32_MAX_LT_UINTMAX_MAX@
 #   define PRIXMAX PRIX64
 #  else
 #   define PRIXMAX "lX"
@@ -658,7 +658,7 @@
 #  endif
 # endif
 # ifdef INT64_MAX
-#  if INT64_MAX == LONG_MAX
+#  if @INT64_MAX_EQ_LONG_MAX@
 #   define _SCN64_PREFIX "l"
 #  elif defined _MSC_VER || defined __MINGW32__
 #   define _SCN64_PREFIX "I64"
@@ -675,7 +675,7 @@
 #  endif
 # endif
 # ifdef UINT64_MAX
-#  if UINT64_MAX == ULONG_MAX
+#  if @UINT64_MAX_EQ_ULONG_MAX@
 #   define _SCNu64_PREFIX "l"
 #  elif defined _MSC_VER || defined __MINGW32__
 #   define _SCNu64_PREFIX "I64"
@@ -958,7 +958,7 @@
 
 # if !defined SCNdMAX || @PRI_MACROS_BROKEN@
 #  undef SCNdMAX
-#  if INTMAX_MAX > INT32_MAX
+#  if @INT32_MAX_LT_INTMAX_MAX@
 #   define SCNdMAX SCNd64
 #  else
 #   define SCNdMAX "ld"
@@ -966,7 +966,7 @@
 # endif
 # if !defined SCNiMAX || @PRI_MACROS_BROKEN@
 #  undef SCNiMAX
-#  if INTMAX_MAX > INT32_MAX
+#  if @INT32_MAX_LT_INTMAX_MAX@
 #   define SCNiMAX SCNi64
 #  else
 #   define SCNiMAX "li"
@@ -974,7 +974,7 @@
 # endif
 # if !defined SCNoMAX || @PRI_MACROS_BROKEN@
 #  undef SCNoMAX
-#  if UINTMAX_MAX > UINT32_MAX
+#  if @UINT32_MAX_LT_UINTMAX_MAX@
 #   define SCNoMAX SCNo64
 #  else
 #   define SCNoMAX "lo"
@@ -982,7 +982,7 @@
 # endif
 # if !defined SCNuMAX || @PRI_MACROS_BROKEN@
 #  undef SCNuMAX
-#  if UINTMAX_MAX > UINT32_MAX
+#  if @UINT32_MAX_LT_UINTMAX_MAX@
 #   define SCNuMAX SCNu64
 #  else
 #   define SCNuMAX "lu"
@@ -990,7 +990,7 @@
 # endif
 # if !defined SCNxMAX || @PRI_MACROS_BROKEN@
 #  undef SCNxMAX
-#  if UINTMAX_MAX > UINT32_MAX
+#  if @UINT32_MAX_LT_UINTMAX_MAX@
 #   define SCNxMAX SCNx64
 #  else
 #   define SCNxMAX "lx"
--- a/m4/inttypes.m4
+++ b/m4/inttypes.m4
@@ -207,11 +207,73 @@
       HAVE_DECL_STRTOUMAX=0
     fi
 
+    gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION(
+      [INT32_MAX_LT_INTMAX_MAX],
+      [defined INT32_MAX && defined INTMAX_MAX],
+      [INT32_MAX < INTMAX_MAX],
+      [sizeof (int) < sizeof (long long int)])
+    gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION(
+      [INT64_MAX_EQ_LONG_MAX],
+      [defined INT64_MAX],
+      [INT64_MAX == LONG_MAX],
+      [sizeof (long long int) == sizeof (long int)])
+    gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION(
+      [UINT32_MAX_LT_UINTMAX_MAX],
+      [defined UINT32_MAX && defined UINTMAX_MAX],
+      [UINT32_MAX < UINTMAX_MAX],
+      [sizeof (unsigned int) < sizeof (unsigned long long int)])
+    gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION(
+      [UINT64_MAX_EQ_ULONG_MAX],
+      [defined UINT64_MAX],
+      [UINT64_MAX == ULONG_MAX],
+      [sizeof (unsigned long long int) == sizeof (unsigned long int)])
+
     INTTYPES_H='inttypes.h'
   fi
   AC_SUBST(INTTYPES_H)
 ])
 
+# Define the symbol $1 to be 1 if the condition is true, 0 otherwise.
+# If $2 is true, the condition is $3; otherwise if long long int is supported
+# approximate the condition with $4; otherwise, assume the condition is false.
+# The condition should work on all C99 platforms; the approximations should be
+# good enough to work on all practical pre-C99 platforms.
+# $2 is evaluated by the C preprocessor, $3 and $4 as compile-time constants.
+AC_DEFUN([gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION],
+[
+  AC_CACHE_CHECK([whether $3],
+    [gl_cv_test_$1],
+    [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM(
+	  [[/* Work also in C++ mode.  */
+	    #define __STDC_LIMIT_MACROS 1
+
+	    /* Work if build is not clean.  */
+	    #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H
+
+	    #include <limits.h>
+	    #if HAVE_STDINT_H
+	     #include <stdint.h>
+	    #endif
+
+	    #if $2
+	     #define CONDITION ($3)
+	    #elif HAVE_LONG_LONG_INT
+	     #define CONDITION ($4)
+	    #else
+	     #define CONDITION 0
+	    #endif
+	    int test[CONDITION ? 1 : -1];]])],
+       [gl_cv_test_$1=yes],
+       [gl_cv_test_$1=no])])
+  if test $gl_cv_test_$1 = yes; then
+    $1=1;
+  else
+    $1=0;
+  fi
+  AC_SUBST([$1])
+])
+
 AC_DEFUN([gl_INTTYPES_MODULE_INDICATOR],
 [
   dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
--- a/m4/longlong.m4
+++ b/m4/longlong.m4
@@ -82,13 +82,10 @@
 AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET],
 [
   AC_LANG_PROGRAM(
-    [[/* Test preprocessor.  */
-      #if ! (-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
-        error in preprocessor;
-      #endif
-      #if ! (18446744073709551615ULL <= -1ull)
-        error in preprocessor;
-      #endif
+    [[/* For now, do not test the preprocessor; as of 2007 there are too many
+	 implementations with broken preprocessors.  Perhaps this can
+	 be revisited in 2012.  In the meantime, code should not expect
+	 #if to work with literals wider than 32 bits.  */
       /* Test literals.  */
       long long int ll = 9223372036854775807ll;
       long long int nll = -9223372036854775807LL;
--- a/modules/inttypes
+++ b/modules/inttypes
@@ -37,6 +37,10 @@
 	      -e 's/@''HAVE_DECL_IMAXDIV''@/$(HAVE_DECL_IMAXDIV)/g' \
 	      -e 's/@''HAVE_DECL_STRTOIMAX''@/$(HAVE_DECL_STRTOIMAX)/g' \
 	      -e 's/@''HAVE_DECL_STRTOUMAX''@/$(HAVE_DECL_STRTOUMAX)/g' \
+	      -e 's/@''INT32_MAX_LT_INTMAX_MAX''@/$(INT32_MAX_LT_INTMAX_MAX)/g' \
+	      -e 's/@''INT64_MAX_EQ_LONG_MAX''@/$(INT64_MAX_EQ_LONG_MAX)/g' \
+	      -e 's/@''UINT32_MAX_LT_UINTMAX_MAX''@/$(UINT32_MAX_LT_UINTMAX_MAX)/g' \
+	      -e 's/@''UINT64_MAX_EQ_ULONG_MAX''@/$(UINT64_MAX_EQ_ULONG_MAX)/g' \
 	      -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \
 	      < $(srcdir)/inttypes.in.h; \
 	} > $@-t