#include "pdumper.h"
#include "atimer.h"
-/* CACHEABLE is ordinarily nothing, except it is 'volatile' if
- necessary to cajole GCC into not warning incorrectly that a
- variable should be volatile. */
-#if defined GCC_LINT || defined lint
-# define CACHEABLE volatile
-#else
-# define CACHEABLE /* empty */
-#endif
-
/* Non-nil means record all fset's and provide's, to be undone
if the file being autoloaded is not fully loaded.
They are recorded by being consed onto the front of Vautoload_queue:
usage: (progn BODY...) */)
(Lisp_Object body)
{
- Lisp_Object CACHEABLE val = Qnil;
+ Lisp_Object val = Qnil;
while (CONSP (body))
{
return internal_catch (tag, Fprogn, XCDR (args));
}
-/* Work around GCC bug 61118
- <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61118>. */
-#if GNUC_PREREQ (4, 9, 0)
-# pragma GCC diagnostic ignored "-Wclobbered"
-#endif
-
/* Assert that E is true, but do not evaluate E. Use this instead of
eassert (E) when E contains variables that might be clobbered by a
longjmp. */
internal_lisp_condition_case (Lisp_Object var, Lisp_Object bodyform,
Lisp_Object handlers)
{
- struct handler *oldhandlerlist = handlerlist;
- ptrdiff_t CACHEABLE clausenb = 0;
+ struct handler *volatile oldhandlerlist = handlerlist;
+
+ /* The number of non-success handlers, plus 1 for a sentinel. */
+ ptrdiff_t clausenb = 1;
var = maybe_remove_pos_from_symbol (var);
CHECK_TYPE (BARE_SYMBOL_P (var), Qsymbolp, var);
memory_full (SIZE_MAX);
Lisp_Object volatile *clauses = alloca (clausenb * sizeof *clauses);
clauses += clausenb;
+ *--clauses = make_fixnum (0);
for (Lisp_Object tail = handlers; CONSP (tail); tail = XCDR (tail))
{
Lisp_Object tem = XCAR (tail);
if (!(CONSP (tem) && EQ (XCAR (tem), QCsuccess)))
*--clauses = tem;
}
- for (ptrdiff_t i = 0; i < clausenb; i++)
+ Lisp_Object volatile var_volatile = var;
+ Lisp_Object val, handler_body;
+ for (Lisp_Object volatile *pcl = clauses; ; pcl++)
{
- Lisp_Object clause = clauses[i];
+ if (BASE_EQ (*pcl, make_fixnum (0)))
+ {
+ val = eval_sub (bodyform);
+ handlerlist = oldhandlerlist;
+ if (NILP (success_handler))
+ return val;
+#if GCC_LINT && __GNUC__ && !__clang__
+ /* This useless assignment pacifies GCC 14.2.1 x86-64
+ <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21161>. */
+ var = var_volatile;
+#endif
+ handler_body = XCDR (success_handler);
+ break;
+ }
+ Lisp_Object clause = *pcl;
Lisp_Object condition = CONSP (clause) ? XCAR (clause) : Qnil;
if (!CONSP (condition))
condition = list1 (condition);
struct handler *c = push_handler (condition, CONDITION_CASE);
+ Lisp_Object volatile *clauses_volatile = clauses;
if (sys_setjmp (c->jmp))
{
- Lisp_Object val = handlerlist->val;
- Lisp_Object volatile *chosen_clause = clauses;
- for (struct handler *h = handlerlist->next; h != oldhandlerlist;
- h = h->next)
+ var = var_volatile;
+ val = handlerlist->val;
+ Lisp_Object volatile *chosen_clause = clauses_volatile;
+ struct handler *oldh = oldhandlerlist;
+ for (struct handler *h = handlerlist->next; h != oldh; h = h->next)
chosen_clause++;
- Lisp_Object handler_body = XCDR (*chosen_clause);
- handlerlist = oldhandlerlist;
-
- if (NILP (var))
- return Fprogn (handler_body);
+ handler_body = XCDR (*chosen_clause);
+ handlerlist = oldh;
- Lisp_Object handler_var = var;
- if (!NILP (Vinternal_interpreter_environment))
- {
- val = Fcons (Fcons (var, val),
- Vinternal_interpreter_environment);
- handler_var = Qinternal_interpreter_environment;
- }
-
- /* Bind HANDLER_VAR to VAL while evaluating HANDLER_BODY.
- The unbind_to undoes just this binding; whoever longjumped
- to us unwound the stack to C->pdlcount before throwing. */
- specpdl_ref count = SPECPDL_INDEX ();
- specbind (handler_var, val);
- return unbind_to (count, Fprogn (handler_body));
+ /* Whoever longjumped to us unwound the stack to C->pdlcount before
+ throwing, so the unbind_to will undo just this binding. */
+ break;
}
}
- Lisp_Object CACHEABLE result = eval_sub (bodyform);
- handlerlist = oldhandlerlist;
- if (!NILP (success_handler))
- {
- if (NILP (var))
- return Fprogn (XCDR (success_handler));
+ if (NILP (var))
+ return Fprogn (handler_body);
- Lisp_Object handler_var = var;
- if (!NILP (Vinternal_interpreter_environment))
- {
- result = Fcons (Fcons (var, result),
- Vinternal_interpreter_environment);
- handler_var = Qinternal_interpreter_environment;
- }
-
- specpdl_ref count = SPECPDL_INDEX ();
- specbind (handler_var, result);
- return unbind_to (count, Fprogn (XCDR (success_handler)));
+ if (!NILP (Vinternal_interpreter_environment))
+ {
+ val = Fcons (Fcons (var, val),
+ Vinternal_interpreter_environment);
+ var = Qinternal_interpreter_environment;
}
- return result;
+
+ specpdl_ref count = SPECPDL_INDEX ();
+ specbind (var, val);
+ return unbind_to (count, Fprogn (handler_body));
}
/* Call the function BFUN with no arguments, catching errors within it
struct handler *
push_handler_nosignal (Lisp_Object tag_ch_val, enum handlertype handlertype)
{
- struct handler *CACHEABLE c = handlerlist->nextfree;
+ struct handler *c = handlerlist->nextfree;
if (!c)
{
c = malloc (sizeof *c);