changeset 17830:06d818b9ca43

stddef: support C11's max_align_t * doc/posix-headers/stddef.texi (stddef.h): Document max_align_t. * lib/stddef.in.h (_@GUARD_PREFIX@_STDDEF_H) [__need_wint_t]: Do not undef, as that might cause max_align_t to be defined twice. Instead, change use to check for _GL_STDDEF_WINT_T too. (max_align_t) [!HAVE_MAX_ALIGN_T]: New decl. * m4/stddef_h.m4 (gl_STDDEF_H, gl_STDDEF_H_DEFAULTS): Check for max_align_t. * modules/stddef (stddef.h): Substitute HAVE_MAX_ALIGN_T. * modules/stddef-tests (Depends-on): Add stdalign. * tests/test-stddef.c: Test max_align_t.
author Paul Eggert <eggert@cs.ucla.edu>
date Fri, 12 Dec 2014 11:27:45 -0800
parents ac1b13f881e5
children db34b1b0db14
files ChangeLog doc/posix-headers/stddef.texi lib/stddef.in.h m4/stddef_h.m4 modules/stddef modules/stddef-tests tests/test-stddef.c
diffstat 7 files changed, 63 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2014-12-12  Paul Eggert  <eggert@cs.ucla.edu>
+
+	stddef: support C11's max_align_t
+	* doc/posix-headers/stddef.texi (stddef.h): Document max_align_t.
+	* lib/stddef.in.h (_@GUARD_PREFIX@_STDDEF_H) [__need_wint_t]:
+	Do not undef, as that might cause max_align_t to be defined twice.
+	Instead, change use to check for _GL_STDDEF_WINT_T too.
+	(max_align_t) [!HAVE_MAX_ALIGN_T]: New decl.
+	* m4/stddef_h.m4 (gl_STDDEF_H, gl_STDDEF_H_DEFAULTS):
+	Check for max_align_t.
+	* modules/stddef (stddef.h): Substitute HAVE_MAX_ALIGN_T.
+	* modules/stddef-tests (Depends-on): Add stdalign.
+	* tests/test-stddef.c: Test max_align_t.
+
 2014-12-11  Daiki Ueno  <ueno@gnu.org>
 
 	unistd: fix iOS check conditional
--- a/doc/posix-headers/stddef.texi
+++ b/doc/posix-headers/stddef.texi
@@ -8,6 +8,9 @@
 Portability problems fixed by Gnulib:
 @itemize
 @item
+Some platforms fail to provide @code{max_align_t}, which was added in C11.
+
+@item
 Some old platforms fail to provide @code{wchar_t}.
 
 @item
--- a/lib/stddef.in.h
+++ b/lib/stddef.in.h
@@ -39,7 +39,6 @@
 
 # if !(defined _@GUARD_PREFIX@_STDDEF_H && defined _GL_STDDEF_WINT_T)
 #  ifdef __need_wint_t
-#   undef _@GUARD_PREFIX@_STDDEF_H
 #   define _GL_STDDEF_WINT_T
 #  endif
 #  @INCLUDE_NEXT@ @NEXT_STDDEF_H@
@@ -54,33 +53,45 @@
 
 #  @INCLUDE_NEXT@ @NEXT_STDDEF_H@
 
-#  ifndef _@GUARD_PREFIX@_STDDEF_H
-#   define _@GUARD_PREFIX@_STDDEF_H
-
 /* On NetBSD 5.0, the definition of NULL lacks proper parentheses.  */
-#if @REPLACE_NULL@
-# undef NULL
-# ifdef __cplusplus
+#  if (@REPLACE_NULL@ \
+       && (!defined _@GUARD_PREFIX@_STDDEF_H || defined _GL_STDDEF_WINT_T))
+#   undef NULL
+#   ifdef __cplusplus
    /* ISO C++ says that the macro NULL must expand to an integer constant
       expression, hence '((void *) 0)' is not allowed in C++.  */
-#  if __GNUG__ >= 3
+#    if __GNUG__ >= 3
     /* GNU C++ has a __null macro that behaves like an integer ('int' or
        'long') but has the same size as a pointer.  Use that, to avoid
        warnings.  */
