changeset 2268:61855263cb07

[xemacs-hg @ 2004-09-14 14:32:29 by james] Identify functions that don't return, including some DEFUNs.
author james
date Tue, 14 Sep 2004 14:33:07 +0000
parents 5753220a0f80
children e13775448cf0
files modules/ChangeLog modules/ldap/eldap.c src/ChangeLog src/buffer.c src/cmdloop.c src/commands.h src/compiler.h src/device-x.c src/emacs.c src/eval.c src/fns.c src/frame-gtk.c src/frame-x.c src/gif_io.c src/gifrlib.h src/lisp.h src/lread.c src/minibuf.c src/objects.c src/objects.h src/process-unix.c src/s/windowsnt.h src/search.c
diffstat 23 files changed, 206 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- a/modules/ChangeLog	Tue Sep 14 02:53:16 2004 +0000
+++ b/modules/ChangeLog	Tue Sep 14 14:33:07 2004 +0000
@@ -1,3 +1,7 @@
+2004-09-13  Jerry James  <james@xemacs.org>
+
+	* ldap/eldap.c (signal_ldap_error): Mark as noreturn.
+
 2004-03-22  Stephen J. Turnbull  <stephen@xemacs.org>
 
 	* XEmacs 21.5.17 "chayote" is released.
--- a/modules/ldap/eldap.c	Tue Sep 14 02:53:16 2004 +0000
+++ b/modules/ldap/eldap.c	Tue Sep 14 14:33:07 2004 +0000
@@ -68,7 +68,9 @@
 /*                         Utility Functions                            */
 /************************************************************************/
 
-static void
+static DECLARE_DOESNT_RETURN (signal_ldap_error (LDAP *, LDAPMessage *, int));
+
+static DOESNT_RETURN
 signal_ldap_error (LDAP *ld, LDAPMessage *res, int ldap_err)
 {
   if (ldap_err <= 0)
--- a/src/ChangeLog	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/ChangeLog	Tue Sep 14 14:33:07 2004 +0000
@@ -1,3 +1,55 @@
+2004-09-13  Jerry James  <james@xemacs.org>
+
+	* s/windowsnt.h: Define (DECLARE_)DOESNT_RETURN_TYPE instead of
+	(DECLARE_)DOESNT_RETURN.
+	* buffer.c (nsberror): Mark as noreturn.
+	* cmdloop.c (Fcommand_loop_1): Mark as noreturn when
+	!LISP_COMMAND_LOOP.
+	* cmdloop.c (Freally_early_error_handler): Mark as noreturn.  Use
+	RETURN_NOT_REACHED to quash compiler warnings.
+	* cmdloop.c (command_loop_3): Ditto.
+	* cmdloop.c (command_loop_2): Ditto.
+	* cmdloop.c (call_command_loop): Ditto, both versions.
+	* cmdloop.c (command_loop_1): Ditto, when !LISP_COMMAND_LOOP.
+	* cmdloop.c (Fcommand_loop_1): Ditto, when !LISP_COMMAND_LOOP.
+	* commands.h (call_command_loop): Declare as noreturn.
+	* compiler.h: Define (DECLARE_)DOESNT_RETURN_TYPE for functions
+	with non-void return types.  Use them to define
+	(DECLARE_)DOESNT_RETURN.
+	* device-x.c (x_IO_error_handler): Use RETURN_NOT_REACHED.
+	* emacs.c (Frun_emacs_from_temacs): Mark as noreturn.
+	* emacs.c (Fkill_emacs): Ditto.  Use RETURN_NOT_REACHED.
+	* eval.c (unwind_to_catch): Declare as noreturn.
+	* eval.c (throw_or_bomb_out): Ditto.  Remove comments about
+	warnings that will now not be generated.
+	* eval.c (Fthrow): Mark as noreturn.  Use RETURN_NOT_REACHED.
+	* eval.c (Fsignal): Use RETURN_NOT_REACHED.
+	* eval.c (flagged_a_squirmer): Mark as noreturn.  Use
+	RETURN_NOT_REACHED.
+	* fns.c (base64_conversion_error): Declare as noreturn.
+	* frame-gtk.c (gtk_cant_notify_wm_error): Ditto.
+	* frame-x.c (x_cant_notify_wm_error): Ditto.
+	* gif_io.c (GifError): Mark as noreturn.
+	* gif_io.c (GifInternError): Ditto.
+	* gifrlib.h (GifInternError): Declare as noreturn.
+	* gifrlib.h (GifError): Ditto.
+	* lisp.h (EXFUN_NORETURN): New macro.
+	* lisp.h (DEFUN_NORETURN): New macro.
+	* lisp.h (Fkill_emacs): Declare as noreturn.
+	* lisp.h (Fthrow): Ditto.
+	* lread.c (read_syntax_error): Ditto.
+	* minibuf.c (Fread_minibuffer_internal): Mark as noreturn.  Don't
+	bother calling specpdl_depth and unbind_to_1 since
+	call_command_loop never returns.
+	* objects.c (finalose): Mark as noreturn.
+	* objects.h (finalose): Declare as noreturn.
+	* process-unix.c (child_setup): Ditto.
+	* search.c (matcher_overflow): Ditto.
+	* search.c (signal_failure): Ditto.  Make the return type void and
+	remove the return statement.
+	* search.c (search_command): Change the use of signal_failure to
+	match, using RETURN_NOT_REACHED.
+
 2004-08-18  Felix H. Gatzemeier  <f.g@tzemeier.info>
 
 	* doprnt.c (emacs_doprnt_1): Use sprintf to format error messages
--- a/src/buffer.c	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/buffer.c	Tue Sep 14 14:33:07 2004 +0000
@@ -341,7 +341,9 @@
   return BUFFERP (object) && BUFFER_LIVE_P (XBUFFER (object)) ? Qt : Qnil;
 }
 
