Mercurial > hg > octave-kai > gnulib-hg
changeset 16011:3ec3070cd6c1
stdalign: port better to MSVC and to Sun C 5.11
I think these problems were reported by Bruno Haible, in email
that I've unfortunately misplaced.
* doc/posix-headers/stdalign.texi (stdalign.h): Document more
shortcomings of MSVC and of Sun C 5.11.
* lib/stdalign.in.h (_Alignas): Omit bogus extra parenthesis
around __declspec arg.
* modules/stdalign-tests (Files): Add tests/macros.h.
* tests/test-stdalign.c: Do not include <stdlib.h>; no longer needed.
Include macros.h, for ASSERT.
(DECLARE_ALIGNED): Remove.
(TEST_ALIGNMENT): Define to 16 if alignment is supported (more likely
to catch bug), and to 1 if not (simplifies the rest of the code).
(CHECK_STATIC): Always declare the alignment test vars; that's simpler.
(CHECK_AUTO): Remove.
(CHECK_ALIGNED): Check only the alignment of the static vars,
since auto var alignment isn't supported by Sun C 5.11.
(CHECK_TYPES): Remove. All uses replaced by inline code, so that
ASSERT failures are easier to diagnose.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Mon, 31 Oct 2011 22:37:30 -0700 |
parents | d9d661219067 |
children | fb7a82c2a615 |
files | ChangeLog doc/posix-headers/stdalign.texi lib/stdalign.in.h modules/stdalign-tests tests/test-stdalign.c |
diffstat | 5 files changed, 92 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2011-10-31 Paul Eggert <eggert@cs.ucla.edu> + + stdalign: port better to MSVC and to Sun C 5.11 + I think these problems were reported by Bruno Haible, in email + that I've unfortunately misplaced. + * doc/posix-headers/stdalign.texi (stdalign.h): Document more + shortcomings of MSVC and of Sun C 5.11. + * lib/stdalign.in.h (_Alignas): Omit bogus extra parenthesis + around __declspec arg. + * modules/stdalign-tests (Files): Add tests/macros.h. + * tests/test-stdalign.c: Do not include <stdlib.h>; no longer needed. + Include macros.h, for ASSERT. + (DECLARE_ALIGNED): Remove. + (TEST_ALIGNMENT): Define to 16 if alignment is supported (more likely + to catch bug), and to 1 if not (simplifies the rest of the code). + (CHECK_STATIC): Always declare the alignment test vars; that's simpler. + (CHECK_AUTO): Remove. + (CHECK_ALIGNED): Check only the alignment of the static vars, + since auto var alignment isn't supported by Sun C 5.11. + (CHECK_TYPES): Remove. All uses replaced by inline code, so that + ASSERT failures are easier to diagnose. + 2011-10-31 Bruno Haible <bruno@clisp.org> doc about some IRIX 5.3 problems.
--- a/doc/posix-headers/stdalign.texi +++ b/doc/posix-headers/stdalign.texi @@ -24,6 +24,20 @@ Supported compilers include GCC, IBM C, Sun C 5.11 and later, and MSVC 7.0 and later. @item +Some compilers do not support alignment via +@code{alignas}/@code{_Alignas} of @code{auto} variables (i.e., +variables on the stack). They diagnose and ignore the alignment: Sun +C 5.11. +@item +Some compilers require the operand of @code{_Alignas}/@code{alignas} +to be a single integer constant, not an expression: MSVC 7.0 through +at least 10.0. +@item +The Sun C 5.11 compiler sometimes mishandles the alignment of multiple +external variables that are declared close together with +@code{_Alignas}/@code{alignas}. This compiler bug causes the Gnulib +module @code{stdalign-tests} to fail. +@item @code{<stdalign.h>} must be #included before @samp{_Alignas} and @samp{_Alignof} can be used. @item
--- a/lib/stdalign.in.h +++ b/lib/stdalign.in.h @@ -62,7 +62,11 @@ A should be a power of two that is at least the type's alignment and at most the implementation's alignment limit. This limit is - 2**28 on typical GNUish hosts, and 2**13 on MSVC. + 2**28 on typical GNUish hosts, and 2**13 on MSVC. To be portable + to MSVC through at least version 10.0, A should be an integer + constant, as MSVC does not support expressions such as 1 << 3. + To be portable to Sun C 5.11, do not align auto variables to + anything stricter than their default alignment. The following draft C1X requirements are not supported here: @@ -75,7 +79,7 @@ #if __GNUC__ || __IBMC__ || __IBMCPP__ || 0x5110 <= __SUNPRO_C # define _Alignas(a) __attribute__ ((__aligned__ (a))) #elif 1300 <= _MSC_VER -# define _Alignas(a) __declspec ((align (a))) +# define _Alignas(a) __declspec (align (a)) #endif #ifdef _Alignas # define alignas _Alignas
--- a/modules/stdalign-tests +++ b/modules/stdalign-tests @@ -1,5 +1,6 @@ Files: tests/test-stdalign.c +tests/macros.h Depends-on: verify
--- a/tests/test-stdalign.c +++ b/tests/test-stdalign.c @@ -22,10 +22,11 @@ #include <stddef.h> #include <stdint.h> -#include <stdlib.h> #include "verify.h" +#include "macros.h" + typedef long double longdouble; typedef struct { char a[1]; } struct1; typedef struct { char a[2]; } struct2; @@ -42,15 +43,11 @@ # ifndef alignas # error "alignas is not a macro" # endif -# define DECLARE_ALIGNED(type, name) \ - type alignas (1 << 3) name##_alignas; \ - type _Alignas (1 << 3) name##_Alignas; -# define CHECK_ALIGNED(name) \ - (((uintptr_t) &name##_alignas % (1 << 3) ? abort () : (void) 0), \ - ((uintptr_t) &name##_Alignas % (1 << 3) ? abort () : (void) 0)) +# define TEST_ALIGNMENT 16 #else -# define DECLARE_ALIGNED(type, name) -# define CHECK_ALIGNED(name) ((void) 0) +# define _Alignas(alignment) +# define alignas(alignment) +# define TEST_ALIGNMENT 1 #endif #define CHECK_STATIC(type) \ @@ -58,40 +55,54 @@ verify (alignof (type) == offsetof (type##_helper, slot2)); \ verify (_Alignof (type) == alignof (type)); \ const int type##_alignment = alignof (type); \ - DECLARE_ALIGNED(type, static_##type) + type alignas (TEST_ALIGNMENT) static_##type##_alignas; \ + type _Alignas (TEST_ALIGNMENT) static_##type##_Alignas -#define CHECK_AUTO(type) \ - { \ - DECLARE_ALIGNED(type, auto_##type) \ - CHECK_ALIGNED(static_##type); \ - CHECK_ALIGNED(auto_##type); \ - } - -#ifdef INT64_MAX -# define if_INT64_MAX(x) x -#else -# define if_INT64_MAX(x) -#endif +#define CHECK_ALIGNED(var) ASSERT ((uintptr_t) &(var) % TEST_ALIGNMENT == 0) -#define CHECK_TYPES(check) \ - check (char) \ - check (short) \ - check (int) \ - check (long) \ - if_INT64_MAX (check (int64_t)) \ - check (float) \ - check (double) \ - check (longdouble) \ - check (struct1) \ - check (struct2) \ - check (struct3) \ - check (struct4) - -CHECK_TYPES (CHECK_STATIC) +CHECK_STATIC (char); +CHECK_STATIC (short); +CHECK_STATIC (int); +CHECK_STATIC (long); +#ifdef INT64_MAX +CHECK_STATIC (int64_t); +#endif +CHECK_STATIC (float); +CHECK_STATIC (double); +CHECK_STATIC (longdouble); +CHECK_STATIC (struct1); +CHECK_STATIC (struct2); +CHECK_STATIC (struct3); +CHECK_STATIC (struct4); int main () { - CHECK_TYPES (CHECK_AUTO) + CHECK_ALIGNED (static_char_alignas); + CHECK_ALIGNED (static_char_Alignas); + CHECK_ALIGNED (static_short_alignas); + CHECK_ALIGNED (static_short_Alignas); + CHECK_ALIGNED (static_int_alignas); + CHECK_ALIGNED (static_int_Alignas); + CHECK_ALIGNED (static_long_alignas); + CHECK_ALIGNED (static_long_Alignas); +#ifdef INT64_MAX + CHECK_ALIGNED (static_int64_t_alignas); + CHECK_ALIGNED (static_int64_t_Alignas); +#endif + CHECK_ALIGNED (static_float_alignas); + CHECK_ALIGNED (static_float_Alignas); + CHECK_ALIGNED (static_double_alignas); + CHECK_ALIGNED (static_double_Alignas); + CHECK_ALIGNED (static_longdouble_alignas); + CHECK_ALIGNED (static_longdouble_Alignas); + CHECK_ALIGNED (static_struct1_alignas); + CHECK_ALIGNED (static_struct1_Alignas); + CHECK_ALIGNED (static_struct2_alignas); + CHECK_ALIGNED (static_struct2_Alignas); + CHECK_ALIGNED (static_struct3_alignas); + CHECK_ALIGNED (static_struct3_Alignas); + CHECK_ALIGNED (static_struct4_alignas); + CHECK_ALIGNED (static_struct4_Alignas); return 0; }