bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Re: stdint.h, C++ and __STDC_LIMIT_MACROS


From: Pedro Alves
Subject: [PATCH] Re: stdint.h, C++ and __STDC_LIMIT_MACROS
Date: Mon, 02 Nov 2015 15:36:25 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0

On 11/02/2015 11:03 AM, Pedro Alves wrote:
> On 11/02/2015 10:36 AM, Pedro Alves wrote:
> 
>> $ grep -rn gl_cv_header_working_stdint_h
>> config.cache:628:gl_cv_header_working_stdint_h=${gl_cv_header_working_stdint_h=no}
>> config.log:39493:gl_cv_header_working_stdint_h=no
>>
>> But, I don't get a replacement:
>>
>> $ find . -name stdint.h
>> $
>>
>> Any hints on where I should be looking next?
> 
> Hmm, I looked for how headers end up or not generated, and found out how that
> makes it to the Makefile, and noticed that the stdint.h generation in my 
> Makefile
> was commented out.  Turns out my Makefile was stale, even after having done (I
> believe) several config.status --recheck last night.  Today I
> re-ran "config.status", and lo, I get a replacement stdint.h.
> 
> Sorry for the false alarm.

Alright, and now with the stdint.h replacement, I tripped on
a real problem.  E.g.:

../../src/gdb/dcache.c: In function 'dcache_block* dcache_alloc(DCACHE*, 
CORE_ADDR)':
../../src/gdb/dcache.c:387:27: error: cast from 'dcache_block*' to 
'splay_tree_value {aka long unsigned int}' loses precision [-fpermissive]
        (splay_tree_value) db);
                           ^

splay_tree_value is a typedef for uintptr_t.  And gnulib's stdint.h
replacement typedef that to "unsigned long":

~~~
/* 7.18.1.4. Integer types capable of holding object pointers */

#undef intptr_t
#undef uintptr_t
typedef long int gl_intptr_t;
typedef unsigned long int gl_uintptr_t;
#define intptr_t gl_intptr_t
#define uintptr_t gl_uintptr_t
~~~

which is not appropriate for mingw/64-bit, which is LLP64.

Given that mingw's stdint.h is good enough if one defines
__STDC_CONSTANT_MACROS / __STDC_LIMIT_MACROS, seems like the best fix
would be to make it so that the only thing the gnulib replacement
does is define __STDC_..._MACROS and include_next mingw's stdint.h,
nothing else.  See patch below.  What do you think?

>From 1fb3ed739c8e03e2f1459b033b4fe57cfd562dd8 Mon Sep 17 00:00:00 2001
From: Pedro Alves <address@hidden>
Date: Mon, 2 Nov 2015 14:52:18 +0000
Subject: [PATCH] stdint: detect good enough pre-C++11 stdint.h in C++ mode

When gnulib is configured in C++ mode for a system with a working C99
implementation of stdint.h that predates C++11, gnulib ends up
substituing stdint.h anyway.  This works on most targets, but on e.g.,
64-bit MinGW, it doesn't, as gnulib's substitute assumes LP64, while
MinGW is LLP64:

~~~
/* 7.18.1.4. Integer types capable of holding object pointers */

#undef intptr_t
#undef uintptr_t
typedef long int gl_intptr_t;
typedef unsigned long int gl_uintptr_t;
#define intptr_t gl_intptr_t
#define uintptr_t gl_uintptr_t
~~~

Instead of trying to detect the right types, detect
good-enough-pre-C++11 stdint.h and in such case make the substitute
stdint.h just wrap the system's stdint.h with
__STDC_CONSTANT_MACROS/__STDC_LIMIT_MACROS defined.

        * lib/stdint.in.h: Skip defining replacement header contents if
        @HAVE_PRE_CXX11_STDINT_H@, indicating the system's stdint.h is
        good enough and just needs __STDC_CONSTANT_MACROS /
        __STDC_LIMIT_MACROS defined in C++.
        * m4/stdint.m4 (gl_STDINT_H): Always define __STDC_CONSTANT_MACROS
        / __STDC_LIMIT_MACROS while checking whether the system stdint.h
        is good.  If it is good, check whether it works without those
        macros defined.  Then if it doesn't work, generate a replacement
        header that just defines those macros and includes the system
        stdint.h.
        * modules/stdint (Makefile.am): Substitute
        @address@hidden
---
 lib/stdint.in.h |  4 +++-
 m4/stdint.m4    | 33 +++++++++++++++++++++++++++++++--
 modules/stdint  |  1 +
 3 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/lib/stdint.in.h b/lib/stdint.in.h