-static void
+static DECLARE_DOESNT_RETURN (nsberror (Lisp_Object));
+
+static DOESNT_RETURN
 nsberror (Lisp_Object spec)
 {
   if (STRINGP (spec))
--- a/src/cmdloop.c	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/cmdloop.c	Tue Sep 14 14:33:07 2004 +0000
@@ -70,8 +70,14 @@
 Lisp_Object Qtop_level;
 Lisp_Object Vminibuffer_echo_wait_function;
 
+#ifdef LISP_COMMAND_LOOP
 static Lisp_Object command_loop_1 (Lisp_Object dummy);
 EXFUN (Fcommand_loop_1, 0);
+#else
+static DECLARE_DOESNT_RETURN_TYPE (Lisp_Object,
+				   command_loop_1 (Lisp_Object dummy));
+EXFUN_NORETURN (Fcommand_loop_1, 0);
+#endif
 
 /* There are two possible command loops -- one written entirely in
    C and one written mostly in Lisp, except stuff written in C for
@@ -107,7 +113,8 @@
   return (unbind_to_1 (speccount, Qt));
 }
 
-DEFUN ("really-early-error-handler", Freally_early_error_handler, 1, 1, 0, /*
+DEFUN_NORETURN ("really-early-error-handler", Freally_early_error_handler,
+		1, 1, 0, /*
 You should almost certainly not be using this.
 */
        (x))
@@ -134,7 +141,8 @@
   Fmswindows_message_box (build_msg_string ("Initialization error"),
 			  Qnil, Qnil);
 #endif
-  return Fkill_emacs (make_int (-1));
+  Fkill_emacs (make_int (-1));
+  RETURN_NOT_REACHED (Qnil);
 }
 
 
@@ -236,6 +244,8 @@
    to condition_case_1() returns. */
 
 /* Avoid confusing the compiler. A helper function for command_loop_2 */
+static DECLARE_DOESNT_RETURN (command_loop_3 (void));
+
 static DOESNT_RETURN
 command_loop_3 (void)
 {
@@ -257,11 +267,13 @@
     }
 }
 
-static Lisp_Object
+static DECLARE_DOESNT_RETURN_TYPE (Lisp_Object, command_loop_2 (Lisp_Object));
+
+static DOESNT_RETURN_TYPE (Lisp_Object)
 command_loop_2 (Lisp_Object dummy)
 {
   command_loop_3(); /* doesn't return */
-  return Qnil;
+  RETURN_NOT_REACHED (Qnil);
 }
 
 /* This is called from emacs.c when it's done with initialization. */
@@ -314,14 +326,15 @@
 
    Note that this function never returns (but may be thrown out of). */
 
