diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h index 8e244a77cf..ac56be4d87 100644 --- a/misc/sys/cdefs.h +++ b/misc/sys/cdefs.h @@ -592,8 +592,14 @@ _Static_assert (0, "IEEE 128-bits long double requires redirection on this platf array according to access mode, or at least one element when size-index is not provided: access (access-mode, [, ]) */ -#define __attr_access(x) __attribute__ ((__access__ x)) +# define __attr_access(x) __attribute__ ((__access__ x)) +# if __GNUC_PREREQ (11, 0) +# define __attr_access_none(pos) __attribute__ ((__access__ (__none__, pos))) +# endif #else # define __attr_access(x) +# define __attr_access_none(pos) +#endif + /* Specify that a function such as setjmp or vfork may return diff --git a/nptl/tst-thread-setspecific.c b/nptl/tst-thread-setspecific.c new file mode 100644 index 0000000000..bda61c6333 --- /dev/null +++ b/nptl/tst-thread-setspecific.c @@ -0,0 +1,43 @@ +/* Test to verify that passing a pointer to an uninitialized object + to pthread_setspecific doesn't trigger bogus uninitialized warnings. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +/* Turn uninitialized warnings into errors to detect the problem. + See BZ #27714. */ + +#pragma GCC diagnostic push +#pragma GCC diagnostic error "-Wmaybe-uninitialized" +#pragma GCC diagnostic error "-Wuninitialized" + +int do_test (void) +{ + void *p = malloc (1); /* Deliberately uninitialized. */ + pthread_setspecific (pthread_self (), p); + + void *q = pthread_getspecific (pthread_self ()); + + return p == q; +} + +#pragma GCC diagnostic pop + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/htl/pthread.h b/sysdeps/htl/pthread.h index 0923ad0002..6bcf97d692 100644 --- a/sysdeps/htl/pthread.h +++ b/sysdeps/htl/pthread.h @@ -822,7 +822,7 @@ extern void *pthread_getspecific (pthread_key_t __key) __THROW; /* Set the caller thread's thread specific value of KEY to VALUE. */ extern int pthread_setspecific (pthread_key_t __key, const void *__value) - __THROW; + __THROW __attr_access_none (2); /* Dynamic package initialization. */ diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h index 23bcd51d91..7c14d0fef7 100644 --- a/sysdeps/nptl/pthread.h +++ b/sysdeps/nptl/pthread.h @@ -1171,7 +1171,8 @@ extern void *pthread_getspecific (pthread_key_t __key) __THROW; /* Store POINTER in the thread-specific data slot identified by KEY. */ extern int pthread_setspecific (pthread_key_t __key, - const void *__pointer) __THROW ; + const void *__pointer) + __THROW __attr_access_none (2); #ifdef __USE_XOPEN2K