all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Paul Eggert <eggert@cs.ucla.edu>
To: Pip Cet <pipcet@protonmail.com>, Eli Zaretskii <eliz@gnu.org>
Cc: sigve.indregard@pm.me, 71744@debbugs.gnu.org
Subject: bug#71744: 29.4; SIGSEGV during completion-at-point in lsp-mode with corfu and cape
Date: Fri, 16 Aug 2024 21:37:29 -0700	[thread overview]
Message-ID: <ea999bf1-670d-4f6e-9fbe-f7eee951f2d9@cs.ucla.edu> (raw)
In-Reply-To: <87h6bkjyj1.fsf@protonmail.com>

[-- Attachment #1: Type: text/plain, Size: 2475 bytes --]

On 2024-08-16 08:08, Pip Cet wrote:

> /* Work around GCC bug 54561.  */
> #if GNUC_PREREQ (4, 3, 0)
> # pragma GCC diagnostic ignored "-Wclobbered"
> #endif
> 
> which means we won't get any warnings at all about such bugs.
> 
> However, even with that part removed, I don't get a compiler warning
> about 'c'.

With that part removed I got a warning about 'kb', not 'c'. The 'kb' 
warning was a false positive, the 'c' warning a false negative. The most 
likely explanation, I think, is that GCC got confused and put the wrong 
identifier name in its diagnostic. This would help to explain a lot of 
the -Wclobbered false positives we've gotten over the years, which has 
caused us to ignore -Wclobbered.


> What's weird about this is that the store at +5463 that's causing our
> problem isn't necessary, and neither is the load at +5479. The variable
> in question, 'kb', is not marked volatile, so it seems strange to me it's
> stored, then loaded, unnecessarily.

My guess is that GCC internally coalesced the two variables, and got 
confused because one was clobbered and the other was not, and issued a 
warning that it clobbered the variable but mistakenly said 'kb' not 'c'. 
The C standard entitles GCC to clobber 'c' so this isn't wrong code, 
it's just a bad (a *really* bad) diagnostic.


> Paul, do you agree that we should simply mark 'c' as volatile, or do you
> think this needs further investigation on the GCC side (because of the
> lack of a -Wclobbered warning being issued, or because of the weird
> code)?

We definitely should mark 'c' as volatile, or do something equivalent, 
because the Emacs code violates the C standard.

Also, if my hypothesis of the mistaken identifier is correct, we should 
stop ignoring -Wclobbered, and instead pacify GCC without using 
-Wclobbered. That way, when we screw up in setjmp related code, we'll 
get *some* warning that *something* is being clobbered, and can investigate.

To do that, I installed the attached patches into the Emacs master 
branch. While looking into this I noticed several uses of clobbered 
variables (i.e., violations of the C standard) and fixed them. Patches 
0001-0004 fix these similar bugs elsewhere. Patch 0005 implements your 
suggestion and should fix Bug#71744. Patch 0006 is a minor performance 
improvement over Patch 0005.

Please give these patches a try. Patch 0005 is simple and if it works 
for the original bug reporter we should be able to close the bug report 
as fixed.

[-- Attachment #2: 0001-Don-t-ignore-Wclobbered-in-bytecode.c.patch --]
[-- Type: text/x-patch, Size: 3451 bytes --]

From 2169a9387a5ac22b969d37ece4ec1aaa0fd830d9 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Fri, 16 Aug 2024 16:29:51 -0700
Subject: [PATCH 1/6] =?UTF-8?q?Don=E2=80=99t=20ignore=20-Wclobbered=20in?=
 =?UTF-8?q?=20bytecode.c?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This fix is prompted by Emacs bug#71744.
The working hypothesis is that there are some bugs in Emacs,
and some in GCC’s diagnostics, and that this patch
fixes the Emacs bugs and works around the GCC diagnostic bugs.
The hypothesis is that GCC diagnostic bugs occur when GCC
coalesces variables or temporaries and some variables
are clobbered by setjmp and some vars/temps are not.
Part of this hypothesis involves GCC diagnosing the wrong variables.
Instead of ignoring the diagnostics, which the hypothesis suggests
indicate either problems in Emacs or in GCC, fix the Emacs bugs
and pacify the GCC false positives, with comments about the GCC bugs.
GCC’s true positives are helpful enough in squashing obscure bugs like
Emacs bug#71744, that it’s worth going to some effort to pacify
-Wclobbered instead of ignoring it.
* src/bytecode.c: Do not ignore -Wclobbered.
(exec_byte_code): Fix violations of the C standard, where setjmp
clobbered quitcounter and bc.  If GCC_LINT && __GNUC__ && !__clang__,
work around GCC -Wclobbered warnings for bytestr_data and vectorp.
---
 src/bytecode.c | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/src/bytecode.c b/src/bytecode.c
index ce075c86afd..48a29c22d55 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -29,11 +29,6 @@
 #include "window.h"
 #include "puresize.h"
 
-/* Work around GCC bug 54561.  */
-#if GNUC_PREREQ (4, 3, 0)
-# pragma GCC diagnostic ignored "-Wclobbered"
-#endif
-
 /* Define BYTE_CODE_SAFE true to enable some minor sanity checking,
    useful for debugging the byte compiler.  It defaults to false.  */
 
@@ -536,6 +531,12 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
     for (ptrdiff_t i = nargs - rest; i < nonrest; i++)
       PUSH (Qnil);
 
+  unsigned char volatile saved_quitcounter;
+#if GCC_LINT && __GNUC__ && !__clang__
+  Lisp_Object *volatile saved_vectorp;
+  unsigned char const *volatile saved_bytestr_data;
+#endif
+
   while (true)
     {
       int op;
@@ -967,15 +968,23 @@ #define DEFINE(name, value) [name] = &&insn_ ## name,
 
 	    if (sys_setjmp (c->jmp))
 	      {
+		quitcounter = saved_quitcounter;
 		struct handler *c = handlerlist;
 		handlerlist = c->next;
 		top = c->bytecode_top;
 		op = c->bytecode_dest;
+		bc = &current_thread->bc;
 		struct bc_frame *fp = bc->fp;
 
 		Lisp_Object fun = fp->fun;
 		Lisp_Object bytestr = AREF (fun, CLOSURE_CODE);
 		Lisp_Object vector = AREF (fun, CLOSURE_CONSTANTS);
+#if GCC_LINT && __GNUC__ && !__clang__
+		/* These useless assignments pacify GCC 14.2.1 x86-64
+		   <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21161>.  */
+		bytestr_data = saved_bytestr_data;
+		vectorp = saved_vectorp;
+#endif
 		bytestr_data = SDATA (bytestr);
 		vectorp = XVECTOR (vector)->contents;
 		if (BYTE_CODE_SAFE)
@@ -989,6 +998,11 @@ #define DEFINE(name, value) [name] = &&insn_ ## name,
 		goto op_branch;
 	      }
 
+	    saved_quitcounter = quitcounter;
+#if GCC_LINT && __GNUC__ && !__clang__
+	    saved_vectorp = vectorp;
+	    saved_bytestr_data = bytestr_data;
+#endif
 	    NEXT;
 	  }
 
-- 
2.43.0


[-- Attachment #3: 0002-Don-t-ignore-Wclobbered-in-emacs-module.c.patch --]
[-- Type: text/x-patch, Size: 3138 bytes --]

From cfa5a634e91f5c232a71ec212679165074dc480b Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Fri, 16 Aug 2024 16:59:08 -0700
Subject: [PATCH 2/6] =?UTF-8?q?Don=E2=80=99t=20ignore=20-Wclobbered=20in?=
 =?UTF-8?q?=20emacs-module.c?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This fix is also prompted by Emacs bug#71744.
* src/emacs-module.c: Do not ignore -Wclobbered.
(MODULE_HANDLE_NONLOCAL_EXIT): Fix violations of the C standard,
where setjmp clobbered env and internal_cleanup.
(module_extract_big_integer) [GCC_LINT && __GNUC__ && !__clang__]:
Work around GCC -Wclobbered false positive for ‘sign’.
---
 src/emacs-module.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/emacs-module.c b/src/emacs-module.c
index 05aa0baef74..5aa4cfa0ae8 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -96,11 +96,6 @@ Copyright (C) 2015-2024 Free Software Foundation, Inc.
 #include <intprops.h>
 #include <verify.h>
 
-/* Work around GCC bug 83162.  */
-#if GNUC_PREREQ (4, 3, 0)
-# pragma GCC diagnostic ignored "-Wclobbered"
-#endif
-
 /* We use different strategies for allocating the user-visible objects
    (struct emacs_runtime, emacs_env, emacs_value), depending on
    whether the user supplied the -module-assertions flag.  If
@@ -273,14 +268,17 @@ #define MODULE_HANDLE_NONLOCAL_EXIT(retval)                             \
       module_out_of_memory (env);					\
       return retval;							\
     }									\
-  struct handler *internal_cleanup                                      \
+  emacs_env *env_volatile = env;					\
+  struct handler *volatile internal_cleanup				\
     = internal_handler;                                                 \
-  if (sys_setjmp (internal_cleanup->jmp))                               \
+  if (sys_setjmp (internal_handler->jmp))				\
     {									\
+      emacs_env *env = env_volatile;					\
+      struct handler *internal_handler = internal_cleanup;	\
       module_handle_nonlocal_exit (env,                                 \
-                                   internal_cleanup->nonlocal_exit,     \
-                                   internal_cleanup->val);              \
-      module_reset_handlerlist (internal_cleanup);			\
+				   internal_handler->nonlocal_exit,     \
+				   internal_handler->val);              \
+      module_reset_handlerlist (internal_handler);			\
       return retval;							\
     }									\
   do { } while (false)
@@ -1045,6 +1043,15 @@ verify ((sizeof (emacs_limb_t) == 4 && EMACS_LIMB_MAX == 0xFFFFFFFF)
 module_extract_big_integer (emacs_env *env, emacs_value arg, int *sign,
                             ptrdiff_t *count, emacs_limb_t *magnitude)
 {
+#if GCC_LINT && __GNUC__ && !__clang__
+  /* These useless assignments pacify GCC 14.2.1 x86-64
+     <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21161>.  */
+  {
+    int *volatile sign_volatile = sign;
+    sign = sign_volatile;
+  }
+#endif
+
   MODULE_FUNCTION_BEGIN (false);
   Lisp_Object o = value_to_lisp (arg);
   CHECK_INTEGER (o);
-- 
2.43.0


[-- Attachment #4: 0003-Don-t-ignore-Wclobbered-in-eval.c.patch --]
[-- Type: text/x-patch, Size: 7071 bytes --]

From 1282714da55cd4bbc1c7f2e49edeb43503427e5e Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Fri, 16 Aug 2024 17:08:36 -0700
Subject: [PATCH 3/6] =?UTF-8?q?Don=E2=80=99t=20ignore=20-Wclobbered=20in?=
 =?UTF-8?q?=20eval.c?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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 @@ Copyright (C) 1985-1987, 1993-1995, 1999-2024 Free Software Foundation,
 #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 @@ DEFUN ("catch", Fcatch, Scatch, 1, UNEVALLED, 0,
   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 @@ DEFUN ("handler-bind-1", Fhandler_bind_1, Shandler_bind_1, 1, MANY, 0,
 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);
-- 
2.43.0


[-- Attachment #5: 0004-Don-t-ignore-Wclobbered-in-image.c.patch --]
[-- Type: text/x-patch, Size: 5402 bytes --]

From 3b24ac538858d994a74826361a1af3f802dd065a Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Fri, 16 Aug 2024 17:19:12 -0700
Subject: [PATCH 4/6] =?UTF-8?q?Don=E2=80=99t=20ignore=20-Wclobbered=20in?=
 =?UTF-8?q?=20image.c?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This fix is also prompted by Emacs bug#71744.
* src/image.c: Do not ignore -Wclobbered.
(png_load_body): Fix violations of the C standard, where setjmp
clobbered c.  Move mask_img decl to pacify GCC.
(jpeg_load_body): Don’t make fp volatile; solve that problem in a
better way, via a new fp_volatile local.  Fix violations of the C
standard, where setjmp clobbered mgr, img, and ximg.  If __GNUC__
&& !__clang__, add useless assignments to pacify GCC.
---
 src/image.c | 44 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 35 insertions(+), 9 deletions(-)

diff --git a/src/image.c b/src/image.c
index 3965a6ce6f8..48694a13341 100644
--- a/src/image.c
+++ b/src/image.c
@@ -63,11 +63,6 @@ Copyright (C) 1989-2024 Free Software Foundation, Inc.
 #include TERM_HEADER
 #endif /* HAVE_WINDOW_SYSTEM */
 
-/* Work around GCC bug 54561.  */
-#if GNUC_PREREQ (4, 3, 0)
-# pragma GCC diagnostic ignored "-Wclobbered"
-#endif
-
 #ifdef HAVE_X_WINDOWS
 typedef struct x_bitmap_record Bitmap_Record;
 #ifndef USE_CAIRO
@@ -8188,7 +8183,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
   bool transparent_p;
   struct png_memory_storage tbr;  /* Data to be read */
   ptrdiff_t nbytes;
-  Emacs_Pix_Container ximg, mask_img = NULL;
+  Emacs_Pix_Container ximg;
 
   /* Find out what file to load.  */
   specified_file = image_spec_value (img->spec, QCfile, NULL);
@@ -8279,9 +8274,12 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
 
   /* Set error jump-back.  We come back here when the PNG library
      detects an error.  */
+
+  struct png_load_context *volatile c_volatile = c;
   if (FAST_SETJMP (PNG_JMPBUF (png_ptr)))
     {
     error:
+      c = c_volatile;
       if (c->png_ptr)
 	png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
       xfree (c->pixels);
@@ -8291,6 +8289,13 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
       return 0;
     }
 
+#if GCC_LINT && __GNUC__ && !__clang__
+  /* These useless assignments pacify GCC 14.2.1 x86-64
+     <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21161>.  */
+  c = c_volatile;
+  fp = c->fp;
+#endif
+
   /* Read image info.  */
   if (!NILP (specified_data))
     png_set_read_fn (png_ptr, &tbr, png_read_from_memory);
@@ -8417,6 +8422,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
 
   /* Create an image and pixmap serving as mask if the PNG image
      contains an alpha channel.  */
+  Emacs_Pix_Container mask_img = NULL;
   if (channels == 4
       && transparent_p
       && !image_create_x_image_and_pixmap (f, img, width, height, 1,
@@ -8912,13 +8918,13 @@ jpeg_load_body (struct frame *f, struct image *img,
 		struct my_jpeg_error_mgr *mgr)
 {
   Lisp_Object specified_file, specified_data;
-  FILE *volatile fp = NULL;
+  FILE *fp = NULL;
   JSAMPARRAY buffer;
   int row_stride, x, y;
   int width, height;
   int i, ir, ig, ib;
   unsigned long *colors;
-  Emacs_Pix_Container ximg = NULL;
+  Emacs_Pix_Container volatile ximg_volatile = NULL;
 
   /* Open the JPEG file.  */
   specified_file = image_spec_value (img->spec, QCfile, NULL);
@@ -8953,8 +8959,15 @@ jpeg_load_body (struct frame *f, struct image *img,
      error is detected.  This function will perform a longjmp.  */
   mgr->cinfo.err = jpeg_std_error (&mgr->pub);
   mgr->pub.error_exit = my_error_exit;
+  struct my_jpeg_error_mgr *volatile mgr_volatile = mgr;
+  struct image *volatile img_volatile = img;
+  FILE *volatile fp_volatile = fp;
   if (sys_setjmp (mgr->setjmp_buffer))
     {
+      mgr = mgr_volatile;
+      img = img_volatile;
+      fp = fp_volatile;
+
       switch (mgr->failure_code)
 	{
 	case MY_JPEG_ERROR_EXIT:
@@ -8980,6 +8993,7 @@ jpeg_load_body (struct frame *f, struct image *img,
       jpeg_destroy_decompress (&mgr->cinfo);
 
       /* If we already have an XImage, free that.  */
+      Emacs_Pix_Container ximg = ximg_volatile;
       if (ximg)
 	image_destroy_x_image (ximg);
       /* Free pixmap and colors.  */
@@ -8987,6 +9001,14 @@ jpeg_load_body (struct frame *f, struct image *img,
       return 0;
     }
 
+#if GCC_LINT && __GNUC__ && !__clang__
+  /* These useless assignments pacify GCC 14.2.1 x86-64
+     <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21161>.  */
+  mgr = mgr_volatile;
+  img = img_volatile;
+  fp = fp_volatile;
+#endif
+
   /* Create the JPEG decompression object.  Let it read from fp.
 	 Read the JPEG image header.  */
   jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo);
@@ -9013,7 +9035,11 @@ jpeg_load_body (struct frame *f, struct image *img,
     }
 
   /* Create X image and pixmap.  */
-  if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
+  Emacs_Pix_Container ximg;
+  bool ximg_ok = image_create_x_image_and_pixmap (f, img, width, height, 0,
+						  &ximg, 0);
+  ximg_volatile = ximg;
+  if (!ximg_ok)
     {
       mgr->failure_code = MY_JPEG_CANNOT_CREATE_X;
       sys_longjmp (mgr->setjmp_buffer, 1);
-- 
2.43.0


[-- Attachment #6: 0005-Don-t-ignore-Wclobbered-in-keyboard.c.patch --]
[-- Type: text/x-patch, Size: 1398 bytes --]

From a967efdd2a5b77e35657f9bdd7098b79241e3aa5 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Fri, 16 Aug 2024 17:20:58 -0700
Subject: [PATCH 5/6] =?UTF-8?q?Don=E2=80=99t=20ignore=20-Wclobbered=20in?=
 =?UTF-8?q?=20keyboard.c?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This fixes Emacs bug#71744.
* src/keyboard.c: Do not ignore -Wclobbered.
(read_char): Fix violation of the C standard, where setjmp
clobbered c.  Fix suggested by Pip Cet in
<https://debbugs.gnu.org/cgi/bugreport.cgi?bug=71744#38>
---
 src/keyboard.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/src/keyboard.c b/src/keyboard.c
index b312d529e59..b519ccdf9f0 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -88,11 +88,6 @@ Copyright (C) 1985-1989, 1993-1997, 1999-2024 Free Software Foundation,
 #include TERM_HEADER
 #endif /* HAVE_WINDOW_SYSTEM */
 
-/* Work around GCC bug 54561.  */
-#if GNUC_PREREQ (4, 3, 0)
-# pragma GCC diagnostic ignored "-Wclobbered"
-#endif
-
 #ifdef WINDOWSNT
 char const DEV_TTY[] = "CONOUT$";
 #else
@@ -2522,7 +2517,7 @@ read_char (int commandflag, Lisp_Object map,
 	   Lisp_Object prev_event,
 	   bool *used_mouse_menu, struct timespec *end_time)
 {
-  Lisp_Object c;
+  Lisp_Object volatile c;
   sys_jmp_buf local_getcjmp;
   sys_jmp_buf save_jump;
   Lisp_Object tem, save;
-- 
2.43.0


[-- Attachment #7: 0006-Tune-volatile-in-read_char.patch --]
[-- Type: text/x-patch, Size: 3680 bytes --]

From 8c81818673ae9ff788c6e65fb90984f327b27964 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Fri, 16 Aug 2024 19:02:55 -0700
Subject: [PATCH 6/6] Tune volatile in read_char

* src/keyboard.c (read_char): Optimize access to a local volatile.
---
 src/keyboard.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/src/keyboard.c b/src/keyboard.c
index b519ccdf9f0..0d3506bc59b 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -2517,7 +2517,7 @@ read_char (int commandflag, Lisp_Object map,
 	   Lisp_Object prev_event,
 	   bool *used_mouse_menu, struct timespec *end_time)
 {
-  Lisp_Object volatile c;
+  Lisp_Object c;
   sys_jmp_buf local_getcjmp;
   sys_jmp_buf save_jump;
   Lisp_Object tem, save;
@@ -2752,8 +2752,10 @@ read_char (int commandflag, Lisp_Object map,
      it *must not* be in effect when we call redisplay.  */
 
   specpdl_ref jmpcount = SPECPDL_INDEX ();
+  Lisp_Object volatile c_volatile;
   if (sys_setjmp (local_getcjmp))
     {
+      c = c_volatile;
       /* Handle quits while reading the keyboard.  */
       /* We must have saved the outer value of getcjmp here,
 	 so restore it now.  */
@@ -2798,6 +2800,13 @@ read_char (int commandflag, Lisp_Object map,
       goto non_reread;
     }
 
+  c_volatile = c;
+#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>.  */
+  c = c_volatile;
+#endif
+
   /* Start idle timers if no time limit is supplied.  We don't do it
      if a time limit is supplied to avoid an infinite recursion in the
      situation where an idle timer calls `sit-for'.  */
@@ -2959,6 +2968,8 @@ read_char (int commandflag, Lisp_Object map,
 	    }
 	  reread = true;
 	}
+
+      c_volatile = c;
     }
 
   /* Read something from current KBOARD's side queue, if possible.  */
@@ -2970,6 +2981,7 @@ read_char (int commandflag, Lisp_Object map,
 	  if (!CONSP (KVAR (current_kboard, kbd_queue)))
 	    emacs_abort ();
 	  c = XCAR (KVAR (current_kboard, kbd_queue));
+	  c_volatile = c;
 	  kset_kbd_queue (current_kboard,
 			  XCDR (KVAR (current_kboard, kbd_queue)));
 	  if (NILP (KVAR (current_kboard, kbd_queue)))
@@ -3025,6 +3037,8 @@ read_char (int commandflag, Lisp_Object map,
 	  c = XCDR (c);
 	  recorded = true;
 	}
+
+      c_volatile = c;
   }
 
  non_reread:
@@ -3108,7 +3122,7 @@ read_char (int commandflag, Lisp_Object map,
 	  d = Faref (KVAR (current_kboard, Vkeyboard_translate_table), c);
 	  /* nil in keyboard-translate-table means no translation.  */
 	  if (!NILP (d))
-	    c = d;
+	    c_volatile = c = d;
 	}
     }
 
@@ -3148,6 +3162,7 @@ read_char (int commandflag, Lisp_Object map,
 	      Vunread_command_events = Fcons (c, Vunread_command_events);
 	    }
 	  c = posn;
+	  c_volatile = c;
 	}
     }
 
@@ -3273,6 +3288,7 @@ read_char (int commandflag, Lisp_Object map,
 	}
       /* It returned one event or more.  */
       c = XCAR (tem);
+      c_volatile = c;
       Vunread_post_input_method_events
 	= nconc2 (XCDR (tem), Vunread_post_input_method_events);
     }
@@ -3347,6 +3363,7 @@ read_char (int commandflag, Lisp_Object map,
       do
 	{
 	  c = read_char (0, Qnil, Qnil, 0, NULL);
+	  c_volatile = c;
 	  if (EVENT_HAS_PARAMETERS (c)
 	      && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_click))
 	    XSETCAR (help_form_saved_window_configs, Qnil);
@@ -3360,7 +3377,7 @@ read_char (int commandflag, Lisp_Object map,
 	{
 	  cancel_echoing ();
 	  do
-	    c = read_char (0, Qnil, Qnil, 0, NULL);
+	    c_volatile = c = read_char (0, Qnil, Qnil, 0, NULL);
 	  while (BUFFERP (c));
 	}
     }
-- 
2.43.0


  reply	other threads:[~2024-08-17  4:37 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-23 21:16 bug#71744: 29.4; SIGSEGV during completion-at-point in lsp-mode with corfu and cape Matthew Rothlisberger
2024-06-24 12:28 ` Eli Zaretskii
2024-06-26 23:27   ` Matthew Rothlisberger
2024-06-27 10:05     ` Eli Zaretskii
2024-08-14 13:22 ` Sigve Indregard via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-14 13:57   ` Eli Zaretskii
2024-08-14 15:40     ` Sigve Indregard via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-14 16:03       ` Eli Zaretskii
2024-08-14 16:22         ` Eli Zaretskii
2024-08-14 16:37           ` Sigve Indregard via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-14 17:03           ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-15  9:07           ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-16 15:08             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-17  4:37               ` Paul Eggert [this message]
2024-08-17  6:14                 ` Eli Zaretskii
2024-08-17 18:23                   ` Paul Eggert
2024-08-17  7:46                 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-17 18:27                   ` Paul Eggert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ea999bf1-670d-4f6e-9fbe-f7eee951f2d9@cs.ucla.edu \
    --to=eggert@cs.ucla.edu \
    --cc=71744@debbugs.gnu.org \
    --cc=eliz@gnu.org \
    --cc=pipcet@protonmail.com \
    --cc=sigve.indregard@pm.me \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.