On AIX 7.1, 7.2, with xlc in 64-bit mode, I see this test compilation failure:
"../../gltests/test-stddef.c", line 57.1: 1506-044 (S) Expression must be a non-negative integer constant. "../../gltests/test-stddef.c", line 58.1: 1506-044 (S) Expression must be a non-negative integer constant. "../../gltests/test-stddef.c", line 59.1: 1506-044 (S) Expression must be a non-negative integer constant. make: 1254-004 The error code from the last command is 1. The cause is the definition of max_align_t: it is defined as 'long double', which has alignment 4 in this case — whereas 'long int' has alignment 8. This patch fixes it. 2021-01-03 Bruno Haible <br...@clisp.org> stddef: Override wrong max_align_t on AIX 7 with xlc in 64-bit mode. * m4/stddef_h.m4 (gl_STDDEF_H): Make check for good max_align_t stricter: Add tests for offsetof-based alignof. * lib/stddef.in.h (max_align_t): Override on AIX in 64-bit mode. * doc/posix-headers/stddef.texi: Document the AIX max_align_t bug. diff --git a/doc/posix-headers/stddef.texi b/doc/posix-headers/stddef.texi index 33018ef..dbc0103 100644 --- a/doc/posix-headers/stddef.texi +++ b/doc/posix-headers/stddef.texi @@ -13,7 +13,7 @@ NetBSD 8.0, Solaris 11.0, and others. @item @code{max_align_t} does not have the expected alignment on some platforms: -NetBSD 8.0/x86. +NetBSD 8.0/x86, AIX 7.2 with xlc in 64-bit mode. @item Some old platforms fail to provide @code{wchar_t}. diff --git a/lib/stddef.in.h b/lib/stddef.in.h index 6ef45af..77147e9 100644 --- a/lib/stddef.in.h +++ b/lib/stddef.in.h @@ -49,6 +49,23 @@ # ifndef _@GUARD_PREFIX@_STDDEF_H +/* On AIX 7.2, with xlc in 64-bit mode, <stddef.h> defines max_align_t to a + type with alignment 4, but 'long' has alignment 8. */ +# if defined _AIX && defined _ARCH_PPC64 +# if !GNULIB_defined_max_align_t +# ifdef _MAX_ALIGN_T +/* /usr/include/stddef.h has already defined max_align_t. Override it. */ +typedef long rpl_max_align_t; +# define max_align_t rpl_max_align_t +# else +/* Prevent /usr/include/stddef.h from defining max_align_t. */ +typedef long max_align_t; +# define _MAX_ALIGN_T +# endif +# define GNULIB_defined_max_align_t 1 +# endif +# endif + /* The include_next requires a split double-inclusion guard. */ # @INCLUDE_NEXT@ @NEXT_STDDEF_H@ diff --git a/m4/stddef_h.m4 b/m4/stddef_h.m4 index 7869621..cd666c4 100644 --- a/m4/stddef_h.m4 +++ b/m4/stddef_h.m4 @@ -1,4 +1,4 @@ -# stddef_h.m4 serial 8 +# stddef_h.m4 serial 9 dnl Copyright (C) 2009-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -28,6 +28,13 @@ AC_DEFUN([gl_STDDEF_H], int check1[2 * (__alignof__ (double) <= __alignof__ (max_align_t)) - 1]; int check2[2 * (__alignof__ (long double) <= __alignof__ (max_align_t)) - 1]; #endif + typedef struct { char a; max_align_t b; } max_helper; + typedef struct { char a; long b; } long_helper; + typedef struct { char a; double b; } double_helper; + typedef struct { char a; long double b; } long_double_helper; + int check3[2 * (offsetof (long_helper, b) <= offsetof (max_helper, b)) - 1]; + int check4[2 * (offsetof (double_helper, b) <= offsetof (max_helper, b)) - 1]; + int check5[2 * (offsetof (long_double_helper, b) <= offsetof (max_helper, b)) - 1]; ]])], [gl_cv_type_max_align_t=yes], [gl_cv_type_max_align_t=no])