Eric Blake wrote: > We could also check at configure time for AC_CHECK_SIZEOF([mode_t]), then > use the preprocessor to skip the unneeded branch altogether using the > appropriate macro from config.h.
Yes. Paul Eggert tried to avoid configure-time checks that could also be done at compile-time. But at this point we are getting GCC warnings repeatedly, at the same spot. A single AC_TRY_COMPILE will be quicker than AC_CHECK_SIZEOF. I propose the following patch. Jim, objections? 2009-05-21 Bruno Haible <br...@clisp.org> Simplify use of mode_t varargs. * lib/open.c (open): Use PROMOTED_MODE_T instead of a conditional that uses 'mode_t' or 'int'. * lib/openat.c (openat): Likewise. * lib/open-safer.c (open_safer): Likewise. * m4/mode_t.m4: New file. * m4/open.m4 (gl_PREREQ_OPEN): Require gl_PROMOTED_TYPE_MODE_T. * m4/openat.m4 (gl_PREREQ_OPENAT): Likewise. * m4/fcntl-safer.m4 (gl_FCNTL_SAFER): Likewise. * modules/open (Files): Add m4/mode_t.m4. * modules/openat (Files): Likewise. * modules/fcntl-safer (Files): Likewise. Suggested by Eric Blake. ================================ m4/mode_t.m4 ================================ # mode_t.m4 serial 1 dnl Copyright (C) 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. # For using mode_t, it's sufficient to use AC_TYPE_MODE_T and # include <sys/types.h>. # Define PROMOTED_MODE_T to the type that is the result of "default argument # promotion" (ISO C 6.5.2.2.(6)) of the type mode_t. AC_DEFUN([gl_PROMOTED_TYPE_MODE_T], [ AC_REQUIRE([AC_TYPE_MODE_T]) AC_CACHE_CHECK([for promoted mode_t type], [gl_cv_promoted_mode_t], [ dnl Assume mode_t promotes to 'int' if and only if it is smaller than 'int', dnl and to itself otherwise. This assumption is not guaranteed by the ISO C dnl standard, but we don't know of any real-world counterexamples. AC_TRY_COMPILE([#include <sys/types.h>], [typedef int array[2 * (sizeof (mode_t) < sizeof (int)) - 1];], [gl_cv_promoted_mode_t='int'], [gl_cv_promoted_mode_t='mode_t']) ]) AC_DEFINE_UNQUOTED([PROMOTED_MODE_T], [$gl_cv_promoted_mode_t], [Define to the type that is the result of default argument promotions of type mode_t.]) ]) ============================================================================== --- lib/open-safer.c.orig 2009-05-21 21:03:28.000000000 +0200 +++ lib/open-safer.c 2009-05-21 19:21:18.000000000 +0200 @@ -1,6 +1,6 @@ /* Invoke open, but avoid some glitches. - Copyright (C) 2005, 2006, 2008 Free Software Foundation, Inc. + Copyright (C) 2005, 2006, 2008-2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -35,13 +35,9 @@ va_list ap; va_start (ap, flags); - /* Assume mode_t promotes to int if and only if it is smaller. - This assumption isn't guaranteed by the C standard, but we - don't know of any real-world counterexamples. */ - if (sizeof (mode_t) < sizeof (int)) - mode = va_arg (ap, int); - else - mode = va_arg (ap, mode_t); + /* We have to use PROMOTED_MODE_T instead of mode_t, otherwise GCC 4 + creates crashing code when 'mode_t' is smaller than 'int'. */ + mode = va_arg (ap, PROMOTED_MODE_T); va_end (ap); } --- lib/open.c.orig 2009-05-21 21:03:28.000000000 +0200 +++ lib/open.c 2009-05-21 19:21:12.000000000 +0200 @@ -1,5 +1,5 @@ /* Open a descriptor to a file. - Copyright (C) 2007-2008 Free Software Foundation, Inc. + Copyright (C) 2007-2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -51,12 +51,9 @@ va_list arg; va_start (arg, flags); - /* If mode_t is narrower than int, use the promoted type (int), - not mode_t. Use sizeof to guess whether mode_t is narrower; - we don't know of any practical counterexamples. */ - mode = (sizeof (mode_t) < sizeof (int) - ? va_arg (arg, int) - : va_arg (arg, mode_t)); + /* We have to use PROMOTED_MODE_T instead of mode_t, otherwise GCC 4 + creates crashing code when 'mode_t' is smaller than 'int'. */ + mode = va_arg (arg, PROMOTED_MODE_T); va_end (arg); } --- lib/openat.c.orig 2009-05-21 21:03:28.000000000 +0200 +++ lib/openat.c 2009-05-21 19:21:14.000000000 +0200 @@ -1,5 +1,5 @@ /* provide a replacement openat function - Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2004-2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -47,12 +47,9 @@ va_list arg; va_start (arg, flags); - /* If mode_t is narrower than int, use the promoted type (int), - not mode_t. Use sizeof to guess whether mode_t is narrower; - we don't know of any practical counterexamples. */ - mode = (sizeof (mode_t) < sizeof (int) - ? va_arg (arg, int) - : va_arg (arg, mode_t)); + /* We have to use PROMOTED_MODE_T instead of mode_t, otherwise GCC 4 + creates crashing code when 'mode_t' is smaller than 'int'. */ + mode = va_arg (arg, PROMOTED_MODE_T); va_end (arg); } --- m4/fcntl-safer.m4.orig 2009-05-21 21:03:28.000000000 +0200 +++ m4/fcntl-safer.m4 2009-05-21 17:49:15.000000000 +0200 @@ -1,5 +1,5 @@ -#serial 5 -dnl Copyright (C) 2005-2007 Free Software Foundation, Inc. +#serial 6 +dnl Copyright (C) 2005-2007, 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -8,4 +8,6 @@ [ AC_LIBOBJ([open-safer]) AC_LIBOBJ([creat-safer]) + # Prerequisites of lib/open-safer.c. + AC_REQUIRE([gl_PROMOTED_TYPE_MODE_T]) ]) --- m4/open.m4.orig 2009-05-21 21:03:28.000000000 +0200 +++ m4/open.m4 2009-05-21 17:48:38.000000000 +0200 @@ -1,4 +1,4 @@ -# open.m4 serial 5 +# open.m4 serial 6 dnl Copyright (C) 2007-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -62,5 +62,6 @@ AC_DEFUN([gl_PREREQ_OPEN], [ AC_REQUIRE([AC_C_INLINE]) + AC_REQUIRE([gl_PROMOTED_TYPE_MODE_T]) : ]) --- m4/openat.m4.orig 2009-05-21 21:03:28.000000000 +0200 +++ m4/openat.m4 2009-05-21 17:49:58.000000000 +0200 @@ -1,4 +1,4 @@ -# serial 17 +# serial 18 # See if we need to use our replacement for Solaris' openat et al functions. dnl Copyright (C) 2004-2009 Free Software Foundation, Inc. @@ -87,5 +87,6 @@ AC_DEFUN([gl_PREREQ_OPENAT], [ + AC_REQUIRE([gl_PROMOTED_TYPE_MODE_T]) : ]) --- modules/fcntl-safer.orig 2009-05-21 21:03:28.000000000 +0200 +++ modules/fcntl-safer 2009-05-21 17:50:15.000000000 +0200 @@ -7,6 +7,7 @@ lib/fcntl-safer.h lib/open-safer.c m4/fcntl-safer.m4 +m4/mode_t.m4 Depends-on: open --- modules/open.orig 2009-05-21 21:03:28.000000000 +0200 +++ modules/open 2009-05-21 17:50:16.000000000 +0200 @@ -4,6 +4,7 @@ Files: lib/open.c m4/open.m4 +m4/mode_t.m4 Depends-on: fcntl --- modules/openat.orig 2009-05-21 21:03:28.000000000 +0200 +++ modules/openat 2009-05-21 17:50:16.000000000 +0200 @@ -12,6 +12,7 @@ lib/openat-priv.h lib/openat-proc.c m4/openat.m4 +m4/mode_t.m4 Depends-on: dirname