-Lisp_Object
+DOESNT_RETURN_TYPE (Lisp_Object)
 call_command_loop (Lisp_Object catch_errors)
 {
   /* This function can GC */
   if (NILP (catch_errors))
-    return (command_loop_1 (Qnil));
+    command_loop_1 (Qnil);
   else
-    return (command_loop_2 (Qnil));
+    command_loop_2 (Qnil);
+  RETURN_NOT_REACHED (Qnil);
 }
 
 static Lisp_Object
@@ -406,7 +419,7 @@
                             cold_load_command_error, Qnil));
 }
 
-Lisp_Object
+DOESNT_RETURN_TYPE (Lisp_Object)
 call_command_loop (Lisp_Object catch_errors)
 {
   /* This function can GC */
@@ -430,7 +443,7 @@
     internal_catch (Qtop_level,
                     cold_load_command_loop, Qnil, 0, 0);
   goto loop;
-  return Qnil;
+  RETURN_NOT_REACHED (Qnil);
 }
 
 static Lisp_Object
@@ -480,13 +493,22 @@
 /*                     Guts of command loop                           */
 /**********************************************************************/
 
+#ifdef LISP_COMMAND_LOOP
 static Lisp_Object
+#else
+static DOESNT_RETURN_TYPE (Lisp_Object)
+#endif
 command_loop_1 (Lisp_Object dummy)
 {
   /* This function can GC */
   /* #### not correct with Vselected_console */
   XCONSOLE (Vselected_console)->prefix_arg = Qnil;
-  return (Fcommand_loop_1 ());
+  Fcommand_loop_1 ();
+#ifdef LISP_COMMAND_LOOP
+  return Qnil;
+#else
+  RETURN_NOT_REACHED (Qnil);
+#endif
 }
 
 /* This is the actual command reading loop, sans error-handling
@@ -499,7 +521,13 @@
    command loop, this will return only when the user specifies
    a new command loop by changing the command-loop variable. */
 
