NEWS.stable: log cherry-pick [e446f25]->[c092018] relocatable-shell: Update suggested...
[gnulib.git] / m4 / stdalign.m4
index d90cee3..9efafe5 100644 (file)
@@ -1,6 +1,6 @@
-# Check for stdalign.h that conforms to C1x.
+# Check for stdalign.h that conforms to C11.
 
-dnl Copyright 2011 Free Software Foundation, Inc.
+dnl Copyright 2011-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,
 dnl with or without modifications, as long as this notice is preserved.
@@ -9,29 +9,45 @@ dnl with or without modifications, as long as this notice is preserved.
 
 AC_DEFUN([gl_STDALIGN_H],
 [
-  AC_CHECK_HEADERS_ONCE([stdalign.h])
-  HAVE_ATTRIBUTE_ALIGNED='?'
+  AC_CACHE_CHECK([for working stdalign.h],
+    [gl_cv_header_working_stdalign_h],
+    [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[#include <stdalign.h>
+            #include <stddef.h>
 
-  if test "$ac_cv_header_stdalign_h" = yes; then
+            /* Test that alignof yields a result consistent with offsetof.
+               This catches GCC bug 52023
+               <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023>.  */
+            #ifdef __cplusplus
+               template <class t> struct alignof_helper { char a; t b; };
+            # define ao(type) offsetof (alignof_helper<type>, b)
+            #else
+            # define ao(type) offsetof (struct { char a; type b; }, b)
+            #endif
+            char test_double[ao (double) % _Alignof (double) == 0 ? 1 : -1];
+            char test_long[ao (long int) % _Alignof (long int) == 0 ? 1 : -1];
+            char test_alignof[alignof (double) == _Alignof (double) ? 1 : -1];
+
+            /* Test _Alignas only on platforms where gnulib can help.  */
+            #if \
+                ((defined __cplusplus && 201103 <= __cplusplus) \
+                 || __GNUC__ || __IBMC__ || __IBMCPP__ || __ICC \
+                 || 0x5110 <= __SUNPRO_C || 1300 <= _MSC_VER)
+              struct alignas_test { char c; char alignas (8) alignas_8; };
+              char test_alignas[offsetof (struct alignas_test, alignas_8) == 8
+                                ? 1 : -1];
+            #endif
+          ]])],
+       [gl_cv_header_working_stdalign_h=yes],
+       [gl_cv_header_working_stdalign_h=no])])
+
+  if test $gl_cv_header_working_stdalign_h = yes; then
     STDALIGN_H=''
   else
     STDALIGN_H='stdalign.h'
-    AC_CACHE_CHECK([for  __attribute__ ((__aligned__ (expr)))],
-      [gl_cv_attribute_aligned],
-      [AC_COMPILE_IFELSE(
-         [AC_LANG_PROGRAM(
-            [[char __attribute__ ((__aligned__ (1 << 3))) c;]],
-            [[]])],
-         [gl_cv_attribute_aligned=yes],
-         [gl_cv_attribute_aligned=no])])
-    if test $gl_cv_attribute_aligned = yes; then
-      HAVE_ATTRIBUTE_ALIGNED=1
-    else
-      HAVE_ATTRIBUTE_ALIGNED=0
-    fi
   fi
 
-  AC_SUBST([HAVE_ATTRIBUTE_ALIGNED])
   AC_SUBST([STDALIGN_H])
   AM_CONDITIONAL([GL_GENERATE_STDALIGN_H], [test -n "$STDALIGN_H"])
 ])