-#   define NULL __null
-#  else
-#   define NULL 0L
+#     define NULL __null
+#    else
+#     define NULL 0L
+#    endif
+#   else
+#    define NULL ((void *) 0)
+#   endif
 #  endif
-# else
-#  define NULL ((void *) 0)
-# endif
-#endif
+
+#  ifndef _@GUARD_PREFIX@_STDDEF_H
+#   define _@GUARD_PREFIX@_STDDEF_H
 
 /* Some platforms lack wchar_t.  */
 #if !@HAVE_WCHAR_T@
 # define wchar_t int
 #endif
 
+/* Some platforms lack max_align_t.  */
+#if !@HAVE_MAX_ALIGN_T@
+typedef union
+{
+  char *__p;
+  double __d;
+  long double __ld;
+  long int __i;
+} max_align_t;
+#endif
+
 #  endif /* _@GUARD_PREFIX@_STDDEF_H */
 # endif /* _@GUARD_PREFIX@_STDDEF_H */
 #endif /* __need_XXX */
--- a/m4/stddef_h.m4
+++ b/m4/stddef_h.m4
@@ -1,5 +1,5 @@
-dnl A placeholder for POSIX 2008 <stddef.h>, for platforms that have issues.
-# stddef_h.m4 serial 4
+dnl A placeholder for <stddef.h>, for platforms that have issues.
+# stddef_h.m4 serial 5
 dnl Copyright (C) 2009-2014 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -10,6 +10,9 @@
   AC_REQUIRE([gl_STDDEF_H_DEFAULTS])
   AC_REQUIRE([gt_TYPE_WCHAR_T])
   STDDEF_H=
+  AC_CHECK_TYPE([max_align_t], [], [HAVE_MAX_ALIGN_T=0; STDDEF_H=stddef.h],
+    [[#include <stddef.h>
+    ]])
   if test $gt_cv_c_wchar_t = no; then
     HAVE_WCHAR_T=0
     STDDEF_H=stddef.h
@@ -43,5 +46,6 @@
 [
   dnl Assume proper GNU behavior unless another module says otherwise.
   REPLACE_NULL=0;                AC_SUBST([REPLACE_NULL])
+  HAVE_MAX_ALIGN_T=1;            AC_SUBST([HAVE_MAX_ALIGN_T])
   HAVE_WCHAR_T=1;                AC_SUBST([HAVE_WCHAR_T])
 ])
--- a/modules/stddef
+++ b/modules/stddef
@@ -26,6 +26,7 @@
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
 	      -e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|g' \
+	      -e 's|@''HAVE_MAX_ALIGN_T''@|$(HAVE_MAX_ALIGN_T)|g' \
 	      -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \
 	      -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \
 	      < $(srcdir)/stddef.in.h; \
--- a/modules/stddef-tests
+++ b/modules/stddef-tests
@@ -2,6 +2,7 @@
 tests/test-stddef.c
 
 Depends-on:
+stdalign
 verify
 
 configure.ac:
--- a/tests/test-stddef.c
+++ b/tests/test-stddef.c
@@ -19,13 +19,14 @@
 #include <config.h>
 
 #include <stddef.h>
-
+#include <stdalign.h>
 #include "verify.h"
 
 /* Check that appropriate types are defined.  */
 wchar_t a = 'c';
 ptrdiff_t b = 1;
 size_t c = 2;
+max_align_t x;
 
 /* Check that NULL can be passed through varargs as a pointer type,
    per POSIX 2008.  */
@@ -45,6 +46,16 @@
 verify (offsetof (struct d, e) < -1); /* Must be unsigned.  */
 verify (offsetof (struct d, f) == 1);
 
+/* Check max_align_t's alignment.  */
+verify (alignof (double) <= alignof (max_align_t));
+verify (alignof (int) <= alignof (max_align_t));
+verify (alignof (long double) <= alignof (max_align_t));
+verify (alignof (long int) <= alignof (max_align_t));
+verify (alignof (ptrdiff_t) <= alignof (max_align_t));
+verify (alignof (size_t) <= alignof (max_align_t));
+verify (alignof (wchar_t) <= alignof (max_align_t));
+verify (alignof (struct d) <= alignof (max_align_t));
+
 int
 main (void)
 {