[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 1282714da55 3/7: Don’t ignore -Wclobbered in eval.c
From: |
Paul Eggert |
Subject: |
master 1282714da55 3/7: Don’t ignore -Wclobbered in eval.c |
Date: |
Sat, 17 Aug 2024 00:16:47 -0400 (EDT) |
branch: master
commit 1282714da55cd4bbc1c7f2e49edeb43503427e5e
Author: Paul Eggert <eggert@cs.ucla.edu>
Commit: Paul Eggert <eggert@cs.ucla.edu>
Don’t ignore -Wclobbered in eval.c
This fix is also prompted by Emacs bug#71744.
* src/eval.c (CACHEABLE): Remove. All uses removed.
Do not ignore -Wclobbered.
(internal_lisp_condition_case): Fix violations of the C standard,
where setjmp clobbered oldhandlerlist, var, and clauses.
Rewrite to pacify GCC, by using a sentinel rather than a count,
which GCC incorrectly complained about, and by coalescing some
duplicate code. If GCC_LINT && __GNUC__ && !__clang__ add a useless
assignment to pacify GCC.
---
src/eval.c | 109 ++++++++++++++++++++++++++-----------------------------------
1 file changed, 47 insertions(+), 62 deletions(-)
diff --git a/src/eval.c b/src/eval.c
index b4103acd28f..ce7b08e894a 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -31,15 +31,6 @@ along with GNU Emacs. If not, see
<https://www.gnu.org/licenses/>. */
#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:
@@ -430,7 +421,7 @@ DEFUN ("progn", Fprogn, Sprogn, 0, UNEVALLED, 0,
usage: (progn BODY...) */)
(Lisp_Object body)
{
- Lisp_Object CACHEABLE val = Qnil;
+ Lisp_Object val = Qnil;
while (CONSP (body))
{
@@ -1257,12 +1248,6 @@ usage: (catch TAG 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. */
@@ -1488,8 +1473,10 @@ Lisp_Object
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);
@@ -1521,69 +1508,67 @@ internal_lisp_condition_case (Lisp_Object var,
Lisp_Object bodyform,
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
@@ -1740,7 +1725,7 @@ push_handler (Lisp_Object tag_ch_val, enum handlertype
handlertype)
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);
- master updated (909d1d02db1 -> ed305c4b98c), Paul Eggert, 2024/08/17
- master ed305c4b98c 7/7: Fix x_construct_mouse_click || vs | typo, Paul Eggert, 2024/08/17
- master 2169a9387a5 1/7: Don’t ignore -Wclobbered in bytecode.c, Paul Eggert, 2024/08/17
- master 1282714da55 3/7: Don’t ignore -Wclobbered in eval.c,
Paul Eggert <=
- master 8c81818673a 6/7: Tune volatile in read_char, Paul Eggert, 2024/08/17
- master cfa5a634e91 2/7: Don’t ignore -Wclobbered in emacs-module.c, Paul Eggert, 2024/08/17
- master 3b24ac53885 4/7: Don’t ignore -Wclobbered in image.c, Paul Eggert, 2024/08/17
- master a967efdd2a5 5/7: Don’t ignore -Wclobbered in keyboard.c, Paul Eggert, 2024/08/17