diff options
| author | Paul Eggert | 2014-08-30 15:59:39 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-08-30 15:59:39 -0700 |
| commit | f9caea823350640fb03195c73c301f08ce932bd0 (patch) | |
| tree | be0e02155cf2f218c61379dde8ac98f100553392 /lib | |
| parent | 88366fcf88e5bccc4d0bcff798beb3ef27aaa496 (diff) | |
| download | emacs-f9caea823350640fb03195c73c301f08ce932bd0.tar.gz emacs-f9caea823350640fb03195c73c301f08ce932bd0.zip | |
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 'lib')
| -rw-r--r-- | lib/gnulib.mk | 11 | ||||
| -rw-r--r-- | lib/stdlib.in.h | 23 | ||||
| -rw-r--r-- | lib/vla.h | 27 |
3 files changed, 60 insertions, 1 deletions
diff --git a/lib/gnulib.mk b/lib/gnulib.mk index 9e9b9ebd6de..5ba7de10d0b 100644 --- a/lib/gnulib.mk +++ b/lib/gnulib.mk | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | # the same distribution terms as the rest of that program. | 21 | # the same distribution terms as the rest of that program. |
| 22 | # | 22 | # |
| 23 | # Generated by gnulib-tool. | 23 | # Generated by gnulib-tool. |
| 24 | # Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=stdarg --avoid=stdbool --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode fstatat fsync getloadavg getopt-gnu gettime gettimeofday intprops largefile lstat manywarnings memrchr mkostemp mktime pipe2 pselect pthread_sigmask putenv qacl readlink readlinkat sig2str socklen stat-time stdalign stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub unsetenv update-copyright utimens warnings | 24 | # Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=stdarg --avoid=stdbool --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode fstatat fsync getloadavg getopt-gnu gettime gettimeofday intprops largefile lstat manywarnings memrchr mkostemp mktime pipe2 pselect pthread_sigmask putenv qacl readlink readlinkat sig2str socklen stat-time stdalign stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub unsetenv update-copyright utimens vla warnings |
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | MOSTLYCLEANFILES += core *.stackdump | 27 | MOSTLYCLEANFILES += core *.stackdump |
| @@ -1141,6 +1141,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ | |||
| 1141 | -e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \ | 1141 | -e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \ |
| 1142 | -e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \ | 1142 | -e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \ |
| 1143 | -e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/g' \ | 1143 | -e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/g' \ |
| 1144 | -e 's/@''GNULIB_QSORT_R''@/$(GNULIB_QSORT_R)/g' \ | ||
| 1144 | -e 's/@''GNULIB_RANDOM''@/$(GNULIB_RANDOM)/g' \ | 1145 | -e 's/@''GNULIB_RANDOM''@/$(GNULIB_RANDOM)/g' \ |
| 1145 | -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \ | 1146 | -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \ |
| 1146 | -e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \ | 1147 | -e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \ |
| @@ -1192,6 +1193,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ | |||
| 1192 | -e 's|@''REPLACE_PTSNAME''@|$(REPLACE_PTSNAME)|g' \ | 1193 | -e 's|@''REPLACE_PTSNAME''@|$(REPLACE_PTSNAME)|g' \ |
| 1193 | -e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \ | 1194 | -e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \ |
| 1194 | -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \ | 1195 | -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \ |
| 1196 | -e 's|@''REPLACE_QSORT_R''@|$(REPLACE_QSORT_R)|g' \ | ||
| 1195 | -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \ | 1197 | -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \ |
| 1196 | -e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \ | 1198 | -e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \ |
| 1197 | -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \ | 1199 | -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \ |
| @@ -1798,6 +1800,13 @@ EXTRA_DIST += verify.h | |||
| 1798 | 1800 | ||
| 1799 | ## end gnulib module verify | 1801 | ## end gnulib module verify |
| 1800 | 1802 | ||
| 1803 | ## begin gnulib module vla | ||
| 1804 | |||
| 1805 | |||
| 1806 | EXTRA_DIST += vla.h | ||
| 1807 | |||
| 1808 | ## end gnulib module vla | ||
| 1809 | |||
| 1801 | ## begin gnulib module xalloc-oversized | 1810 | ## begin gnulib module xalloc-oversized |
| 1802 | 1811 | ||
| 1803 | if gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec | 1812 | if gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec |
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index 46e10dba972..ee643247d85 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h | |||
| @@ -520,6 +520,29 @@ _GL_CXXALIAS_SYS (putenv, int, (char *string)); | |||
| 520 | _GL_CXXALIASWARN (putenv); | 520 | _GL_CXXALIASWARN (putenv); |
| 521 | #endif | 521 | #endif |
| 522 | 522 | ||
| 523 | #if @GNULIB_QSORT_R@ | ||
| 524 | # if @REPLACE_QSORT_R@ | ||
| 525 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 526 | # undef qsort_r | ||
| 527 | # define qsort_r rpl_qsort_r | ||
| 528 | # endif | ||
| 529 | _GL_FUNCDECL_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size, | ||
| 530 | int (*compare) (void const *, void const *, | ||
| 531 | void *), | ||
| 532 | void *arg) _GL_ARG_NONNULL ((1, 4))); | ||
| 533 | _GL_CXXALIAS_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size, | ||
| 534 | int (*compare) (void const *, void const *, | ||
| 535 | void *), | ||
| 536 | void *arg)); | ||
| 537 | # else | ||
| 538 | _GL_CXXALIAS_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size, | ||
| 539 | int (*compare) (void const *, void const *, | ||
| 540 | void *), | ||
| 541 | void *arg)); | ||
| 542 | # endif | ||
| 543 | _GL_CXXALIASWARN (qsort_r); | ||
| 544 | #endif | ||
| 545 | |||
| 523 | 546 | ||
| 524 | #if @GNULIB_RANDOM_R@ | 547 | #if @GNULIB_RANDOM_R@ |
| 525 | # if !@HAVE_RANDOM_R@ | 548 | # if !@HAVE_RANDOM_R@ |
diff --git a/lib/vla.h b/lib/vla.h new file mode 100644 index 00000000000..05125a7978e --- /dev/null +++ b/lib/vla.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | /* vla.h - variable length arrays | ||
| 2 | |||
| 3 | Copyright 2014 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This program is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 3 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | |||
| 18 | Written by Paul Eggert. */ | ||
| 19 | |||
| 20 | /* A function's argument must point to an array with at least N elements. | ||
| 21 | Example: 'int main (int argc, char *argv[VLA_ELEMS (argc)]);'. */ | ||
| 22 | |||
| 23 | #ifdef __STDC_NO_VLA__ | ||
| 24 | # define VLA_ELEMS(n) | ||
| 25 | #else | ||
| 26 | # define VLA_ELEMS(n) static n | ||
| 27 | #endif | ||