83f3f15eb604c74debd3ced59d3f2b4435026162
[buildroot.git] /
1 From ea50889c35fb73ed9e140d800303aae9148c2888 Mon Sep 17 00:00:00 2001
2 From: Joseph Myers <joseph@codesourcery.com>
3 Date: Fri, 30 Oct 2020 22:25:42 +0000
4 Subject: [PATCH 4/4] Avoid -Wstringop-overflow warning in pthread_cleanup_push
5 macros
6
7 GCC 11 introduces a -Wstringop-overflow warning for calls to functions
8 with an array argument passed as a pointer to memory not large enough
9 for that array. This includes the __sigsetjmp calls from
10 pthread_cleanup_push macros, because those use a structure in
11 __pthread_unwind_buf_t, which has a common initial subsequence with
12 jmp_buf but does not include the saved signal mask; this is OK in this
13 case because the second argument to __sigsetjmp is 0 so the signal
14 mask is not accessed.
15
16 To avoid this warning, use a function alias __sigsetjmp_cancel with
17 first argument an array of exactly the type used in the calls to the
18 function, if using GCC 11 or later. With older compilers, continue to
19 use __sigsetjmp with a cast, to avoid any issues with compilers
20 predating the returns_twice attribute not applying the same special
21 handling to __sigsetjmp_cancel as to __sigsetjmp.
22
23 Tested with build-many-glibcs.py for arm-linux-gnueabi that this fixes
24 the testsuite build failures.
25
26 [Upstream: https://github.com/bminor/glibc/commit/548f467fa14ffe7d955beeb31b30e2aeae4467e0.patch]
27 Signed-off-by: Peter Seiderer <ps.report@gmx.net>
28 ---
29 misc/sys/cdefs.h | 8 ++++++++
30 sysdeps/nptl/pthread.h | 37 +++++++++++++++++++++++++++----------
31 2 files changed, 35 insertions(+), 10 deletions(-)
32
33 diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
34 index 38221d0b..ce877487 100644
35 --- a/misc/sys/cdefs.h
36 +++ b/misc/sys/cdefs.h
37 @@ -556,4 +556,12 @@ _Static_assert (0, "IEEE 128-bits long double requires redirection on this platf
38 # define __attr_access(x)
39 #endif
40
41 +/* Specify that a function such as setjmp or vfork may return
42 + twice. */
43 +#if __GNUC_PREREQ (4, 1)
44 +# define __attribute_returns_twice__ __attribute__ ((__returns_twice__))
45 +#else
46 +# define __attribute_returns_twice__ /* Ignore. */
47 +#endif
48 +
49 #endif /* sys/cdefs.h */
50 diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
51 index d4194da7..3a34d823 100644
52 --- a/sysdeps/nptl/pthread.h
53 +++ b/sysdeps/nptl/pthread.h
54 @@ -512,13 +512,15 @@ extern void pthread_testcancel (void);
55
56 /* Cancellation handling with integration into exception handling. */
57
58 +struct __cancel_jmp_buf_tag
59 +{
60 + __jmp_buf __cancel_jmp_buf;
61 + int __mask_was_saved;
62 +};
63 +
64 typedef struct
65 {
66 - struct
67 - {
68 - __jmp_buf __cancel_jmp_buf;
69 - int __mask_was_saved;
70 - } __cancel_jmp_buf[1];
71 + struct __cancel_jmp_buf_tag __cancel_jmp_buf[1];
72 void *__pad[4];
73 } __pthread_unwind_buf_t __attribute__ ((__aligned__));
74
75 @@ -658,8 +660,8 @@ __pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame)
76 __pthread_unwind_buf_t __cancel_buf; \
77 void (*__cancel_routine) (void *) = (routine); \
78 void *__cancel_arg = (arg); \
79 - int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) \
80 - __cancel_buf.__cancel_jmp_buf, 0); \
81 + int __not_first_call = __sigsetjmp_cancel (__cancel_buf.__cancel_jmp_buf, \
82 + 0); \
83 if (__glibc_unlikely (__not_first_call)) \
84 { \
85 __cancel_routine (__cancel_arg); \
86 @@ -693,8 +695,8 @@ extern void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf)
87 __pthread_unwind_buf_t __cancel_buf; \
88 void (*__cancel_routine) (void *) = (routine); \
89 void *__cancel_arg = (arg); \
90 - int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) \
91 - __cancel_buf.__cancel_jmp_buf, 0); \
92 + int __not_first_call = __sigsetjmp_cancel (__cancel_buf.__cancel_jmp_buf, \
93 + 0); \
94 if (__glibc_unlikely (__not_first_call)) \
95 { \
96 __cancel_routine (__cancel_arg); \
97 @@ -730,9 +732,24 @@ extern void __pthread_unwind_next (__pthread_unwind_buf_t *__buf)
98 ;
99 #endif
100
101 -/* Function used in the macros. */
102 +/* Function used in the macros. Calling __sigsetjmp, with its first
103 + argument declared as an array, results in a -Wstringop-overflow
104 + warning from GCC 11 because struct pthread_unwind_buf is smaller
105 + than jmp_buf. The calls from the macros have __SAVEMASK set to 0,
106 + so nothing beyond the common prefix is used and this warning is a
107 + false positive. Use an alias with its first argument declared to
108 + use the type in the macros if possible to avoid this warning. */
109 +#if __GNUC_PREREQ (11, 0)
110 +extern int __REDIRECT_NTHNL (__sigsetjmp_cancel,
111 + (struct __cancel_jmp_buf_tag __env[1],
112 + int __savemask),
113 + __sigsetjmp) __attribute_returns_twice__;
114 +#else
115 +# define __sigsetjmp_cancel(env, savemask) \
116 + __sigsetjmp ((struct __jmp_buf_tag *) (void *) (env), (savemask))
117 extern int __sigsetjmp (struct __jmp_buf_tag __env[1],
118 int __savemask) __THROWNL;
119 +#endif
120
121
122 /* Mutex handling. */
123 --
124 2.31.1
125