summaryrefslogtreecommitdiff
path: root/src/eval.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2016-07-24 11:10:09 +0200
committerPaul Eggert <eggert@cs.ucla.edu>2016-07-25 00:38:34 +0200
commit50cc08bf6e6cdc96dcdcbef388cf9cf76a15f81a (patch)
tree9cfd5f799262e0ba85d7213113bdb20302196e74 /src/eval.c
parent2c2b0cd07c143e33af9f7237ef4819c28764a90f (diff)
‘signal’ no longer returns
Although for decades ‘signal’ has been documented to not return, a corner case in the Lisp debugger causes ‘signal’ to return. Remove the corner case and adjust Emacs internals accordingly. An alternative would be to document the corner case, but this would complicate the Lisp API unnecessarily. (Bug#24047) * src/eval.c (signal_or_quit): New function, with most of the old contents of Fsignal. (quit): New function, which uses signal_or_quit and which might return. All keyboard-based callers of Fsignal (Qquit, Qnil) changed to use this new function instead. (Fsignal): Use signal_or_quit. Now _Noreturn. All callers changed. (xsignal): Move to lisp.h. * src/lisp.h (xsignal): Now an inline function, as it's now just an alias for Fsignal.
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/src/eval.c b/src/eval.c
index 72facd5db6..33b82f74b6 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1431,6 +1431,7 @@ push_handler_nosignal (Lisp_Object tag_ch_val, enum handlertype handlertype)
}
+static Lisp_Object signal_or_quit (Lisp_Object, Lisp_Object, bool);
static Lisp_Object find_handler_clause (Lisp_Object, Lisp_Object);
static bool maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig,
Lisp_Object data);
@@ -1444,7 +1445,7 @@ process_quit_flag (void)
Fkill_emacs (Qnil);
if (EQ (Vthrow_on_input, flag))
Fthrow (Vthrow_on_input, Qt);
- Fsignal (Qquit, Qnil);
+ quit ();
}
DEFUN ("signal", Fsignal, Ssignal, 2, 2, 0,
@@ -1460,9 +1461,29 @@ DATA should be a list. Its elements are printed as part of the error message.
See Info anchor `(elisp)Definition of signal' for some details on how this
error message is constructed.
If the signal is handled, DATA is made available to the handler.
-See also the function `condition-case'. */)
+See also the function `condition-case'. */
+ attributes: noreturn)
(Lisp_Object error_symbol, Lisp_Object data)
{
+ signal_or_quit (error_symbol, data, false);
+ eassume (false);
+}
+
+/* Quit, in response to a keyboard quit request. */
+Lisp_Object
+quit (void)
+{
+ return signal_or_quit (Qquit, Qnil, true);
+}
+
+/* Signal an error, or quit. ERROR_SYMBOL and DATA are as with Fsignal.
+ If KEYBOARD_QUIT, this is a quit; ERROR_SYMBOL should be
+ Qquit and DATA should be Qnil, and this function may return.
+ Otherwise this function is like Fsignal and does not return. */
+
+static Lisp_Object
+signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
+{
/* When memory is full, ERROR-SYMBOL is nil,
and DATA is (REAL-ERROR-SYMBOL . REAL-DATA).
That is a special case--don't do this in other situations. */
@@ -1542,7 +1563,7 @@ See also the function `condition-case'. */)
= maybe_call_debugger (conditions, error_symbol, data);
/* We can't return values to code which signaled an error, but we
can continue code which has signaled a quit. */
- if (debugger_called && EQ (real_error_symbol, Qquit))
+ if (keyboard_quit && debugger_called && EQ (real_error_symbol, Qquit))
return Qnil;
}
@@ -1569,16 +1590,6 @@ See also the function `condition-case'. */)
fatal ("%s", SDATA (string));
}
-/* Internal version of Fsignal that never returns.
- Used for anything but Qquit (which can return from Fsignal). */
-
-void
-xsignal (Lisp_Object error_symbol, Lisp_Object data)
-{
- Fsignal (error_symbol, data);
- emacs_abort ();
-}
-
/* Like xsignal, but takes 0, 1, 2, or 3 args instead of a list. */
void