Mercurial > hg > octave-lojdl > gnulib-hg
changeset 15999:bf4984d2b939
Adjust to Bruno's comments.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Thu, 27 Oct 2011 12:43:51 -0700 |
parents | 9b28a5d31bb5 |
children | 79bbea2afc18 |
files | ChangeLog doc/posix-headers/stdalign.texi lib/stdalign.in.h m4/stdalign.m4 modules/stdalign tests/test-stdalign.c |
diffstat | 6 files changed, 81 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2011-10-27 Paul Eggert <eggert@cs.ucla.edu> + Add stdalign module and use it in other modules. + This is based on a previous proposal by Bruno Haible + <https://lists.gnu.org/archive/html/bug-gnulib/2011-07/msg00226.html>. + stdalign: new module * doc/posix-headers/stdalign.texi, lib/stdalign.in.h, m4/stdalign.m4: * modules/stdalign: New files.
--- a/doc/posix-headers/stdalign.texi +++ b/doc/posix-headers/stdalign.texi @@ -21,8 +21,8 @@ @code{_Alignas} and @code{alignas} are not always supported; on platforms lacking support, the macro @code{__alignas_is_defined} is not defined. -Supported platforms includes GCC 2 and later, Sun C 5.11 and later, -and MSVC 7.0 or later. +Supported compilers include GCC, IBM C, Sun C 5.11 and later, +and MSVC 7.0 and later. @item @code{<stdalign.h>} must be #included before @samp{_Alignas} and @samp{_Alignof} can be used.
--- a/lib/stdalign.in.h +++ b/lib/stdalign.in.h @@ -29,14 +29,18 @@ C++0X <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf> section 18.10. */ -/* Return the alignment of a structure slot (field) of TYPE, - as an integer constant expression. The result cannot be used as a - value for an 'enum' constant, if you want to be portable to HP-UX - 10.20 cc and AIX 3.2.5 xlc. +/* alignof (TYPE), also known as _Alignof (TYPE), yields the alignment + requirement of a structure member (i.e., slot or field) that is of + type TYPE, as an integer constant expression. - This is not the same as GCC's __alignof__ operator; for example, on - x86 with GCC, _Alignof (long long) is typically 4 whereas - __alignof__ (long long) is 8. */ + This differs from GCC's __alignof__ operator, which can yield a + better-performing alignment for an object of that type. For + example, on x86 with GCC, __alignof__ (double) and __alignof__ + (long long) are 8, whereas alignof (double) and alignof (long long) + are 4 unless the option '-malign-double' is used. + + The result cannot be used as a value for an 'enum' constant, if you + want to be portable to HP-UX 10.20 cc and AIX 3.2.5 xlc. */ #include <stddef.h> #if defined __cplusplus template <class __t> struct __alignof_helper { char __a; __t __b; }; @@ -47,8 +51,28 @@ #define alignof _Alignof #define __alignof_is_defined 1 -/* Align a type or variable to the alignment A. */ -#if @HAVE_ATTRIBUTE_ALIGNED@ && !defined __cplusplus +/* alignas (A), also known as _Alignas (A), aligns a variable or type + to the alignment A, where A is an integer constant expression. For + example: + + int alignas (8) foo; + struct s { int a; int alignas (8) bar; }; + + aligns the address of FOO and the offset of BAR to be multiples of 8. + + 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. + + The following draft C1X requirements are not supported here: + + - If A is zero, alignas has no effect. + - alignas can be used multiple times; the strictest one wins. + - alignas (TYPE) is equivalent to alignas (alignof (TYPE)). + + */ + +#if __GNUC__ || __IBMC__ || __IBMCPP__ || 0x5110 <= __SUNPRO_C # define _Alignas(a) __attribute__ ((__aligned__ (a))) #elif 1300 <= _MSC_VER # define _Alignas(a) __declspec ((align (a)))
--- a/m4/stdalign.m4 +++ b/m4/stdalign.m4 @@ -10,28 +10,13 @@ AC_DEFUN([gl_STDALIGN_H], [ AC_CHECK_HEADERS_ONCE([stdalign.h]) - HAVE_ATTRIBUTE_ALIGNED='?' - if test "$ac_cv_header_stdalign_h" = yes; then + if test $ac_cv_header_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"]) ])
--- a/modules/stdalign +++ b/modules/stdalign @@ -19,7 +19,7 @@ stdalign.h: stdalign.in.h $(top_builddir)/config.status $(AM_V_GEN)rm -f $@-t $@ && \ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''HAVE_ATTRIBUTE_ALIGNED''@/$(HAVE_ATTRIBUTE_ALIGNED)/g' < $(srcdir)/stdalign.in.h; \ + cat $(srcdir)/stdalign.in.h; \ } > $@-t && \ mv $@-t $@ else
--- a/tests/test-stdalign.c +++ b/tests/test-stdalign.c @@ -22,6 +22,7 @@ #include <stddef.h> #include <stdint.h> +#include <stdlib.h> #include "verify.h" @@ -41,37 +42,56 @@ # ifndef alignas # error "alignas is not a macro" # endif -# define CHECK_ALIGNAS(type) \ - type alignas (1 << 3) type##_alignas; \ - type _Alignas (1 << 3) type##_Alignas; +# 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)) #else -# define CHECK_ALIGNAS(type) +# define DECLARE_ALIGNED(type, name) +# define CHECK_ALIGNED(name) ((void) 0) #endif -#define CHECK(type) \ +#define CHECK_STATIC(type) \ typedef struct { char slot1; type slot2; } type##_helper; \ verify (alignof (type) == offsetof (type##_helper, slot2)); \ verify (_Alignof (type) == alignof (type)); \ const int type##_alignment = alignof (type); \ - CHECK_ALIGNAS(type) + DECLARE_ALIGNED(type, static_##type) + +#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 -CHECK (char) -CHECK (short) -CHECK (int) -CHECK (long) -CHECK (float) -CHECK (double) -CHECK (longdouble) -#ifdef INT64_MAX -CHECK (int64_t) -#endif -CHECK (struct1) -CHECK (struct2) -CHECK (struct3) -CHECK (struct4) +#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) int main () { + CHECK_TYPES (CHECK_AUTO) return 0; }