From d9741b61c8e446de084cc4dc609aaa8e5702118d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 20 Sep 2016 08:30:17 -0700 Subject: [PATCH] Use flexmembers on IBM XL C for AIX MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This removes a workaround where Emacs did not use flexible array members when compiled with IBM XL C. Instead, avoid the problem by making the aliasing issues more obvious to this compiler. * admin/merge-gnulib: Don’t remove m4/flexmember.m4. * m4/flexmember.m4: Copy from gnulib. * configure.ac (AC_C_FLEXIBLE_ARRAY_MEMBER): Remove workaround. * src/alloc.c (allocate_string_data): Rephrase to avoid aliasing problem that would otherwise mess up code generated for flexible array members by IBM XL C for AIX, V12.1. * src/conf_post.h (FLEXIBLE_ARRAY_MEMBER): Remove; now done by gnulib code. --- admin/merge-gnulib | 2 +- configure.ac | 2 -- m4/flexmember.m4 | 43 +++++++++++++++++++++++++++++++++++++++++++ src/alloc.c | 16 +++++++++------- src/conf_post.h | 10 ---------- 5 files changed, 53 insertions(+), 20 deletions(-) create mode 100644 m4/flexmember.m4 diff --git a/admin/merge-gnulib b/admin/merge-gnulib index 1e3b7599626..ada80b4ae86 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib @@ -93,7 +93,7 @@ test -x "$gnulib_srcdir"/gnulib-tool || { } "$gnulib_srcdir"/gnulib-tool --dir="$src" $GNULIB_TOOL_FLAGS $GNULIB_MODULES && -rm -- "$src"lib/gl_openssl.h "$src"m4/fcntl-o.m4 "$src"m4/flexmember.m4 \ +rm -- "$src"lib/gl_openssl.h "$src"m4/fcntl-o.m4 \ "$src"m4/gl-openssl.m4 \ "$src"m4/gnulib-cache.m4"$src" m4/warn-on-use.m4 && cp -- "$gnulib_srcdir"/build-aux/texinfo.tex "$src"doc/misc && diff --git a/configure.ac b/configure.ac index 82a672b8cc5..6488f901e33 100644 --- a/configure.ac +++ b/configure.ac @@ -775,8 +775,6 @@ dnl alternative to lib/gnulib.mk, so as to avoid generating header files dnl that clash with MinGW. AM_CONDITIONAL([BUILDING_FOR_WINDOWSNT], [test "x$opsys" = "xmingw32"]) -# Skip gnulib's tests for flexible array members, as Emacs assumes C99. -AC_DEFUN([AC_C_FLEXIBLE_ARRAY_MEMBER]) # Avoid gnulib's tests for -lcrypto, so that there's no static dependency on it. AC_DEFUN([gl_CRYPTO_CHECK]) # Avoid gnulib's tests for HAVE_WORKING_O_NOATIME and HAVE_WORKING_O_NOFOLLOW, diff --git a/m4/flexmember.m4 b/m4/flexmember.m4 new file mode 100644 index 00000000000..155ae9b8120 --- /dev/null +++ b/m4/flexmember.m4 @@ -0,0 +1,43 @@ +# serial 4 +# Check for flexible array member support. + +# Copyright (C) 2006, 2009-2016 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Written by Paul Eggert. + +AC_DEFUN([AC_C_FLEXIBLE_ARRAY_MEMBER], +[ + AC_CACHE_CHECK([for flexible array member], + ac_cv_c_flexmember, + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #include + #include + struct s { int n; double d[]; };]], + [[int m = getchar (); + size_t nbytes = offsetof (struct s, d) + m * sizeof (double); + nbytes += sizeof (struct s) - 1; + nbytes -= nbytes % sizeof (struct s); + struct s *p = malloc (nbytes); + p->d[0] = 0.0; + return p->d != (double *) NULL;]])], + [ac_cv_c_flexmember=yes], + [ac_cv_c_flexmember=no])]) + if test $ac_cv_c_flexmember = yes; then + AC_DEFINE([FLEXIBLE_ARRAY_MEMBER], [], + [Define to nothing if C supports flexible array members, and to + 1 if it does not. That way, with a declaration like 'struct s + { int n; double d@<:@FLEXIBLE_ARRAY_MEMBER@:>@; };', the struct hack + can be used with pre-C99 compilers. + When computing the size of such an object, don't use 'sizeof (struct s)' + as it overestimates the size. Use 'offsetof (struct s, d)' instead. + Don't use 'offsetof (struct s, d@<:@0@:>@)', as this doesn't work with + MSVC and with C++ compilers.]) + else + AC_DEFINE([FLEXIBLE_ARRAY_MEMBER], [1]) + fi +]) diff --git a/src/alloc.c b/src/alloc.c index 1092a34801a..41b2f9e77d2 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -2002,9 +2002,9 @@ allocate_string_data (struct Lisp_String *s, mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); #endif - b->next_free = b->data; - b->data[0].string = NULL; + data = b->data; b->next = large_sblocks; + b->next_free = data; large_sblocks = b; } else if (current_sblock == NULL @@ -2014,9 +2014,9 @@ allocate_string_data (struct Lisp_String *s, { /* Not enough room in the current sblock. */ b = lisp_malloc (SBLOCK_SIZE, MEM_TYPE_NON_LISP); - b->next_free = b->data; - b->data[0].string = NULL; + data = b->data; b->next = NULL; + b->next_free = data; if (current_sblock) current_sblock->next = b; @@ -2025,14 +2025,16 @@ allocate_string_data (struct Lisp_String *s, current_sblock = b; } else - b = current_sblock; + { + b = current_sblock; + data = b->next_free; + } - data = b->next_free; + data->string = s; b->next_free = (sdata *) ((char *) data + needed + GC_STRING_EXTRA); MALLOC_UNBLOCK_INPUT; - data->string = s; s->data = SDATA_DATA (data); #ifdef GC_CHECK_STRING_BYTES SDATA_NBYTES (data) = nbytes; diff --git a/src/conf_post.h b/src/conf_post.h index 865d0183a57..6d54524b970 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -358,16 +358,6 @@ extern int emacs_setenv_TZ (char const *); #define INLINE_HEADER_BEGIN _GL_INLINE_HEADER_BEGIN #define INLINE_HEADER_END _GL_INLINE_HEADER_END -/* To use the struct hack with N elements, declare the struct like this: - struct s { ...; t name[FLEXIBLE_ARRAY_MEMBER]; }; - and allocate (offsetof (struct s, name) + N * sizeof (t)) bytes. - IBM xlc 12.1 claims to do C99 but mishandles flexible array members. */ -#ifdef __IBMC__ -# define FLEXIBLE_ARRAY_MEMBER 1 -#else -# define FLEXIBLE_ARRAY_MEMBER -#endif - /* 'int x UNINIT;' is equivalent to 'int x;', except it cajoles GCC into not warning incorrectly about use of an uninitialized variable. */ #if defined GCC_LINT || defined lint -- 2.11.4.GIT