1From 12cd30dbe088f20a2953985ca1612cb6a539700d Mon Sep 17 00:00:00 2001
2From: Joseph Myers <joseph@codesourcery.com>
3Date: Fri, 30 Oct 2020 21:38:31 +0000
4Subject: [PATCH 05/20] Disable spurious -Wstringop-overflow for setjmp/longjmp
5 (bug 26647)
6
7Building glibc with GCC 11 fails with (among other warnings) spurious
8-Wstringop-overflow warnings from calls to setjmp and longjmp with a
9pointer to a pthread_unwind_buf that is smaller than jmp_buf.  As
10discussed in bug 26647, the warning in libc-start.c is a false
11positive, because setjmp and longjmp do not access anything (the
12signal mask) beyond the common prefix of the two structures, so this
13patch disables the warning for that call to setjmp, as well as for two
14calls in NPTL code that produce the same warning and look like false
15positives for the same reason.
16
17Tested with build-many-glibcs.py for arm-linux-gnueabi, where this
18allows the build to get further.
19
20Reviewed-by: DJ Delorie <dj@redhat.com>
21(cherry picked from commit 2098d4034d398cbde6ccd4a2aaac52c518374698)
22Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
23---
24 csu/libc-start.c      | 10 ++++++++++
25 nptl/pthread_create.c | 10 ++++++++++
26 nptl/unwind.c         | 10 ++++++++++
27 3 files changed, 30 insertions(+)
28
29diff --git a/csu/libc-start.c b/csu/libc-start.c
30index 49413236..dd572d53 100644
31--- a/csu/libc-start.c
32+++ b/csu/libc-start.c
33@@ -21,6 +21,7 @@
34 #include <unistd.h>
35 #include <ldsodefs.h>
36 #include <exit-thread.h>
37+#include <libc-diag.h>
38 #include <libc-internal.h>
39
40 #include <elf/dl-tunables.h>
41@@ -292,7 +293,16 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
42   struct pthread_unwind_buf unwind_buf;
43
44   int not_first_call;
45+  DIAG_PUSH_NEEDS_COMMENT;
46+#if __GNUC_PREREQ (7, 0)
47+  /* This call results in a -Wstringop-overflow warning because struct
48+     pthread_unwind_buf is smaller than jmp_buf.  setjmp and longjmp
49+     do not use anything beyond the common prefix (they never access
50+     the saved signal mask), so that is a false positive.  */
51+  DIAG_IGNORE_NEEDS_COMMENT (11, "-Wstringop-overflow=");
52+#endif
53   not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
54+  DIAG_POP_NEEDS_COMMENT;
55   if (__glibc_likely (! not_first_call))
56     {
57       struct pthread *self = THREAD_SELF;
58diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
59index fe75d041..05bbbd88 100644
60--- a/nptl/pthread_create.c
61+++ b/nptl/pthread_create.c
62@@ -26,6 +26,7 @@
63 #include <hp-timing.h>
64 #include <ldsodefs.h>
65 #include <atomic.h>
66+#include <libc-diag.h>
67 #include <libc-internal.h>
68 #include <resolv.h>
69 #include <kernel-features.h>
70@@ -429,7 +430,16 @@ START_THREAD_DEFN
71   struct pthread_unwind_buf unwind_buf;
72
73   int not_first_call;
74+  DIAG_PUSH_NEEDS_COMMENT;
75+#if __GNUC_PREREQ (7, 0)
76+  /* This call results in a -Wstringop-overflow warning because struct
77+     pthread_unwind_buf is smaller than jmp_buf.  setjmp and longjmp
78+     do not use anything beyond the common prefix (they never access
79+     the saved signal mask), so that is a false positive.  */
80+  DIAG_IGNORE_NEEDS_COMMENT (11, "-Wstringop-overflow=");
81+#endif
82   not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
83+  DIAG_POP_NEEDS_COMMENT;
84
85   /* No previous handlers.  NB: This must be done after setjmp since the
86      private space in the unwind jump buffer may overlap space used by
87diff --git a/nptl/unwind.c b/nptl/unwind.c
88index b37a063c..3cf0779d 100644
89--- a/nptl/unwind.c
90+++ b/nptl/unwind.c
91@@ -23,6 +23,7 @@
92 #include <string.h>
93 #include <unistd.h>
94 #include "pthreadP.h"
95+#include <libc-diag.h>
96 #include <jmpbuf-unwind.h>
97
98 #ifdef _STACK_GROWS_DOWN
99@@ -90,8 +91,17 @@ unwind_stop (int version, _Unwind_Action actions,
100 	}
101     }
102
103+  DIAG_PUSH_NEEDS_COMMENT;
104+#if __GNUC_PREREQ (7, 0)
105+  /* This call results in a -Wstringop-overflow warning because struct
106+     pthread_unwind_buf is smaller than jmp_buf.  setjmp and longjmp
107+     do not use anything beyond the common prefix (they never access
108+     the saved signal mask), so that is a false positive.  */
109+  DIAG_IGNORE_NEEDS_COMMENT (11, "-Wstringop-overflow=");
110+#endif
111   if (do_longjump)
112     __libc_unwind_longjmp ((struct __jmp_buf_tag *) buf->cancel_jmp_buf, 1);
113+  DIAG_POP_NEEDS_COMMENT;
114
115   return _URC_NO_REASON;
116 }
117--
1182.20.1
119
120