summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndrea Corallo <akrl@sdf.org>2020-08-29 11:33:37 +0200
committerAndrea Corallo <akrl@sdf.org>2020-08-29 11:33:37 +0200
commitc3514a6274cd6c6ddf2c133ccc708b7875aab90e (patch)
tree5f76eefdfef645bca9bc8640accb77c53704116a /lib
parentaa526c9470d679e9144af55d9e56928a111d2ceb (diff)
parent7d5807277ff614a337c7e4530bb8d0e0188c189b (diff)
downloademacs-c3514a6274cd6c6ddf2c133ccc708b7875aab90e.tar.gz
Merge remote-tracking branch 'savannah/master' into HEAD
Diffstat (limited to 'lib')
-rw-r--r--lib/cdefs.h6
-rw-r--r--lib/diffseq.h128
-rw-r--r--lib/gnulib.mk.in16
-rw-r--r--lib/intprops.h15
-rw-r--r--lib/sig2str.c17
-rw-r--r--lib/sigdescr_np.c376
-rw-r--r--lib/string.in.h15
-rw-r--r--lib/verify.h45
8 files changed, 558 insertions, 60 deletions
diff --git a/lib/cdefs.h b/lib/cdefs.h
index b1870fd0a93..ff7c628a264 100644
--- a/lib/cdefs.h
+++ b/lib/cdefs.h
@@ -148,7 +148,11 @@
# define __warnattr(msg) __attribute__((__warning__ (msg)))
# define __errordecl(name, msg) \
extern void name (void) __attribute__((__error__ (msg)))
-#elif __glibc_clang_has_attribute (__diagnose_if__) && 0 /* fails on Fedora 31 with Clang 9. */
+#elif __glibc_clang_has_attribute (__diagnose_if__) && 0
+/* These definitions are not enabled, because they produce bogus warnings
+ in the glibc Fortify functions. These functions are written in a style
+ that works with GCC. In order to work with clang, these functions would
+ need to be modified. */
# define __warndecl(name, msg) \
extern void name (void) __attribute__((__diagnose_if__ (1, msg, "warning")))
# define __warnattr(msg) __attribute__((__diagnose_if__ (1, msg, "warning")))
diff --git a/lib/diffseq.h b/lib/diffseq.h
index c89363ac9ee..26e10bdd043 100644
--- a/lib/diffseq.h
+++ b/lib/diffseq.h
@@ -51,10 +51,14 @@
EXTRA_CONTEXT_FIELDS Declarations of fields for 'struct context'.
NOTE_DELETE(ctxt, xoff) Record the removal of the object xvec[xoff].
NOTE_INSERT(ctxt, yoff) Record the insertion of the object yvec[yoff].
+ NOTE_ORDERED (Optional) A boolean expression saying that
+ NOTE_DELETE and NOTE_INSERT calls must be
+ issued in offset order.
EARLY_ABORT(ctxt) (Optional) A boolean expression that triggers an
early abort of the computation.
USE_HEURISTIC (Optional) Define if you want to support the
heuristic for large vectors.
+
It is also possible to use this file with abstract arrays. In this case,
xvec and yvec are not represented in memory. They only exist conceptually.
In this case, the list of defines above is amended as follows:
@@ -63,6 +67,7 @@
XVECREF_YVECREF_EQUAL(ctxt, xoff, yoff)
A three-argument macro: References xvec[xoff] and
yvec[yoff] and tests these elements for equality.
+
Before including this file, you also need to include:
#include <limits.h>
#include <stdbool.h>
@@ -78,6 +83,10 @@
# define EARLY_ABORT(ctxt) false
#endif
+#ifndef NOTE_ORDERED
+# define NOTE_ORDERED false
+#endif
+
/* Use this to suppress gcc's "...may be used before initialized" warnings.
Beware: The Code argument must not contain commas. */
#ifndef IF_LINT
@@ -88,15 +97,6 @@
# endif
#endif
-/* As above, but when Code must contain one comma. */
-#ifndef IF_LINT2
-# if defined GCC_LINT || defined lint
-# define IF_LINT2(Code1, Code2) Code1, Code2
-# else
-# define IF_LINT2(Code1, Code2) /* empty */
-# endif
-#endif
-
/*
* Context of comparison operation.
*/
@@ -468,49 +468,89 @@ compareseq (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim,
#define XREF_YREF_EQUAL(x,y) XVECREF_YVECREF_EQUAL (ctxt, x, y)
#endif
- /* Slide down the bottom initial diagonal. */
- while (xoff < xlim && yoff < ylim && XREF_YREF_EQUAL (xoff, yoff))
+ while (true)
{
- xoff++;
- yoff++;
- }
+ /* Slide down the bottom initial diagonal. */
+ while (xoff < xlim && yoff < ylim && XREF_YREF_EQUAL (xoff, yoff))
+ {
+ xoff++;
+ yoff++;
+ }
- /* Slide up the top initial diagonal. */
- while (xoff < xlim && yoff < ylim && XREF_YREF_EQUAL (xlim - 1, ylim - 1))
- {
- xlim--;
- ylim--;
- }
+ /* Slide up the top initial diagonal. */
+ while (xoff < xlim && yoff < ylim && XREF_YREF_EQUAL (xlim - 1, ylim - 1))
+ {
+ xlim--;
+ ylim--;
+ }
- /* Handle simple cases. */
- if (xoff == xlim)
- while (yoff < ylim)
- {
- NOTE_INSERT (ctxt, yoff);
- if (EARLY_ABORT (ctxt))
- return true;
- yoff++;
- }
- else if (yoff == ylim)
- while (xoff < xlim)
- {
- NOTE_DELETE (ctxt, xoff);
- if (EARLY_ABORT (ctxt))
- return true;
- xoff++;
- }
- else
- {
- struct partition part IF_LINT2 (= { .xmid = 0, .ymid = 0 });
+ /* Handle simple cases. */
+ if (xoff == xlim)
+ {
+ while (yoff < ylim)
+ {
+ NOTE_INSERT (ctxt, yoff);
+ if (EARLY_ABORT (ctxt))
+ return true;
+ yoff++;
+ }
+ break;
+ }
+ if (yoff == ylim)
+ {
+ while (xoff < xlim)
+ {
+ NOTE_DELETE (ctxt, xoff);
+ if (EARLY_ABORT (ctxt))
+ return true;
+ xoff++;
+ }
+ break;
+ }
+
+ struct partition part;
/* Find a point of correspondence in the middle of the vectors. */
diag (xoff, xlim, yoff, ylim, find_minimal, &part, ctxt);
/* Use the partitions to split this problem into subproblems. */
- if (compareseq (xoff, part.xmid, yoff, part.ymid, part.lo_minimal, ctxt))
- return true;
- if (compareseq (part.xmid, xlim, part.ymid, ylim, part.hi_minimal, ctxt))
- return true;
+ OFFSET xoff1, xlim1, yoff1, ylim1, xoff2, xlim2, yoff2, ylim2;
+ bool find_minimal1, find_minimal2;
+ if (!NOTE_ORDERED
+ && ((xlim + ylim) - (part.xmid + part.ymid)
+ < (part.xmid + part.ymid) - (xoff + yoff)))
+ {
+ /* The second problem is smaller and the caller doesn't
+ care about order, so do the second problem first to
+ lessen recursion. */
+ xoff1 = part.xmid; xlim1 = xlim;
+ yoff1 = part.ymid; ylim1 = ylim;
+ find_minimal1 = part.hi_minimal;
+
+ xoff2 = xoff; xlim2 = part.xmid;
+ yoff2 = yoff; ylim2 = part.ymid;
+ find_minimal2 = part.lo_minimal;
+ }
+ else
+ {
+ xoff1 = xoff; xlim1 = part.xmid;
+ yoff1 = yoff; ylim1 = part.ymid;
+ find_minimal1 = part.lo_minimal;
+
+ xoff2 = part.xmid; xlim2 = xlim;
+ yoff2 = part.ymid; ylim2 = ylim;
+ find_minimal2 = part.hi_minimal;
+ }
+
+ /* Recurse to do one subproblem. */
+ bool early = compareseq (xoff1, xlim1, yoff1, ylim1, find_minimal1, ctxt);
+ if (early)
+ return early;
+
+ /* Iterate to do the other subproblem. */
+ xoff = xoff2; xlim = xlim2;
+ yoff = yoff2; ylim = ylim2;
+ find_minimal = find_minimal2;
}
return false;
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index 78b4542d80a..f564d501222 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -136,6 +136,7 @@
# readlinkat \
# regex \
# sig2str \
+# sigdescr_np \
# socklen \
# stat-time \
# std-gnu11 \
@@ -426,6 +427,7 @@ GNULIB_SETENV = @GNULIB_SETENV@
GNULIB_SETHOSTNAME = @GNULIB_SETHOSTNAME@
GNULIB_SIGABBREV_NP = @GNULIB_SIGABBREV_NP@
GNULIB_SIGACTION = @GNULIB_SIGACTION@
+GNULIB_SIGDESCR_NP = @GNULIB_SIGDESCR_NP@
GNULIB_SIGNAL_H_SIGPIPE = @GNULIB_SIGNAL_H_SIGPIPE@
GNULIB_SIGPROCMASK = @GNULIB_SIGPROCMASK@
GNULIB_SLEEP = @GNULIB_SLEEP@
@@ -647,6 +649,7 @@ HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@
HAVE_SETSTATE = @HAVE_SETSTATE@
HAVE_SIGABBREV_NP = @HAVE_SIGABBREV_NP@
HAVE_SIGACTION = @HAVE_SIGACTION@
+HAVE_SIGDESCR_NP = @HAVE_SIGDESCR_NP@
HAVE_SIGHANDLER_T = @HAVE_SIGHANDLER_T@
HAVE_SIGINFO_T = @HAVE_SIGINFO_T@
HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
@@ -2312,6 +2315,17 @@ EXTRA_libgnu_a_SOURCES += sig2str.c
endif
## end gnulib module sig2str
+## begin gnulib module sigdescr_np
+ifeq (,$(OMIT_GNULIB_MODULE_sigdescr_np))
+
+
+EXTRA_DIST += sigdescr_np.c
+
+EXTRA_libgnu_a_SOURCES += sigdescr_np.c
+
+endif
+## end gnulib module sigdescr_np
+
## begin gnulib module signal-h
ifeq (,$(OMIT_GNULIB_MODULE_signal-h))
@@ -2846,6 +2860,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's/@''GNULIB_STRERROR''@/$(GNULIB_STRERROR)/g' \
-e 's/@''GNULIB_STRERROR_R''@/$(GNULIB_STRERROR_R)/g' \
-e 's/@''GNULIB_SIGABBREV_NP''@/$(GNULIB_SIGABBREV_NP)/g' \
+ -e 's/@''GNULIB_SIGDESCR_NP''@/$(GNULIB_SIGDESCR_NP)/g' \
-e 's/@''GNULIB_STRSIGNAL''@/$(GNULIB_STRSIGNAL)/g' \
-e 's/@''GNULIB_STRVERSCMP''@/$(GNULIB_STRVERSCMP)/g' \
< $(srcdir)/string.in.h | \
@@ -2869,6 +2884,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \
-e 's|@''HAVE_DECL_STRERROR_R''@|$(HAVE_DECL_STRERROR_R)|g' \
-e 's|@''HAVE_SIGABBREV_NP''@|$(HAVE_SIGABBREV_NP)|g' \
+ -e 's|@''HAVE_SIGDESCR_NP''@|$(HAVE_SIGDESCR_NP)|g' \
-e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \
-e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \
-e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \
diff --git a/lib/intprops.h b/lib/intprops.h
index f2f70b3e733..b27f2eea056 100644
--- a/lib/intprops.h
+++ b/lib/intprops.h
@@ -48,7 +48,7 @@
/* Minimum and maximum values for integer types and expressions. */
/* The width in bits of the integer type or expression T.
- Do not evaluate T.
+ Do not evaluate T. T must not be a bit-field expression.
Padding bits are not supported; this is checked at compile-time below. */
#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)
@@ -70,7 +70,7 @@
? _GL_SIGNED_INT_MAXIMUM (e) \
: _GL_INT_NEGATE_CONVERT (e, 1))
#define _GL_SIGNED_INT_MAXIMUM(e) \
- (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH ((e) + 0) - 2)) - 1) * 2 + 1)
+ (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1)
/* Work around OpenVMS incompatibility with C99. */
#if !defined LLONG_MAX && defined __INT64_MAX
@@ -95,8 +95,9 @@
#endif
/* Return 1 if the integer type or expression T might be signed. Return 0
- if it is definitely unsigned. This macro does not evaluate its argument,
- and expands to an integer constant expression. */
+ if it is definitely unsigned. T must not be a bit-field expression.
+ This macro does not evaluate its argument, and expands to an
+ integer constant expression. */
#if _GL_HAVE___TYPEOF__
# define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t))
#else
@@ -109,6 +110,8 @@
#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485)
/* Bound on length of the string representing an integer type or expression T.
+ T must not be a bit-field expression.
+
Subtract 1 for the sign bit if T is signed, and then add 1 more for
a minus sign if needed.
@@ -120,7 +123,7 @@
+ _GL_SIGNED_TYPE_OR_EXPR (t))
/* Bound on buffer size needed to represent an integer type or expression T,
- including the terminating null. */
+ including the terminating null. T must not be a bit-field expression. */
#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
@@ -566,7 +569,7 @@
? (EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \
? (a) < (tmax) / (b) \
: ((INT_NEGATE_OVERFLOW (b) \
- ? _GL_INT_CONVERT (b, tmax) >> (TYPE_WIDTH (b) - 1) \
+ ? _GL_INT_CONVERT (b, tmax) >> (TYPE_WIDTH (+ (b)) - 1) \
: (tmax) / -(b)) \
<= -1 - (a))) \
: INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (b, tmin)) && (b) == -1 \
diff --git a/lib/sig2str.c b/lib/sig2str.c
index 905daea2f20..cf7c3bb5c38 100644
--- a/lib/sig2str.c
+++ b/lib/sig2str.c
@@ -189,6 +189,11 @@ static struct numname { int num; char const name[8]; } numname_table[] =
NUMNAME (STKFLT),
#endif
+ /* AIX 7. */
+#ifdef SIGCPUFAIL
+ NUMNAME (CPUFAIL),
+#endif
+
/* AIX 5L. */
#ifdef SIGDANGER
NUMNAME (DANGER),
@@ -229,7 +234,12 @@ static struct numname { int num; char const name[8]; } numname_table[] =
NUMNAME (WINDOW), /* Older name for SIGWINCH. */
#endif
- /* BeOS */
+ /* OpenBSD. */
+#ifdef SIGTHR
+ NUMNAME (THR),
+#endif
+
+ /* BeOS, Haiku */
#ifdef SIGKILLTHR
NUMNAME (KILLTHR),
#endif
@@ -239,6 +249,11 @@ static struct numname { int num; char const name[8]; } numname_table[] =
NUMNAME (DIL),
#endif
+ /* native Windows */
+#ifdef SIGBREAK
+ NUMNAME (BREAK),
+#endif
+
/* Korn shell and Bash, of uncertain vintage. */
{ 0, "EXIT" }
};
diff --git a/lib/sigdescr_np.c b/lib/sigdescr_np.c
new file mode 100644
index 00000000000..fc9cd3c2369
--- /dev/null
+++ b/lib/sigdescr_np.c
@@ -0,0 +1,376 @@
+/* English descriptions of signals.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2020. */
+
+#include <config.h>
+
+/* Specification. */
+#include <string.h>
+
+#include <signal.h>
+
+const char *
+sigdescr_np (int sig)
+{
+ /* Note: Some platforms (glibc, FreeBSD, NetBSD, OpenBSD, AIX, IRIX, Haiku,
+ Android) have an array 'sys_siglist'. (On AIX, you need to declare it
+ yourself, and it has fewer than NSIG elements.) Its contents varies
+ depending on the OS.
+ On other OSes, you can invoke strsignal (sig) in the C locale.
+ In the code below, we show the differences.
+ You can see how cryptic some of these strings are. We try to pick more
+ understandable wordings. */
+
+ switch (sig)
+ {
+ /* Signals specified by ISO C. */
+ case SIGABRT:
+ /* glibc: "Aborted". *BSD: "Abort trap". Solaris: "Abort". */
+ return "Aborted";
+ case SIGFPE:
+ /* glibc, *BSD: "Floating point exception". Solaris: "Arithmetic exception".
+ The latter is more correct, because of integer division by 0 or -1. */
+ return "Arithmetic exception";
+ case SIGILL:
+ return "Illegal instruction";
+ case SIGINT:
+ return "Interrupt";
+ case SIGSEGV:
+ return "Segmentation fault";
+ case SIGTERM:
+ return "Terminated";
+
+ /* Signals specified by POSIX.
+ <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html> */
+ #if defined SIGALRM
+ case SIGALRM:
+ return "Alarm clock";
+ #endif
+ #if defined SIGBUS
+ case SIGBUS:
+ return "Bus error";
+ #endif
+ #if defined SIGCHLD
+ case SIGCHLD:
+ /* glibc, *BSD: "Child exited". Solaris: "Child status changed". */
+ return "Child stopped or exited";
+ #endif
+ #if defined SIGCONT
+ case SIGCONT:
+ return "Continued";
+ #endif
+ #if defined SIGHUP
+ case SIGHUP:
+ return "Hangup";
+ #endif
+ #if defined SIGKILL
+ case SIGKILL:
+ return "Killed";
+ #endif
+ #if defined SIGPIPE
+ case SIGPIPE:
+ return "Broken pipe";
+ #endif
+ #if defined SIGQUIT
+ case SIGQUIT:
+ return "Quit";
+ #endif
+ #if defined SIGSTOP
+ case SIGSTOP:
+ /* glibc, Solaris: "Stopped (signal)". *BSD: "Suspended (signal)". */
+ return "Stopped (signal)";
+ #endif
+ #if defined SIGTSTP
+ case SIGTSTP:
+ /* glibc: "Stopped". *BSD: "Suspended". Solaris: "Stopped (user)". */
+ return "Stopped";
+ #endif
+ #if defined SIGTTIN
+ case SIGTTIN:
+ return "Stopped (tty input)";
+ #endif
+ #if defined SIGTTOU
+ case SIGTTOU:
+ return "Stopped (tty output)";
+ #endif
+ #if defined SIGUSR1
+ case SIGUSR1:
+ /* glibc, *BSD: "User defined signal 1". Solaris: "User signal 1". */
+ return "User defined signal 1";
+ #endif
+ #if defined SIGUSR2
+ case SIGUSR2:
+ /* glibc, *BSD: "User defined signal 2". Solaris: "User signal 2". */
+ return "User defined signal 2";
+ #endif
+ #if defined SIGPOLL
+ case SIGPOLL:
+ /* glibc: "I/O possible". Solaris: "Pollable event". */
+ return "I/O possible";
+ #endif
+ #if defined SIGPROF
+ case SIGPROF:
+ return "Profiling timer expired";
+ #endif
+ #if defined SIGSYS
+ case SIGSYS:
+ return "Bad system call";
+ #endif
+ #if defined SIGTRAP
+ case SIGTRAP:
+ /* glibc, Solaris: "Trace/breakpoint trap". *BSD: "Trace/BPT trap". */
+ return "Trace/breakpoint trap";
+ #endif
+ #if defined SIGURG
+ case SIGURG:
+ /* glibc, *BSD: "Urgent I/O condition". Solaris: "Urgent socket condition". */
+ return "Urgent I/O condition";
+ #endif
+ #if defined SIGVTALRM
+ case SIGVTALRM:
+ return "Virtual timer expired";
+ #endif
+ #if defined SIGXCPU
+ case SIGXCPU:
+ /* glibc, *BSD: "CPU time limit exceeded". Solaris: "Cpu limit exceeded". */
+ return "CPU time limit exceeded";
+ #endif
+ #if defined SIGXFSZ
+ case SIGXFSZ:
+ return "File size limit exceeded";
+ #endif
+
+ /* Other signals on other systems. */
+ /* native Windows */
+ #if defined SIGBREAK
+ case SIGBREAK:
+ return "Ctrl-Break";
+ #endif
+ /* IRIX */
+ #if defined SIGCKPT
+ case SIGCKPT:
+ return "Checkpoint"; /* See man 1 cpr, man 3C atcheckpoint */
+ #endif
+ /* Linux, IRIX, Cygwin */
+ #if defined SIGCLD && SIGCLD != SIGCHLD
+ case SIGCLD:
+ return "Child stopped or exited";
+ #endif
+ /* AIX */
+ #if defined SIGCPUFAIL
+ case SIGCPUFAIL:
+ /* AIX: "CPU failure predicted". */
+ return "CPU going down"; /* See man bindprocessor */
+ #endif
+ /* AIX */
+ #if defined SIGDANGER
+ case SIGDANGER:
+ /* AIX: "Paging space low". */
+ return "Swap space nearly exhausted";
+ #endif
+ /* Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix, AIX, IRIX, Cygwin, mingw */
+ #if defined SIGEMT
+ case SIGEMT:
+ /* glibc/Hurd, *BSD: "EMT trap". Solaris: "Emulation trap". */
+ return "Instruction emulation needed";
+ #endif
+ /* Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix */
+ #if defined SIGINFO
+ case SIGINFO:
+ return "Information request";
+ #endif
+ /* Linux, Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix, AIX, IRIX, Cygwin */
+ #if defined SIGIO && SIGIO != SIGPOLL
+ case SIGIO:
+ return "I/O possible";
+ #endif
+ /* Linux, IRIX, Cygwin, mingw */
+ #if defined SIGIOT && SIGIOT != SIGABRT
+ case SIGIOT:
+ return "IOT instruction"; /* a PDP-11 instruction */
+ #endif
+ /* AIX */
+ #if defined SIGKAP
+ case SIGKAP:
+ /* Process must issue a KSKAPACK ioctl, or will be killed in 30 seconds. */
+ /* AIX: "Monitor mode granted". */
+ return "Keep Alive Poll";
+ #endif
+ /* Haiku */
+ #if defined SIGKILLTHR
+ case SIGKILLTHR:
+ return "Kill thread";
+ #endif
+ /* Minix */
+ #if defined SIGKMEM
+ case SIGKMEM:
+ return "Kernel memory request";
+ #endif
+ /* Minix */
+ #if defined SIGKMESS
+ case SIGKMESS:
+ return "Kernel message";
+ #endif
+ /* Minix */
+ #if defined SIGKSIG
+ case SIGKSIG:
+ return "Kernel signal";
+ #endif
+ /* Minix */
+ #if defined SIGKSIGSM
+ case SIGKSIGSM:
+ return "Kernel signal for signal manager";
+ #endif
+ /* FreeBSD */
+ #if defined SIGLIBRT
+ case SIGLIBRT:
+ return "Real-time library interrupt";
+ #endif
+ /* Cygwin */
+ #if defined SIGLOST && SIGLOST != SIGABRT && SIGLOST != SIGPWR
+ case SIGLOST:
+ /* Solaris: "Resource lost". */
+ return "File lock lost";
+ #endif
+ /* AIX */
+ #if defined SIGMIGRATE
+ case SIGMIGRATE:
+ return "Process migration";
+ #endif
+ /* AIX */
+ #if defined SIGMSG
+ case SIGMSG:
+ /* AIX: "Input device data". */
+ return "Message in the ring";
+ #endif
+ /* ACM */
+ #if defined SIGPLAN
+ case SIGPLAN:
+ return "Programming language anomaly";
+ #endif
+ /* AIX */
+ #if defined SIGPRE
+ case SIGPRE:
+ return "Programmed exception";
+ #endif
+ /* IRIX */
+ #if defined SIGPTINTR
+ case SIGPTINTR:
+ return "Pthread interrupt";
+ #endif
+ /* IRIX */
+ #if defined SIGPTRESCHED
+ case SIGPTRESCHED:
+ return "Pthread rescheduling";
+ #endif
+ /* Linux, NetBSD, Minix, AIX, IRIX, Cygwin */
+ #if defined SIGPWR
+ case SIGPWR:
+ /* glibc: "Power failure". NetBSD: "Power fail/restart". */
+ return "Power failure";
+ #endif
+ /* AIX */
+ #if defined SIGRECONFIG
+ case SIGRECONFIG:
+ return "Dynamic logical partitioning changed";
+ #endif
+ /* AIX */
+ #if defined SIGRECOVERY
+ case SIGRECOVERY:
+ return "Kernel recovery";
+ #endif
+ /* IRIX */
+ #if defined SIGRESTART
+ case SIGRESTART:
+ return "Checkpoint restart"; /* See man 1 cpr, man 3C atrestart */
+ #endif
+ /* AIX */
+ #if defined SIGRETRACT
+ case SIGRETRACT:
+ /* AIX: "Monitor mode retracted". */
+ return "Retracting Keep Alive Poll";
+ #endif
+ /* AIX */
+ #if defined SIGSAK
+ case SIGSAK:
+ /* AIX: "Secure attention". */
+ return "Secure Attention Key";
+ #endif
+ /* ACM */
+ #if defined SIGSAM
+ case SIGSAM:
+ return "Symbolic computation failed";
+ #endif
+ /* Minix */
+ #if defined SIGSNDELAY
+ case SIGSNDELAY:
+ return "Done sending message";
+ #endif
+ /* AIX */
+ #if defined SIGSOUND
+ case SIGSOUND:
+ /* AIX: "Sound completed". */
+ return "Sound configuration changed";
+ #endif
+ /* Linux */
+ #if defined SIGSTKFLT
+ case SIGSTKFLT:
+ return "Stack fault";
+ #endif
+ /* AIX */
+ #if defined SIGSYSERROR
+ case SIGSYSERROR:
+ return "Kernel error";
+ #endif
+ /* AIX */
+ #if defined SIGTALRM
+ case SIGTALRM:
+ return "Thread alarm clock";
+ #endif
+ /* FreeBSD, OpenBSD */
+ #if defined SIGTHR
+ case SIGTHR:
+ /* OpenBSD: "Thread AST". */
+ return "Thread library interrupt";
+ #endif
+ /* IRIX */
+ #if defined SIGUME
+ case SIGUME:
+ return "Uncorrectable memory error";
+ #endif
+ /* AIX */
+ #if defined SIGVIRT
+ case SIGVIRT:
+ return "Virtual time alarm clock";
+ #endif
+ /* AIX */
+ #if defined SIGWAITING
+ case SIGWAITING:
+ /* AIX: "No runnable lwp". */
+ return "Thread waiting";
+ #endif
+ /* Linux, Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix, AIX, IRIX, Cygwin, Haiku */
+ #if defined SIGWINCH
+ case SIGWINCH:
+ /* glibc: "Window changed". *BSD: "Window size changed" or "Window size changes". */
+ return "Window size changed";
+ #endif
+
+ default:
+ return NULL;
+ }
+}
diff --git a/lib/string.in.h b/lib/string.in.h
index 5134e11289d..776133c5eba 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -1060,6 +1060,21 @@ _GL_WARN_ON_USE (sigabbrev_np, "sigabbrev_np is unportable - "
# endif
#endif
+/* Return an English description string for the signal number SIG. */
+#if @GNULIB_SIGDESCR_NP@
+# if ! @HAVE_SIGDESCR_NP@
+_GL_FUNCDECL_SYS (sigdescr_np, const char *, (int sig));
+# endif
+_GL_CXXALIAS_SYS (sigdescr_np, const char *, (int sig));
+_GL_CXXALIASWARN (sigdescr_np);
+#elif defined GNULIB_POSIXCHECK
+# undef sigdescr_np
+# if HAVE_RAW_DECL_SIGDESCR_NP
+_GL_WARN_ON_USE (sigdescr_np, "sigdescr_np is unportable - "
+ "use gnulib module sigdescr_np for portability");
+# endif
+#endif
+
#if @GNULIB_STRSIGNAL@
# if @REPLACE_STRSIGNAL@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
diff --git a/lib/verify.h b/lib/verify.h
index d485a0283a9..ca2a1540736 100644
--- a/lib/verify.h
+++ b/lib/verify.h
@@ -246,6 +246,13 @@ template <int w>
/* @assert.h omit start@ */
+#if defined __has_builtin
+/* <https://clang.llvm.org/docs/LanguageExtensions.html#builtin-functions> */
+# define _GL_HAS_BUILTIN_ASSUME __has_builtin (__builtin_assume)
+#else
+# define _GL_HAS_BUILTIN_ASSUME 0
+#endif
+
#if 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__))
# define _GL_HAS_BUILTIN_TRAP 1
#elif defined __has_builtin
@@ -305,14 +312,36 @@ template <int w>
Although assuming R can help a compiler generate better code or
diagnostics, performance can suffer if R uses hard-to-optimize
- features such as function calls not inlined by the compiler.
-
- Avoid Clang’s __builtin_assume, as clang 9.0.1 -Wassume can
- generate a bogus diagnostic "the argument to '__builtin_assume' has
- side effects that will be discarded" even when the argument has no
- side effects. */
-
-#if _GL_HAS_BUILTIN_UNREACHABLE
+ features such as function calls not inlined by the compiler. */
+
+/* Use __builtin_assume in preference to __builtin_unreachable, because
+ in clang versions 8.0.x and older, the definition based on
+ __builtin_assume has an effect on optimizations, whereas the definition
+ based on __builtin_unreachable does not. (GCC so far has only
+ __builtin_unreachable.) */
+#if _GL_HAS_BUILTIN_ASSUME
+/* Use __builtin_constant_p to help clang's data-flow analysis for the case
+ assume (0).
+ Use a temporary variable, to avoid a clang warning
+ "the argument to '__builtin_assume' has side effects that will be discarded"
+ if R contains invocations of functions not marked as 'const'.
+ The type of the temporary variable can't be __typeof__ (R), because that
+ does not work on bit field expressions. Use '_Bool' or 'bool' as type
+ instead. */
+# if defined __cplusplus
+# define assume(R) \
+ (__builtin_constant_p (R) && !(R) \
+ ? (void) __builtin_unreachable () \
+ : (void) ({ bool _gl_verify_temp = (R); \
+ __builtin_assume (_gl_verify_temp); }))
+# else
+# define assume(R) \
+ (__builtin_constant_p (R) && !(R) \
+ ? (void) __builtin_unreachable () \
+ : (void) ({ _Bool _gl_verify_temp = (R); \
+ __builtin_assume (_gl_verify_temp); }))
+# endif
+#elif _GL_HAS_BUILTIN_UNREACHABLE
# define assume(R) ((R) ? (void) 0 : __builtin_unreachable ())
#elif 1200 <= _MSC_VER
# define assume(R) __assume (R)