-DEFUN ("command-loop-1", Fcommand_loop_1, 0, 0, 0, /*
+#ifdef LISP_COMMAND_LOOP
+#define DEFUN_COMMAND_LOOP(a,b,c,d,e,f) DEFUN (a, b, c, d, e, f)
+#else
+#define DEFUN_COMMAND_LOOP(a,b,c,d,e,f) DEFUN_NORETURN (a, b, c, d, e, f)
+#endif
+
+DEFUN_COMMAND_LOOP ("command-loop-1", Fcommand_loop_1, 0, 0, 0, /*
 Invoke the internals of the canonical editor command loop.
 Don't call this unless you know what you're doing.
 */
--- a/src/commands.h	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/commands.h	Tue Sep 14 14:33:07 2004 +0000
@@ -109,7 +109,8 @@
 extern Lisp_Object Vcommand_loop;
 /* #endif */
 DECLARE_DOESNT_RETURN (initial_command_loop (Lisp_Object));
-Lisp_Object call_command_loop (Lisp_Object catch_errors);
+DECLARE_DOESNT_RETURN_TYPE (Lisp_Object,
+			    call_command_loop (Lisp_Object catch_errors));
 extern Fixnum command_loop_level;
 
 extern Lisp_Object Vkeyboard_translate_table;
--- a/src/compiler.h	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/compiler.h	Tue Sep 14 14:33:07 2004 +0000
@@ -110,24 +110,25 @@
 # endif /* GNUC */
 #endif
 
-#ifndef DOESNT_RETURN
+#ifndef DOESNT_RETURN_TYPE
 # if (GCC_VERSION > NEED_GCC (0, 0, 0))
 #  if (GCC_VERSION >= NEED_GCC (2, 5, 0))
-#   if (GCC_VERSION < NEED_GCC (3, 0, 0))
-      /* GCC 3.2 -O3 issues complaints in Fcommand_loop_1 about no return
-	 statement if we have this definition */
-#    define RETURN_NOT_REACHED(value) DO_NOTHING
-#   endif
-#   define DOESNT_RETURN void
-#   define DECLARE_DOESNT_RETURN(decl) void decl __attribute__ ((noreturn))
+#   define RETURN_NOT_REACHED(value) DO_NOTHING
+#   define DOESNT_RETURN_TYPE(rettype) rettype
+#   define DECLARE_DOESNT_RETURN_TYPE(rettype,decl) rettype decl \
+	   __attribute__ ((noreturn))
 #  else /* GCC_VERSION < NEED_GCC (2, 5, 0) */
-#   define DOESNT_RETURN void volatile
-#   define DECLARE_DOESNT_RETURN(decl) void volatile decl
+#   define DOESNT_RETURN_TYPE(rettype) rettype volatile
+#   define DECLARE_DOESNT_RETURN_TYPE(rettype,decl) rettype volatile decl
 #  endif /* GCC_VERSION >= NEED_GCC (2, 5, 0) */
 # else /* not gcc */
-#  define DOESNT_RETURN void
-#  define DECLARE_DOESNT_RETURN(decl) void decl
+#  define DOESNT_RETURN_TYPE(rettype) rettype
+#  define DECLARE_DOESNT_RETURN_TYPE(rettype,decl) rettype decl
 # endif /* GCC_VERSION > NEED_GCC (0, 0, 0) */
+#endif /* DOESNT_RETURN_TYPE */
+#ifndef DOESNT_RETURN
+# define DOESNT_RETURN DOESNT_RETURN_TYPE (void)
+# define DECLARE_DOESNT_RETURN(decl) DECLARE_DOESNT_RETURN_TYPE (void, decl)
 #endif /* DOESNT_RETURN */
 
 /* Another try to fix SunPro C compiler warnings */
--- a/src/device-x.c	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/device-x.c	Tue Sep 14 14:33:07 2004 +0000
@@ -1195,7 +1195,7 @@
   DEVICE_X_BEING_DELETED (d) = 1;
   Fthrow (Qtop_level, Qnil);
 
-  return 0; /* not reached */
+  RETURN_NOT_REACHED (0);
 }
 
 DEFUN ("x-debug-mode", Fx_debug_mode, 1, 2, 0, /*
--- a/src/emacs.c	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/emacs.c	Tue Sep 14 14:33:07 2004 +0000
@@ -2682,7 +2682,7 @@
     return Fnreverse (plist);
 }
 
-DEFUN ("run-emacs-from-temacs", Frun_emacs_from_temacs, 0, MANY, 0, /*
+DEFUN_NORETURN ("run-emacs-from-temacs", Frun_emacs_from_temacs, 0, MANY, 0, /*
 Do not call this.  It will reinitialize your XEmacs.  You'll be sorry.
 */
 /* If this function is called from startup.el, it will be possible to run
@@ -3374,7 +3374,7 @@
 }
 #endif /* GNU_MALLOC */
 
-DEFUN ("kill-emacs", Fkill_emacs, 0, 1, "P", /*
+DEFUN_NORETURN ("kill-emacs", Fkill_emacs, 0, 1, "P", /*
 Exit the XEmacs job and kill it.  Ask for confirmation, without argument.
 If ARG is an integer, return ARG as the exit program code.
 If ARG is a string, stuff it as keyboard input.
@@ -3440,8 +3440,7 @@
 #endif
 
   exit (INTP (arg) ? XINT (arg) : 0);
-  /* NOTREACHED */
-  return Qnil; /* I'm sick of the compiler warning */
+  RETURN_NOT_REACHED (Qnil);
 }
 
 /* -------------------------------- */
--- a/src/eval.c	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/eval.c	Tue Sep 14 14:33:07 2004 +0000
@@ -1549,7 +1549,10 @@
 
    This is used for correct unwinding in Fthrow and Fsignal.  */
 
-static void
+static DECLARE_DOESNT_RETURN (unwind_to_catch (struct catchtag *, Lisp_Object,
+					       Lisp_Object));
+
+static DOESNT_RETURN
 unwind_to_catch (struct catchtag *c, Lisp_Object val, Lisp_Object tag)
 {
   REGISTER int last_time;
@@ -1630,6 +1633,9 @@
   LONGJMP (c->jmp, 1);
 }
 
+static DECLARE_DOESNT_RETURN (throw_or_bomb_out (Lisp_Object, Lisp_Object, int,
+						 Lisp_Object, Lisp_Object));
+
 static DOESNT_RETURN
 throw_or_bomb_out (Lisp_Object tag, Lisp_Object val, int bomb_out_p,
 		   Lisp_Object sig, Lisp_Object data)
@@ -1680,11 +1686,6 @@
       else
         call1 (Qreally_early_error_handler, Fcons (sig, data));
     }
