changeset 37538:3e5b13c36d70

stdio: fix use of PRIdMAX on modern mingw Commit cf88e56ab broke the use of PRIdMAX and friends on modern mingw64 installations. Basically, when requesting _USE_MINGW_ANSI_STDIO, not only does mingw turn on support for %lld, it also rewrites <inttypes.h> to provide PRIdMAX as "lld" instead of "I64d" (but only when <stdio.h> is also included). But if a user is NOT using the gnulib printf module, gnulib's <stdio.h> was still giving printf() the system printf attribute, which causes the compiler to then complain about an unknown %lld specifier, even though we know we don't need to use the non-standard %I64d. So this patch adds a configure-time probe that should work with older gcc (which does not differentiate between printf flavors) and older mingw (where _USE_MINGW_ANSI_STDIO has no impact on behavior), while fixing the mismatch in flavors on modern systems. * m4/stdio_h.m4 (gl_STDIO_H): Probe for printf flavor via inttypes. * lib/stdio.in.h (_GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM): Use result to work with modern mingw. Signed-off-by: Eric Blake <eblake@redhat.com>
author Eric Blake <eblake@redhat.com>
date Mon, 05 Jan 2015 14:08:27 -0700
parents 10c7c458ab22
children f705c8bf7838
files ChangeLog lib/stdio.in.h m4/stdio_h.m4
diffstat 3 files changed, 32 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Dec 15 17:44:22 2014 +0000
+++ b/ChangeLog	Mon Jan 05 14:08:27 2015 -0700
@@ -1,3 +1,10 @@
+2015-01-05  Eric Blake  <eblake@redhat.com>
+
+	stdio: fix use of PRIdMAX on modern mingw
+	* m4/stdio_h.m4 (gl_STDIO_H): Probe for printf flavor via inttypes.
+	* lib/stdio.in.h (_GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM): Use result
+	to work with modern mingw.
+
 2015-01-05  Daniel P. Berrange  <berrange@redhat.com>  (tiny change)
 
 	pthread: detect git mingw builds with only partial pollution
--- a/lib/stdio.in.h	Mon Dec 15 17:44:22 2014 +0000
+++ b/lib/stdio.in.h	Mon Jan 05 14:08:27 2015 -0700
@@ -84,8 +84,13 @@
    except that it indicates to GCC that the supported format string directives
    are the ones of the system printf(), rather than the ones standardized by
    ISO C99 and POSIX.  */
-#define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \
+#if GNULIB_PRINTF_ATTRIBUTE_FLAVOR_GNU
+# define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \
+  _GL_ATTRIBUTE_FORMAT_PRINTF (formatstring_parameter, first_argument)
+#else
+# define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \
   _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter, first_argument))
+#endif
 
 /* _GL_ATTRIBUTE_FORMAT_SCANF
    indicates to GCC that the function takes a format string and arguments,
--- a/m4/stdio_h.m4	Mon Dec 15 17:44:22 2014 +0000
+++ b/m4/stdio_h.m4	Mon Jan 05 14:08:27 2015 -0700
@@ -1,4 +1,4 @@
-# stdio_h.m4 serial 43
+# stdio_h.m4 serial 44
 dnl Copyright (C) 2007-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,
@@ -12,6 +12,24 @@
   AC_REQUIRE([gl_STDIO_H_DEFAULTS])
   gl_NEXT_HEADERS([stdio.h])
 
+  dnl Determine whether __USE_MINGW_ANSI_STDIO makes printf and
+  dnl inttypes.h behave like gnu instead of system; we must give our
+  dnl printf wrapper the right attribute to match.
+  AC_CACHE_CHECK([whether inttypes macros match system or gnu printf],
+    [gl_cv_func_printf_attribute_flavor],
+    [AC_EGREP_CPP([findme .(ll|j)d. findme],
+      [#define __STDC_FORMAT_MACROS 1
+       #include <stdio.h>
+       #include <inttypes.h>
+       findme PRIdMAX findme
+      ], [gl_cv_func_printf_attribute_flavor=gnu],
+      [gl_cv_func_printf_attribute_flavor=system])])
+  if test "$gl_cv_func_printf_attribute_flavor" = gnu; then
+    AC_DEFINE([GNULIB_PRINTF_ATTRIBUTE_FLAVOR_GNU], [1],
+      [Define to 1 if printf and friends should be labeled with
+       attribute "__gnu_printf__" instead of "__printf__"])
+  fi
+
   dnl No need to create extra modules for these functions. Everyone who uses
   dnl <stdio.h> likely needs them.
   GNULIB_FSCANF=1