]> git.eshelyaron.com Git - emacs.git/commitdiff
‘signal’ no longer returns
authorPaul Eggert <eggert@cs.ucla.edu>
Sun, 24 Jul 2016 09:10:09 +0000 (11:10 +0200)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 24 Jul 2016 22:38:34 +0000 (00:38 +0200)
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.

13 files changed:
src/bytecode.c
src/charset.c
src/coding.c
src/eval.c
src/fileio.c
src/keyboard.c
src/lisp.h
src/nsmenu.m
src/term.c
src/w32fns.c
src/w32menu.c
src/xfns.c
src/xmenu.c

index 05bc9fcdb08c50c00056846e19ea5c35768125a9..ee1b79f182622706858fc7505bef146693fb9694 100644 (file)
@@ -386,7 +386,7 @@ relocate_byte_stack (void)
        Vquit_flag = Qnil;                              \
        if (EQ (Vthrow_on_input, flag))                 \
          Fthrow (Vthrow_on_input, Qt);                 \
-       Fsignal (Qquit, Qnil);                          \
+       quit ();                                        \
       }                                                        \
     else if (pending_signals)                          \
       process_pending_signals ();                      \
index 95a9c577d52867ed1a783a0be67041b3eb871c2c..05469aa2650e431b701983494709adca19f194cf 100644 (file)
@@ -843,9 +843,9 @@ usage: (define-charset-internal ...)  */)
   int nchars;
 
   if (nargs != charset_arg_max)
-    return Fsignal (Qwrong_number_of_arguments,
-                   Fcons (intern ("define-charset-internal"),
-                          make_number (nargs)));
+    Fsignal (Qwrong_number_of_arguments,
+            Fcons (intern ("define-charset-internal"),
+                   make_number (nargs)));
 
   attrs = Fmake_vector (make_number (charset_attr_max), Qnil);
 
index 29c90f0a401b9769b27c84719cb22b73e7a182a3..a8ddc8175659e356e36c9cf7728757efba643cae 100644 (file)
@@ -10546,9 +10546,9 @@ usage: (define-coding-system-internal ...)  */)
   return Qnil;
 
  short_args:
-  return Fsignal (Qwrong_number_of_arguments,
-                 Fcons (intern ("define-coding-system-internal"),
-                        make_number (nargs)));
+  Fsignal (Qwrong_number_of_arguments,
+          Fcons (intern ("define-coding-system-internal"),
+                 make_number (nargs)));
 }
 
 
index 72facd5db64c8452f1edba23074438291306b9a6..33b82f74b6451a6982a41ff2ae897f310b0936e1 100644 (file)
@@ -1431,6 +1431,7 @@ push_handler_nosignal (Lisp_Object tag_ch_val, enum handlertype handlertype)
 }
 
 \f