-
-  /* can't happen.  who cares? - (Sun's compiler does) */
-  /* throw_level--; */
-  /* getting tired of compilation warnings */
-  /* return Qnil; */
 }
 
 /* See above, where CATCHLIST is defined, for a description of how
@@ -1706,14 +1707,14 @@
    condition_case_1).  See below for more info.
 */
 
-DEFUN ("throw", Fthrow, 2, 2, 0, /*
+DEFUN_NORETURN ("throw", Fthrow, 2, 2, 0, /*
 Throw to the catch for TAG and return VALUE from it.
 Both TAG and VALUE are evalled.
 */
        (tag, value))
 {
   throw_or_bomb_out (tag, value, 0, Qnil, Qnil); /* Doesn't return */
-  return Qnil;
+  RETURN_NOT_REACHED (Qnil);
 }
 
 DEFUN ("unwind-protect", Funwind_protect, 1, UNEVALLED, 0, /*
@@ -2391,7 +2392,7 @@
   UNGCPRO;
   throw_or_bomb_out (Qtop_level, Qt, 1, error_symbol,
 		     data); /* Doesn't return */
-  return Qnil;
+  RETURN_NOT_REACHED (Qnil);
 }
 
 /****************** Error functions class 1 ******************/
@@ -4813,7 +4814,10 @@
   void *arg;
 };
 
-static Lisp_Object
+static DECLARE_DOESNT_RETURN_TYPE
+  (Lisp_Object, flagged_a_squirmer (Lisp_Object, Lisp_Object, Lisp_Object));
+
+static DOESNT_RETURN_TYPE (Lisp_Object)
 flagged_a_squirmer (Lisp_Object error_conditions, Lisp_Object data,
 		    Lisp_Object opaque)
 {
@@ -4851,7 +4855,7 @@
   p->data = data;
 
   Fthrow (p->catchtag, Qnil);
-  return Qnil; /* not reached */
+  RETURN_NOT_REACHED (Qnil);
 }
 
 static Lisp_Object
--- a/src/fns.c	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/fns.c	Tue Sep 14 14:33:07 2004 +0000
@@ -3675,6 +3675,9 @@
    The octets are divided into 6 bit chunks, which are then encoded into
    base64 characters.  */
 
+static DECLARE_DOESNT_RETURN (base64_conversion_error (const char *,
+						       Lisp_Object));
+
 static DOESNT_RETURN
 base64_conversion_error (const char *reason, Lisp_Object frob)
 {
--- a/src/frame-gtk.c	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/frame-gtk.c	Tue Sep 14 14:33:07 2004 +0000
@@ -1233,8 +1233,10 @@
     return (1);
 }
 
-static void
-gtk_cant_notify_wm_error (void)
+static DECLARE_DOESNT_RETURN (gtk_cant_notify_wm_error (void));
+
+static DOESNT_RETURN
+gtk_cant_notify_wm_error ()
 {
   signal_error (Qgui_error, "Can't notify window manager of iconification", Qunbound);
 }
--- a/src/frame-x.c	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/frame-x.c	Tue Sep 14 14:33:07 2004 +0000
@@ -2408,8 +2408,10 @@
   return 1;
 }
 
-static void
-x_cant_notify_wm_error (void)
+static DECLARE_DOESNT_RETURN (x_cant_notify_wm_error (void));
+
+static DOESNT_RETURN
+x_cant_notify_wm_error ()
 {
   signal_error (Qgui_error, "Can't notify window manager of iconification", Qunbound);
 }
--- a/src/gif_io.c	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/gif_io.c	Tue Sep 14 14:33:07 2004 +0000
@@ -216,7 +216,7 @@
 /******************************
 * These are called internally *        
 ******************************/
-void GifError(GifFileType *GifFile, const char *err_str)
+DOESNT_RETURN GifError(GifFileType *GifFile, const char *err_str)
 {
   GifIODataType *GifIO = (GifIODataType*)GifFile->GifIO;
   if (GifIO->ErrorFunc)
@@ -233,7 +233,7 @@
     (*(GifIO->WarningFunc))(err_str, GifIO->WarningFunc_data);
 }
 
