diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2014-08-30 15:59:39 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2014-08-30 15:59:39 -0700 |
commit | f9caea823350640fb03195c73c301f08ce932bd0 (patch) | |
tree | be0e02155cf2f218c61379dde8ac98f100553392 /m4 | |
parent | 88366fcf88e5bccc4d0bcff798beb3ef27aaa496 (diff) |
Vector-sorting fixes.
It's not safe to call qsort or qsort_r, since they have undefined
behavior if the user-specified predicate is not a total order.
Also, watch out for garbage-collection while sorting vectors.
* admin/merge-gnulib (GNULIB_MODULES): Add vla.
* configure.ac (qsort_r): Remove, as we no longer use qsort-like
functions.
* lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate.
* lib/vla.h, m4/vararrays.m4: New files, copied from gnulib.
* lib/stdlib.in.h, m4/stdlib_h.m4: Sync from gnulib, incorporating:
2014-08-29 qsort_r: new module, for GNU-style qsort_r
The previous two files' changes are boilerplate generated by
admin/merge-gnulib, and should not affect Emacs.
* src/fns.c: Include <vla.h>.
(sort_vector_predicate) [!HAVE_QSORT_R]: Remove.
(sort_vector_compare): Remove, replacing with ....
(inorder, merge_vectors, sort_vector_inplace, sort_vector_copy):
... these new functions.
(sort_vector): Rewrite to use the new functions.
GCPRO locals, since the predicate can invoke the GC.
Since it's in-place return void; caller changed.
(merge): Use 'inorder', for clarity.
Fixes: debbugs:18361
Diffstat (limited to 'm4')
-rw-r--r-- | m4/gnulib-comp.m4 | 5 | ||||
-rw-r--r-- | m4/stdlib_h.m4 | 2 | ||||
-rw-r--r-- | m4/vararrays.m4 | 68 |
3 files changed, 75 insertions, 0 deletions
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 98acc069c9..7b6b5c00f9 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -146,7 +146,9 @@ AC_DEFUN([gl_EARLY], # Code from module unsetenv: # Code from module update-copyright: # Code from module utimens: + # Code from module vararrays: # Code from module verify: + # Code from module vla: # Code from module warnings: # Code from module xalloc-oversized: ]) @@ -383,6 +385,7 @@ AC_DEFUN([gl_INIT], fi gl_STDLIB_MODULE_INDICATOR([unsetenv]) gl_UTIMENS + AC_C_VARARRAYS gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b=false gl_gnulib_enabled_dosname=false gl_gnulib_enabled_euidaccess=false @@ -916,6 +919,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/utimens.c lib/utimens.h lib/verify.h + lib/vla.h lib/xalloc-oversized.h m4/00gnulib.m4 m4/absolute-header.m4 @@ -1013,6 +1017,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/utimbuf.m4 m4/utimens.m4 m4/utimes.m4 + m4/vararrays.m4 m4/warn-on-use.m4 m4/warnings.m4 m4/wchar_t.m4 diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 index 03b448b94f..86aff16eb0 100644 --- a/m4/stdlib_h.m4 +++ b/m4/stdlib_h.m4 @@ -55,6 +55,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], GNULIB_PTSNAME=0; AC_SUBST([GNULIB_PTSNAME]) GNULIB_PTSNAME_R=0; AC_SUBST([GNULIB_PTSNAME_R]) GNULIB_PUTENV=0; AC_SUBST([GNULIB_PUTENV]) + GNULIB_QSORT_R=0; AC_SUBST([GNULIB_QSORT_R]) GNULIB_RANDOM=0; AC_SUBST([GNULIB_RANDOM]) GNULIB_RANDOM_R=0; AC_SUBST([GNULIB_RANDOM_R]) GNULIB_REALLOC_POSIX=0; AC_SUBST([GNULIB_REALLOC_POSIX]) @@ -107,6 +108,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], REPLACE_PTSNAME=0; AC_SUBST([REPLACE_PTSNAME]) REPLACE_PTSNAME_R=0; AC_SUBST([REPLACE_PTSNAME_R]) REPLACE_PUTENV=0; AC_SUBST([REPLACE_PUTENV]) + REPLACE_QSORT_R=0; AC_SUBST([REPLACE_QSORT_R]) REPLACE_RANDOM_R=0; AC_SUBST([REPLACE_RANDOM_R]) REPLACE_REALLOC=0; AC_SUBST([REPLACE_REALLOC]) REPLACE_REALPATH=0; AC_SUBST([REPLACE_REALPATH]) diff --git a/m4/vararrays.m4 b/m4/vararrays.m4 new file mode 100644 index 0000000000..cbda525c75 --- /dev/null +++ b/m4/vararrays.m4 @@ -0,0 +1,68 @@ +# Check for variable-length arrays. + +# serial 5 + +# From Paul Eggert + +# Copyright (C) 2001, 2009-2014 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. + +# This is a copy of AC_C_VARARRAYS from a recent development version +# of Autoconf. It replaces Autoconf's version, or for pre-2.61 autoconf +# it defines the macro that Autoconf lacks. +AC_DEFUN([AC_C_VARARRAYS], +[ + AC_CACHE_CHECK([for variable-length arrays], + ac_cv_c_vararrays, + [AC_EGREP_CPP([defined], + [#ifdef __STDC_NO_VLA__ + defined + #endif + ], + [ac_cv_c_vararrays='no: __STDC_NO_VLA__ is defined'], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[/* Test for VLA support. This test is partly inspired + from examples in the C standard. Use at least two VLA + functions to detect the GCC 3.4.3 bug described in: + http://lists.gnu.org/archive/html/bug-gnulib/2014-08/msg00014.html + */ + #ifdef __STDC_NO_VLA__ + syntax error; + #else + extern int n; + int B[100]; + int fvla (int m, int C[m][m]); + + int + simple (int count, int all[static count]) + { + return all[count - 1]; + } + + int + fvla (int m, int C[m][m]) + { + typedef int VLA[m][m]; + VLA x; + int D[m]; + static int (*q)[m] = &B; + int (*s)[n] = q; + return C && &x[0][0] == &D[0] && &D[0] == s[0]; + } + #endif + ]])], + [ac_cv_c_vararrays=yes], + [ac_cv_c_vararrays=no])])]) + if test "$ac_cv_c_vararrays" = yes; then + dnl This is for compatibility with Autoconf 2.61-2.69. + AC_DEFINE([HAVE_C_VARARRAYS], 1, + [Define to 1 if C supports variable-length arrays.]) + elif test "$ac_cv_c_vararrays" = no; then + AC_DEFINE([__STDC_NO_VLA__], 1, + [Define to 1 if C does not support variable-length arrays, and + if the compiler does not already define this.]) + fi +]) |