+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,8 +1461,28 @@ 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).
@@ -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
index b1f9d3cf73aaf6216802eeec6bd9e746412fa620..66ea761ca567c9650cab0a0fd28af20a5f925dd4 100644 (file)
@@ -4513,7 +4513,7 @@ by calling `format-decode', which see.  */)
                              PT - BEG, Z - PT - inserted);
 
   if (read_quit)
-    Fsignal (Qquit, Qnil);
+    quit ();
 
   /* Retval needs to be dealt with in all cases consistently.  */
   if (NILP (val))
index 8901ff055e7e69fd8e2beb9018ba89683daf70b2..ed4968486c3f6634c7a9ede383597d3c1591612b 100644 (file)
@@ -696,7 +696,7 @@ recursive_edit_1 (void)
 
   val = command_loop ();
   if (EQ (val, Qt))
-    Fsignal (Qquit, Qnil);
+    quit ();
   /* Handle throw from read_minibuf when using minibuffer
      while it's active but we're in another window.  */
   if (STRINGP (val))
@@ -7581,7 +7581,7 @@ menu_item_eval_property_1 (Lisp_Object arg)
   /* If we got a quit from within the menu computation,
      quit all the way out of it.  This takes care of C-] in the debugger.  */
   if (CONSP (arg) && EQ (XCAR (arg), Qquit))
-    Fsignal (Qquit, Qnil);
+    quit ();
 
   return Qnil;
 }
@@ -10407,7 +10407,7 @@ handle_interrupt (bool in_signal_handler)
          immediate_quit = false;
          pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
          saved = gl_state;
-         Fsignal (Qquit, Qnil);
+         quit ();
          gl_state = saved;
        }
       else
index 39877d7bb4d89cc1b3622211946014923a7f029e..089f3977cd244f9c7a53242859734c162142c53f 100644 (file)
@@ -3879,7 +3879,12 @@ extern void run_hook_with_args_2 (Lisp_Object, Lisp_Object, Lisp_Object);
 extern Lisp_Object run_hook_with_args (ptrdiff_t nargs, Lisp_Object *args,
                                       Lisp_Object (*funcall)
                                       (ptrdiff_t nargs, Lisp_Object *args));
-extern _Noreturn void xsignal (Lisp_Object, Lisp_Object);
+extern Lisp_Object quit (void);
+INLINE _Noreturn void
+xsignal (Lisp_Object error_symbol, Lisp_Object data)
+{
+  Fsignal (error_symbol, data);
+}
 extern _Noreturn void xsignal0 (Lisp_Object);
 extern _Noreturn void xsignal1 (Lisp_Object, Lisp_Object);
 extern _Noreturn void xsignal2 (Lisp_Object, Lisp_Object, Lisp_Object);
index 83ded6daca3bf7e030c36ae88cd7bf09ad129e77..d1f4b020bb07fd5429b0bd9676d13b8c69da4289 100644 (file)
@@ -1843,7 +1843,7 @@ ns_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
 
   if (EQ (ret, Qundefined) && window_closed)
     /* Make close button pressed equivalent to C-g.  */
-    Fsignal (Qquit, Qnil);
+    quit ();
 
   return ret;
 }
index 81908b370a5dc8a53af9626a461a1f09eed7657f..d54ff115f9d09b8bde061399305fc08b3e51e5a8 100644 (file)
@@ -3759,7 +3759,7 @@ tty_menu_show (struct frame *f, int x, int y, int menuflags,
       /* Make "Cancel" equivalent to C-g unless FOR_CLICK (which means
         the menu was invoked with a mouse event as POSITION).  */
       if (!(menuflags & MENU_FOR_CLICK))
-        Fsignal (Qquit, Qnil);
+       quit ();
       break;
     }
 
index d6b54d19a19953d9afed8add319e7f3ec4d02cb2..584e311230e640b5d639ffe35ac00ce4ee2d3e93 100644 (file)
@@ -7584,7 +7584,7 @@ value of DIR as in previous invocations; this is standard Windows behavior.  */)
 
   /* Make "Cancel" equivalent to C-g.  */
   if (NILP (filename))
-    Fsignal (Qquit, Qnil);
+    quit ();
 
   return filename;
 }
index 13296d9d855a77fd7c8aee28018e0218bb41fdc9..7c66360becdbb85106d6bb5f174cb42c0a3c78eb 100644 (file)
@@ -827,7 +827,7 @@ w32_menu_show (struct frame *f, int x, int y, int menuflags,
     {
       unblock_input ();
       /* Make "Cancel" equivalent to C-g.  */
-      Fsignal (Qquit, Qnil);
+      quit ();
     }
 
   unblock_input ();
@@ -1019,7 +1019,7 @@ w32_dialog_show (struct frame *f, Lisp_Object title,
     }
   else
     /* Make "Cancel" equivalent to C-g.  */
-    Fsignal (Qquit, Qnil);
+    quit ();
 
   return Qnil;
 }
@@ -1155,7 +1155,7 @@ simple_dialog_show (struct frame *f, Lisp_Object contents, Lisp_Object header)
   else if (answer == IDNO)
     lispy_answer = build_string ("No");
   else
-    Fsignal (Qquit, Qnil);
+    quit ();
 
   for (temp = XCDR (contents); CONSP (temp); temp = XCDR (temp))
     {
@@ -1177,8 +1177,7 @@ simple_dialog_show (struct frame *f, Lisp_Object contents, Lisp_Object header)
          return value;
        }
     }
-  Fsignal (Qquit, Qnil);
-  return Qnil;
+  return quit ();
 }
 #endif  /* !HAVE_DIALOGS  */
 \f
index 798dc49bef51555938f3141de0b359468afc6f56..c44997b3d6fea414014917917001c9a6428465c4 100644 (file)
@@ -6346,7 +6346,7 @@ value of DIR as in previous invocations; this is standard Windows behavior.  */)
 
   /* Make "Cancel" equivalent to C-g.  */
   if (NILP (file))
-    Fsignal (Qquit, Qnil);
+    quit ();
 
   decoded_file = DECODE_FILE (file);
 
@@ -6418,7 +6418,7 @@ value of DIR as in previous invocations; this is standard Windows behavior.  */)
 
   /* Make "Cancel" equivalent to C-g.  */
   if (NILP (file))
-    Fsignal (Qquit, Qnil);
+    quit ();
 
   decoded_file = DECODE_FILE (file);
 
@@ -6469,7 +6469,7 @@ nil, it defaults to the selected frame. */)
   unblock_input ();
 
   if (NILP (font))
-    Fsignal (Qquit, Qnil);
+    quit ();
 
   return unbind_to (count, font);
 }
index 9e1a817946af2e4116728ee173471f399e1b0d20..9ab7bdf971f49401a64cfb0e3a2f928bfae15662 100644 (file)
@@ -1649,7 +1649,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
     {
       unblock_input ();
       /* Make "Cancel" equivalent to C-g.  */
-      Fsignal (Qquit, Qnil);
+      quit ();
     }
 
   unblock_input ();
@@ -1913,7 +1913,7 @@ x_dialog_show (struct frame *f, Lisp_Object title,
     }
   else
     /* Make "Cancel" equivalent to C-g.  */
-    Fsignal (Qquit, Qnil);
+    quit ();
 
   return Qnil;
 }
@@ -2304,7 +2304,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
       if (!(menuflags & MENU_FOR_CLICK))
        {
          unblock_input ();
-         Fsignal (Qquit, Qnil);
+         quit ();
        }
       break;
     }