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
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
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.
23 Tested with build-many-glibcs.py for arm-linux-gnueabi that this fixes
24 the testsuite build failures.
26 [Upstream: https://github.com/bminor/glibc/commit/548f467fa14ffe7d955beeb31b30e2aeae4467e0.patch]
27 Signed-off-by: Peter Seiderer <ps.report@gmx.net>
29 misc/sys/cdefs.h | 8 ++++++++
30 sysdeps/nptl/pthread.h | 37 +++++++++++++++++++++++++++----------
31 2 files changed, 35 insertions(+), 10 deletions(-)
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)
41 +/* Specify that a function such as setjmp or vfork may return
43 +#if __GNUC_PREREQ (4, 1)
44 +# define __attribute_returns_twice__ __attribute__ ((__returns_twice__))
46 +# define __attribute_returns_twice__ /* Ignore. */
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);
56 /* Cancellation handling with integration into exception handling. */
58 +struct __cancel_jmp_buf_tag
60 + __jmp_buf __cancel_jmp_buf;
61 + int __mask_was_saved;
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];
73 } __pthread_unwind_buf_t __attribute__ ((__aligned__));
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, \
83 if (__glibc_unlikely (__not_first_call)) \
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, \
94 if (__glibc_unlikely (__not_first_call)) \
96 __cancel_routine (__cancel_arg); \
97 @@ -730,9 +732,24 @@ extern void __pthread_unwind_next (__pthread_unwind_buf_t *__buf)
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],
113 + __sigsetjmp) __attribute_returns_twice__;
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;
122 /* Mutex handling. */