* 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. --- ChangeLog | 14 ++++++++++++++ doc/posix-headers/stddef.texi | 3 +++ lib/stddef.in.h | 41 ++++++++++++++++++++++++++--------------- m4/stddef_h.m4 | 8 ++++++-- modules/stddef | 1 + modules/stddef-tests | 1 + tests/test-stddef.c | 13 ++++++++++++- 7 files changed, 63 insertions(+), 18 deletions(-)
diff --git a/ChangeLog b/ChangeLog index 2336ee5..df4d8d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2014-12-12 Paul Eggert <egg...@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 <u...@gnu.org> unistd: fix iOS check conditional diff --git a/doc/posix-headers/stddef.texi b/doc/posix-headers/stddef.texi index 6174b1f..77b3d3b 100644 --- a/doc/posix-headers/stddef.texi +++ b/doc/posix-headers/stddef.texi @@ -8,6 +8,9 @@ Gnulib module: stddef 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 diff --git a/lib/stddef.in.h b/lib/stddef.in.h index 11b58be..6032526 100644 --- 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 */ diff --git a/m4/stddef_h.m4 b/m4/stddef_h.m4 index c555e29..9659813 100644 --- 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_DEFUN([gl_STDDEF_H], 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 @@ AC_DEFUN([gl_STDDEF_H_DEFAULTS], [ 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]) ]) diff --git a/modules/stddef b/modules/stddef index fd4cf50..99794a9 100644 --- a/modules/stddef +++ b/modules/stddef @@ -26,6 +26,7 @@ stddef.h: stddef.in.h $(top_builddir)/config.status -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; \ diff --git a/modules/stddef-tests b/modules/stddef-tests index 622ece5..cef92fa 100644 --- a/modules/stddef-tests +++ b/modules/stddef-tests @@ -2,6 +2,7 @@ Files: tests/test-stddef.c Depends-on: +stdalign verify configure.ac: diff --git a/tests/test-stddef.c b/tests/test-stddef.c index d5d887e..0b8649d 100644 --- 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 (sizeof (offsetof (struct d, e)) == sizeof (size_t)); 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) { -- 1.9.3