index f46bbf3..fecb5e1 100644
--- a/lib/stdint.in.h
+++ b/lib/stdint.in.h
@@ -76,7 +76,9 @@
 # @INCLUDE_NEXT@ @NEXT_STDINT_H@
 #endif
 
-#if ! defined address@hidden@_STDINT_H && ! defined 
_GL_JUST_INCLUDE_SYSTEM_STDINT_H
+#if (! defined address@hidden@_STDINT_H                        \
+     && ! (defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H    \
+          || @HAVE_PRE_CXX11_STDINT_H@))
 #define address@hidden@_STDINT_H
 
 /* <sys/types.h> defines some of the stdint.h types as well, on glibc,
diff --git a/m4/stdint.m4 b/m4/stdint.m4
index 4011a49..4b98596 100644
--- a/m4/stdint.m4
+++ b/m4/stdint.m4
@@ -1,4 +1,4 @@
-# stdint.m4 serial 43
+# stdint.m4 serial 44
 dnl Copyright (C) 2001-2015 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -70,6 +70,8 @@ AC_DEFUN_ONCE([gl_STDINT_H],
        AC_COMPILE_IFELSE([
          AC_LANG_PROGRAM([[
 #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */
+#define __STDC_CONSTANT_MACROS 1
+#define __STDC_LIMIT_MACROS 1
 #include <stdint.h>
 /* Dragonfly defines WCHAR_MIN, WCHAR_MAX only in <wchar.h>.  */
 #if !(defined WCHAR_MIN && defined WCHAR_MAX)
@@ -218,6 +220,8 @@ struct s {
           AC_RUN_IFELSE([
             AC_LANG_PROGRAM([[
 #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */
+#define __STDC_CONSTANT_MACROS 1
+#define __STDC_LIMIT_MACROS 1
 #include <stdint.h>
 ]
 gl_STDINT_INCLUDES
@@ -279,7 +283,30 @@ static const char *macro_values[] =
       ])
   fi
   if test "$gl_cv_header_working_stdint_h" = yes; then
-    STDINT_H=
+    dnl Now see whether the system <stdint.h> works without
+    dnl __STDC_CONSTANT_MACROS/__STDC_LIMIT_MACROS defined.
+    AC_CACHE_CHECK([whether stdint.h predates C++11],
+      [gl_cv_header_stdint_predates_cxx11_h],
+      [gl_cv_header_stdint_predates_cxx11_h=yes
+       AC_COMPILE_IFELSE([
+        AC_LANG_PROGRAM([[
+#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */
+#include <stdint.h>
+]
+gl_STDINT_INCLUDES
+[
+intmax_t im = INTMAX_MAX;
+int32_t i32 = INT32_C (0x7fffffff);
+         ]])],
+         [gl_cv_header_stdint_predates_cxx11_h=no])])
+
+    if test "$gl_cv_header_stdint_predates_cxx11_h" = yes; then
+      HAVE_PRE_CXX11_STDINT_H=1
+      STDINT_H=stdint.h
+    else
+      HAVE_PRE_CXX11_STDINT_H=0
+      STDINT_H=
+    fi
   else
     dnl Check for <sys/inttypes.h>, and for
     dnl <sys/bitypes.h> (used in Linux libc4 >= 4.6.7 and libc5).
@@ -299,7 +326,9 @@ static const char *macro_values[] =
 
     gl_STDINT_TYPE_PROPERTIES
     STDINT_H=stdint.h
+    HAVE_PRE_CXX11_STDINT_H=0
   fi
+  AC_SUBST([HAVE_PRE_CXX11_STDINT_H])
   AC_SUBST([STDINT_H])
   AM_CONDITIONAL([GL_GENERATE_STDINT_H], [test -n "$STDINT_H"])
 ])
diff --git a/modules/stdint b/modules/stdint
index 62a5797..094f959 100644
--- a/modules/stdint
+++ b/modules/stdint
@@ -55,6 +55,7 @@ stdint.h: stdint.in.h $(top_builddir)/config.status
              -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \
              -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \
              -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \
+             -e 's/@''HAVE_PRE_CXX11_STDINT_H''@/$(HAVE_PRE_CXX11_STDINT_H)/g' 
\
              < $(srcdir)/stdint.in.h; \
        } > address@hidden && \
        mv address@hidden $@
-- 
1.9.3





reply via email to

[Prev in Thread] Current Thread [Next in Thread]