-void GifInternError(GifFileType *GifFile, int error_num)
+DOESNT_RETURN GifInternError(GifFileType *GifFile, int error_num)
 {
   const char *ErrStr = GetGifError(error_num);
   GifError(GifFile, ErrStr);
--- a/src/gifrlib.h	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/gifrlib.h	Tue Sep 14 14:33:07 2004 +0000
@@ -145,9 +145,11 @@
 ******************************************************************************/
 extern void GifSetErrorFunc(GifFileType *GifFile, Gif_error_func func, VoidPtr data);
 extern void GifSetWarningFunc(GifFileType *GifFile, Gif_error_func func, VoidPtr data);
-extern void GifInternError(GifFileType *GifFile, int errnum);
+extern DECLARE_DOESNT_RETURN (GifInternError(GifFileType *GifFile,
+					     int errnum));
 extern void GifInternWarning(GifFileType *GifFile, int errnum);
-extern void GifError(GifFileType *GifFile, const char *err_str);
+extern DECLARE_DOESNT_RETURN (GifError(GifFileType *GifFile,
+				       const char *err_str));
 extern void GifWarning(GifFileType *GifFile, const char *err_str);
 
 /*****************************************************************************
--- a/src/lisp.h	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/lisp.h	Tue Sep 14 14:33:07 2004 +0000
@@ -2767,6 +2767,8 @@
 #define EXFUN_MANY int, Lisp_Object*
 #define EXFUN_UNEVALLED Lisp_Object
 #define EXFUN(sym, max_args) Lisp_Object sym (EXFUN_##max_args)
+#define EXFUN_NORETURN(sym, max_args) \
+  DECLARE_DOESNT_RETURN_TYPE (Lisp_Object, sym (EXFUN_##max_args))
 
 #define SUBR_MAX_ARGS 8
 #define MANY -2
@@ -2795,6 +2797,26 @@
   };									\
   Lisp_Object Fname (DEFUN_##max_args arglist)
 
+#define DEFUN_NORETURN(lname, Fname, min_args, max_args, prompt, arglist) \
+  DECLARE_DOESNT_RETURN_TYPE (Lisp_Object, Fname (EXFUN_##max_args));	\
+  static struct Lisp_Subr S##Fname =					\
+  {									\
+    { /* struct lrecord_header */					\
+      lrecord_type_subr, /* lrecord_type_index */			\
+      1, /* mark bit */							\
+      1, /* c_readonly bit */						\
+      1, /* lisp_readonly bit */					\
+      0  /* unused */                                                   \
+    },									\
+    min_args,								\
+    max_args,								\
+    prompt,								\
+    0,	/* doc string */						\
+    lname,								\
+    (lisp_fn_t) Fname							\
+  };									\
+  DOESNT_RETURN_TYPE (Lisp_Object) Fname (DEFUN_##max_args arglist)
+
 /* Heavy ANSI C preprocessor hackery to get DEFUN to declare a
    prototype that matches max_args, and add the obligatory
    `Lisp_Object' type declaration to the formal C arguments.  */
@@ -3720,7 +3742,7 @@
 Lisp_Object save_current_buffer_restore (Lisp_Object);
 
 /* Defined in emacs.c */
-EXFUN (Fkill_emacs, 1);
+EXFUN_NORETURN (Fkill_emacs, 1);
 EXFUN (Frunning_temacs_p, 0);
 EXFUN (Fforce_debugging_signal, 1);
 
@@ -3760,7 +3782,7 @@
 EXFUN (Finteractive_p, 0);
 EXFUN (Fprogn, UNEVALLED);
 MODULE_API EXFUN (Fsignal, 2);
-MODULE_API EXFUN (Fthrow, 2);
+MODULE_API EXFUN_NORETURN (Fthrow, 2);
 MODULE_API EXFUN (Fcall_with_condition_handler, MANY);
 EXFUN (Ffunction_max_args, 1);
 EXFUN (Ffunction_min_args, 1);
--- a/src/lread.c	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/lread.c	Tue Sep 14 14:33:07 2004 +0000
@@ -218,6 +218,8 @@
 			      : (x))
 
 
+static DECLARE_DOESNT_RETURN (read_syntax_error (const char *));
+
 static DOESNT_RETURN
 read_syntax_error (const char *string)
 {
--- a/src/minibuf.c	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/minibuf.c	Tue Sep 14 14:33:07 2004 +0000
@@ -134,13 +134,18 @@
   return Qnil;
 }
 
