Disable spurious -Wstringop-overflow for setjmp/longjmp (bug 26647)

DJ Delorie dj@redhat.com
Fri Oct 30 21:06:02 GMT 2020


Joseph Myers <joseph@codesourcery.com> writes:
> diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
>  
> +/* Specify that a function such as setjmp or vfork may return
> +   twice.  */
> +#if __GNUC_PREREQ (4, 1)
> +# define __attribute_returns_twice__ __attribute__ ((__returns_twice__))
> +#else
> +# define __attribute_returns_twice__ /* Ignore.  */
> +#endif
> +
>  #endif	 /* sys/cdefs.h */

Ok.

> diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
>  
> +struct __cancel_jmp_buf_tag
> +{
> +  __jmp_buf __cancel_jmp_buf;
> +  int __mask_was_saved;
> +};
> +
>  typedef struct
>  {
> -  struct
> -  {
> -    __jmp_buf __cancel_jmp_buf;
> -    int __mask_was_saved;
> -  } __cancel_jmp_buf[1];
> +  struct __cancel_jmp_buf_tag __cancel_jmp_buf[1];
>    void *__pad[4];
>  } __pthread_unwind_buf_t __attribute__ ((__aligned__));

Extracts prefix struct out to its own type.  Ok.

> -    int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *)     \
> -					__cancel_buf.__cancel_jmp_buf, 0);    \
> +    int __not_first_call = __sigsetjmp_cancel (__cancel_buf.__cancel_jmp_buf, \
> +					       0);			      \

Ok.  Same effective arguments, different function.

> -    int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *)     \
> -					__cancel_buf.__cancel_jmp_buf, 0);    \
> +    int __not_first_call = __sigsetjmp_cancel (__cancel_buf.__cancel_jmp_buf, \
> +					       0);			      \

Ok, likewise.

> -/* Function used in the macros.  */
> +/* Function used in the macros.  Calling __sigsetjmp, with its first
> +   argument declared as an array, results in a -Wstringop-overflow
> +   warning from GCC 11 because struct pthread_unwind_buf is smaller
> +   than jmp_buf.  The calls from the macros have __SAVEMASK set to 0,
> +   so nothing beyond the common prefix is used and this warning is a
> +   false positive.  Use an alias with its first argument declared to
> +   use the type in the macros if possible to avoid this warning.  */
> +#if __GNUC_PREREQ (11, 0)
> +extern int __REDIRECT_NTHNL (__sigsetjmp_cancel,
> +			     (struct __cancel_jmp_buf_tag __env[1],
> +			      int __savemask),
> +			     __sigsetjmp) __attribute_returns_twice__;
> +#else
> +# define __sigsetjmp_cancel(env, savemask) \
> +  __sigsetjmp ((struct __jmp_buf_tag *) (void *) (env), (savemask))
>  extern int __sigsetjmp (struct __jmp_buf_tag __env[1],
>  			int __savemask) __THROWNL;
> +#endif

So we're adding a __sigsetjmp_cancel that's the same as __sigsetjmp but
with a different signature just to appease gcc...  the name makes it
sound like you're cancelling a sigsetjmp, but what you're really doing
(iirc) is setting up a jump point for a later cancellation.

Maybe __sigsetjmp_for_cancel would make more sense, but I'm not
bikeshedding it.

LGTM.

Reviewed-by: DJ Delorie <dj@redhat.com>



More information about the Libc-alpha mailing list