From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by sourceware.org (Postfix) with ESMTPS id 037093858409 for ; Thu, 4 Nov 2021 07:03:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 037093858409 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-547-kY1yAkKINmWzXlMwyAyuog-1; Thu, 04 Nov 2021 03:03:38 -0400 X-MC-Unique: kY1yAkKINmWzXlMwyAyuog-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 8E24169720; Thu, 4 Nov 2021 07:03:37 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.39.192.72]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6D03E641AA; Thu, 4 Nov 2021 07:03:35 +0000 (UTC) From: Florian Weimer To: gcc-patches@gcc.gnu.org Cc: libc-alpha@sourceware.org, Martin Sebor Subject: Invalid -Wstringop-overread warning for valid POSIX constructs Date: Thu, 04 Nov 2021 08:03:33 +0100 Message-ID: <87k0hojtbu.fsf@oldenburg.str.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-6.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=unavailable autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 04 Nov 2021 07:03:43 -0000 This code: #include #include void f (pthread_key_t key) { pthread_setspecific (key, MAP_FAILED); } Results in a warning: t.c: In function =E2=80=98f=E2=80=99: t.c:7:3: warning: =E2=80=98pthread_setspecific=E2=80=99 expecting 1 byte in= a region of size 0 [-Wstringop-overread] 7 | pthread_setspecific (key, MAP_FAILED); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from t.c:1: /usr/include/pthread.h:1308:12: note: in a call to function =E2=80=98pthrea= d_setspecific=E2=80=99 declared with attribute =E2=80=98access (none, 2)=E2= =80=99 1308 | extern int pthread_setspecific (pthread_key_t __key, | ^~~~~~~~~~~~~~~~~~~ This also results in the same warning, for different reasons: #include extern int x[1]; void f (pthread_key_t key) { pthread_setspecific (key, &x[1]); } t.c: In function =E2=80=98f=E2=80=99: t.c:8:3: warning: =E2=80=98pthread_setspecific=E2=80=99 expecting 1 byte in= a region of size 0 [-Wstringop-overread] 8 | pthread_setspecific (key, &x[1]); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ t.c:3:12: note: at offset 4 into source object =E2=80=98x=E2=80=99 of size = 4 3 | extern int x[1]; | ^ In file included from t.c:1: /usr/include/pthread.h:1308:12: note: in a call to function =E2=80=98pthrea= d_setspecific=E2=80=99 declared with attribute =E2=80=98access (none, 2)=E2= =80=99 1308 | extern int pthread_setspecific (pthread_key_t __key, | ^~~~~~~~~~~~~~~~~~~ The original argument justifying this warning was that passing non-pointer constants is invalid. But MAP_FAILED is a valid POSIX pointer constant, so it is allowed here as well. And the second example shows that the warning also fires for completely valid pointers. So the none access attribute is clearly not correct here. (=E2=80=9Cnone=E2=80=9D= requires that the pointer is valid, there just aren't any accesses to the object it points to, but the object must exist. Apparently, this is what the kernel expects for its use of the annotation.) The root of the problem is the const void * pointer argument. Without the access attribute, we warn for other examples: typedef unsigned int pthread_key_t; int pthread_setspecific (pthread_key_t __key, const void *); void f (pthread_key_t key) { int x; pthread_setspecific (key, &x); } t.c: In function =E2=80=98f=E2=80=99: t.c:10:3: warning: =E2=80=98x=E2=80=99 may be used uninitialized [-Wmaybe-u= ninitialized] 10 | pthread_setspecific (key, &x); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ t.c:4:5: note: by argument 2 of type =E2=80=98const void *=E2=80=99 to =E2= =80=98pthread_setspecific=E2=80=99 declared here 4 | int pthread_setspecific (pthread_key_t __key, const void *); | ^~~~~~~~~~~~~~~~~~~ t.c:9:7: note: =E2=80=98x=E2=80=99 declared here 9 | int x; | ^ This is why we added the none access attribute, but this leads to the other problem. We could change glibc to use a different attribute (preferable one that we can probe using __has_attribute) if one were to become available, and backport that. But so far, I see nothing on the GCC side, and GCC PR 102329 seems to have stalled. Thanks, Florian