-DEFUN ("read-minibuffer-internal", Fread_minibuffer_internal, 1, 1, 0, /*
+DEFUN_NORETURN ("read-minibuffer-internal", Fread_minibuffer_internal,
+		1, 1, 0, /*
 Lowest-level interface to minibuffers.  Don't call this.
 */
        (prompt))
 {
   /* This function can GC */
-  int speccount = specpdl_depth ();
+
+  /* We used to record the specpdl_depth here, but since call_command_loop
+     never returns, we can never call unbind_to_1.  Since we exit via a throw,
+     we let whoever catches unbind for us. */
+
   Lisp_Object val;
 
   CHECK_STRING (prompt);
@@ -188,7 +193,7 @@
 
   val = call_command_loop (Qt);
 
-  return unbind_to_1 (speccount, val);
+  RETURN_NOT_REACHED (val);
 }
 
 
--- a/src/objects.c	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/objects.c	Tue Sep 14 14:33:07 2004 +0000
@@ -45,12 +45,11 @@
 
 /* Authors: Ben Wing, Chuck Thompson */
 
-void
+DOESNT_RETURN
 finalose (void *ptr)
 {
   Lisp_Object obj = wrap_pointer_1 (ptr);
 
-
   invalid_operation
     ("Can't dump an emacs containing window system objects", obj);
 }
--- a/src/objects.h	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/objects.h	Tue Sep 14 14:33:07 2004 +0000
@@ -24,7 +24,7 @@
 #ifndef INCLUDED_objects_h_
 #define INCLUDED_objects_h_
 
-void finalose (void *ptr);
+DECLARE_DOESNT_RETURN (finalose (void *ptr));
 
 /****************************************************************************
  *                           Color Instance Object                          *
--- a/src/process-unix.c	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/process-unix.c	Tue Sep 14 14:33:07 2004 +0000
@@ -879,7 +879,10 @@
    XEmacs?), this should be verified as an executable directory by the
    parent.  */
 
-static void
+static DECLARE_DOESNT_RETURN (child_setup (int, int, int, Ibyte **,
+					   Lisp_Object));
+
+static DOESNT_RETURN
 child_setup (int in, int out, int err, Ibyte **new_argv,
 	     Lisp_Object current_dir)
 {
--- a/src/s/windowsnt.h	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/s/windowsnt.h	Tue Sep 14 14:33:07 2004 +0000
@@ -241,8 +241,9 @@
 
 /* MSVC 6.0 has a mechanism to declare functions which never return */
 #if (_MSC_VER >= 1200)
-#define DOESNT_RETURN __declspec(noreturn) void
-#define DECLARE_DOESNT_RETURN(decl) __declspec(noreturn) extern void XCDECL decl
+#define DOESNT_RETURN_TYPE(rettype) __declspec(noreturn) rettype
+#define DECLARE_DOESNT_RETURN_TYPE(rettype,decl) \
+  __declspec(noreturn) extern rettype XCDECL decl
 #endif /* MSVC 6.0 */
 
 /* MSVC warnings no-no crap.  When adding one to this section,
--- a/src/search.c	Tue Sep 14 02:53:16 2004 +0000
+++ b/src/search.c	Tue Sep 14 14:33:07 2004 +0000
@@ -137,8 +137,10 @@
 			       int RE, Lisp_Object trt,
 			       Lisp_Object inverse_trt, int posix);
 
-static void
-matcher_overflow (void)
+static DECLARE_DOESNT_RETURN (matcher_overflow (void));
+
+static DOESNT_RETURN
+matcher_overflow ()
 {
   stack_overflow ("Stack overflow in regexp matcher", Qunbound);
 }
@@ -243,12 +245,13 @@
 /* Error condition used for failing searches */
 Lisp_Object Qsearch_failed;
 
-static Lisp_Object
+static DECLARE_DOESNT_RETURN (signal_failure (Lisp_Object));
+
+static DOESNT_RETURN
 signal_failure (Lisp_Object arg)
 {
   for (;;)
     Fsignal (Qsearch_failed, list1 (arg));
-  return Qnil; /* Not reached. */
 }
 
 /* Convert the search registers from Bytebpos's to Charbpos's.  Needs to be
@@ -1159,7 +1162,10 @@
   if (np <= 0)
     {
       if (NILP (noerror))
-	return signal_failure (string);
+	{
+	  signal_failure (string);
+	  RETURN_NOT_REACHED (Qnil);
+	}
       if (!EQ (noerror, Qt))
 	{
 	  if (lim < BUF_BEGV (buf) || lim > BUF_ZV (buf))