Add __attribute_access_none to disable GCC warnings [BZ #27714]

GCC 11 warns when a pointer to an uninitialized object is passed
to a function that takes a const-qualified argument.  This is done
on the assumption that most such functions read from the object.
For the rare case of a function that doesn't, GCC 11 extends
attribute access to add a new mode called none.

POSIX pthread_setspecific() is one such rare function that takes
a const void* argument but that doesn't read from the object it
points to.  To suppress the -Wmaybe-uninitialized issued by GCC
11 when the address of an uninitialized object is passed to it
(e.g., the result of malloc()), this change #defines
__attr_access_none in cdefs.h and uses the macro on the function
in sysdeps/htl/pthread.h and sysdeps/nptl/pthread.h.
This commit is contained in:
Martin Sebor 2021-04-27 13:01:55 -06:00
parent 876cdfd154
commit a1561c3bbe
5 changed files with 54 additions and 3 deletions

View File

@ -592,9 +592,15 @@ _Static_assert (0, "IEEE 128-bits long double requires redirection on this platf
array according to access mode, or at least one element when array according to access mode, or at least one element when
size-index is not provided: size-index is not provided:
access (access-mode, <ref-index> [, <size-index>]) */ access (access-mode, <ref-index> [, <size-index>]) */
#define __attr_access(x) __attribute__ ((__access__ x)) # define __attr_access(x) __attribute__ ((__access__ x))
# if __GNUC_PREREQ (11, 0)
# define __attr_access_none(argno) __attribute__ ((__access__ (__none__, argno)))
# else
# define __attr_access_none(argno)
# endif
#else #else
# define __attr_access(x) # define __attr_access(x)
# define __attr_access_none(argno)
#endif #endif
/* Specify that a function such as setjmp or vfork may return /* Specify that a function such as setjmp or vfork may return

View File

@ -314,6 +314,7 @@ tests = tst-attr2 tst-attr3 tst-default-attr \
tst-pthread-gdb-attach tst-pthread-gdb-attach-static \ tst-pthread-gdb-attach tst-pthread-gdb-attach-static \
tst-pthread_exit-nothreads \ tst-pthread_exit-nothreads \
tst-pthread_exit-nothreads-static \ tst-pthread_exit-nothreads-static \
tst-thread-setspecific
tests-nolibpthread = \ tests-nolibpthread = \
tst-pthread_exit-nothreads \ tst-pthread_exit-nothreads \

View File

@ -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
<https://www.gnu.org/licenses/>. */
#include <pthread.h>
#include <stdlib.h>
/* 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"

View File

@ -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. */ /* Set the caller thread's thread specific value of KEY to VALUE. */
extern int pthread_setspecific (pthread_key_t __key, const void *__value) extern int pthread_setspecific (pthread_key_t __key, const void *__value)
__THROW; __THROW __attr_access_none (2);
/* Dynamic package initialization. */ /* Dynamic package initialization. */

View File

@ -1182,7 +1182,8 @@ extern void *pthread_getspecific (pthread_key_t __key) __THROW;
/* Store POINTER in the thread-specific data slot identified by KEY. */ /* Store POINTER in the thread-specific data slot identified by KEY. */
extern int pthread_setspecific (pthread_key_t __key, extern int pthread_setspecific (pthread_key_t __key,
const void *__pointer) __THROW ; const void *__pointer)
__THROW __attr_access_none (2);
#ifdef __USE_XOPEN2K #ifdef __USE_XOPEN2K