GNU bug report logs -
#55895
[PATCH] maint: Fix ptr_align signature to silence -Wmaybe-uninitialized
Previous Next
Reported by: Anders Kaseorg <andersk <at> mit.edu>
Date: Fri, 10 Jun 2022 22:31:02 UTC
Severity: normal
Tags: patch
Done: Paul Eggert <eggert <at> cs.ucla.edu>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 55895 in the body.
You can then email your comments to 55895 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-coreutils <at> gnu.org
:
bug#55895
; Package
coreutils
.
(Fri, 10 Jun 2022 22:31:02 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
Anders Kaseorg <andersk <at> mit.edu>
:
New bug report received and forwarded. Copy sent to
bug-coreutils <at> gnu.org
.
(Fri, 10 Jun 2022 22:31:02 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
ptr_align is always called with a pointer to uninitialized memory, so
it does not make sense for that pointer to be const. This change
avoids -Wmaybe-uninitialized warnings from GCC 11.
Signed-off-by: Anders Kaseorg <andersk <at> mit.edu>
---
Some of the warnings from GCC 11.3.0 without this patch:
CC src/cksum-digest.o
src/digest.c: In function 'digest_check':
src/digest.c:1036:31: error: 'bin_buffer_unaligned' may be used uninitialized [-Werror=maybe-uninitialized]
1036 | unsigned char *bin_buffer = ptr_align (bin_buffer_unaligned, DIGEST_ALIGN);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/digest.c:24:
src/system.h:493:1: note: by argument 1 of type 'const void *' to 'ptr_align' declared here
493 | ptr_align (void const *ptr, size_t alignment)
| ^~~~~~~~~
src/digest.c:1034:17: note: 'bin_buffer_unaligned' declared here
1034 | unsigned char bin_buffer_unaligned[DIGEST_BIN_BYTES + DIGEST_ALIGN];
| ^~~~~~~~~~~~~~~~~~~~
src/digest.c: In function 'main':
src/digest.c:1247:31: error: 'bin_buffer_unaligned' may be used uninitialized [-Werror=maybe-uninitialized]
1247 | unsigned char *bin_buffer = ptr_align (bin_buffer_unaligned, DIGEST_ALIGN);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/digest.c:24:
src/system.h:493:1: note: by argument 1 of type 'const void *' to 'ptr_align' declared here
493 | ptr_align (void const *ptr, size_t alignment)
| ^~~~~~~~~
src/digest.c:1245:17: note: 'bin_buffer_unaligned' declared here
1245 | unsigned char bin_buffer_unaligned[DIGEST_BIN_BYTES + DIGEST_ALIGN];
| ^~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[2]: *** [Makefile:20574: src/cksum-digest.o] Error 1
src/system.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/system.h b/src/system.h
index 0c5c9b900..120fd15e4 100644
--- a/src/system.h
+++ b/src/system.h
@@ -490,7 +490,7 @@ lcm (size_t u, size_t v)
locations. */
static inline void *
-ptr_align (void const *ptr, size_t alignment)
+ptr_align (void *ptr, size_t alignment)
{
char const *p0 = ptr;
char const *p1 = p0 + alignment - 1;
--
2.36.1
Information forwarded
to
bug-coreutils <at> gnu.org
:
bug#55895
; Package
coreutils
.
(Sat, 11 Jun 2022 03:24:01 GMT)
Full text and
rfc822 format available.
Message #8 received at 55895 <at> debbugs.gnu.org (full text, mbox):
On 6/10/22 15:24, Anders Kaseorg wrote:
> ptr_align is always called with a pointer to uninitialized memory, so
> it does not make sense for that pointer to be const.
I don't see why not. ptr_align does not modify the referenced storage so
"void const *" is appropriate. If we changed the type to "void *" we'd
unnecessarily limit ptr_align's applicability.
> This change avoids -Wmaybe-uninitialized warnings from GCC 11.
I can't reproduce the problem with the latest coreutils commit
93e099e4c3b659b2e329f655fbdc73fdf594a66e on Savannah master on Ubuntu
22.04 LTS x86-64, I don't get warnings with either gcc (Ubuntu
11.2.0-19ubuntu1) 11.2.0 or with gcc-12 (Ubuntu 12-20220319-1ubuntu1)
12.0.1 20220319 (experimental) [master r12-7719-g8ca61ad148f]. I also
don't see a problem on Fedora 36 x86-64 with gcc (GCC) 12.1.1 20220507
(Red Hat 12.1.1-1)
. In all cases I configured and built with "./configure
--enable-gcc-warnings; make".
Perhaps the problem (whatever it was) has already been fixed in
coreutils. If not, I guess that the issue has something to do with the
particular platform and options you configured with. If it's an older
compiler like GCC 11.3.0 I wouldn't worry too much about it, as older
GCCs are notorious for false alarms and not worth the trouble of pacifying.
Most likely the warnings are false positives (though I haven't checked
this).
Information forwarded
to
bug-coreutils <at> gnu.org
:
bug#55895
; Package
coreutils
.
(Sat, 11 Jun 2022 04:13:01 GMT)
Full text and
rfc822 format available.
Message #11 received at 55895 <at> debbugs.gnu.org (full text, mbox):
Thanks for checking. I should have nailed down the reproduction recipe
more precisely; sorry for that. It seems the important step I should
have included was CFLAGS=-O0. Full recipe, using the same systems you
checked:
Ubuntu 22.04 LTS x86-64
gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0
coreutils master, commit 93e099e4c3b659b2e329f655fbdc73fdf594a66e
./bootstrap --skip-po
./configure CFLAGS=-O0 (with or without --enable-gcc-warnings)
make
or
Fedora 36 x86-64
gcc (GCC) 12.1.1 20220507 (Red Hat 12.1.1-1)
coreutils master, commit 93e099e4c3b659b2e329f655fbdc73fdf594a66e
./bootstrap --skip-po
./configure CFLAGS=-O0 (with or without --enable-gcc-warnings)
make -k
(With GCC 12.1.1 I get the same error and also additional errors that
might merit further investigation.)
Can you reproduce with CFLAGS=-O0?
On 6/10/22 20:23, Paul Eggert wrote:
> On 6/10/22 15:24, Anders Kaseorg wrote:
>> ptr_align is always called with a pointer to uninitialized memory, so
>> it does not make sense for that pointer to be const.
>
> I don't see why not. ptr_align does not modify the referenced storage so
> "void const *" is appropriate. If we changed the type to "void *" we'd
> unnecessarily limit ptr_align's applicability.
My claim is that there’s never a reason to call ptr_align with a const
pointer, because if the memory is initialized the pointer would have
already been aligned, and if the memory is uninitialized you’re going to
need to write to it somewhere.
Also, the current signature converts a const pointer to a mutable
pointer. Given the squishy nature of const in C (and the general lack
of language features that would make it a more reliably useful signal),
I know this kind of “safety hole” is so common that I hesitate to
suggest it’s really a hole. But given that it’s unnecessary we might as
well avoid it.
GCC’s -Wmaybe-uninitialized seems to assume that a const pointer might
be read, in the absense of better information from higher optimization
levels. Although this heuristic isn’t perfect (I’m not suggesting that
the code is actually _wrong_), it seems reasonable enough to be worth
appeasing, given that there doesn’t seem to be a notable downside.
Anders
Reply sent
to
Paul Eggert <eggert <at> cs.ucla.edu>
:
You have taken responsibility.
(Sat, 11 Jun 2022 16:13:02 GMT)
Full text and
rfc822 format available.
Notification sent
to
Anders Kaseorg <andersk <at> mit.edu>
:
bug acknowledged by developer.
(Sat, 11 Jun 2022 16:13:02 GMT)
Full text and
rfc822 format available.
Message #16 received at 55895-done <at> debbugs.gnu.org (full text, mbox):
On 6/10/22 21:11, Anders Kaseorg wrote:
> It seems the important step I should
> have included was CFLAGS=-O0.
Ah, OK. Since you're building from Git, I can refer you to
README-hacking which is intended for that. It says, "If you get warnings
with other configurations, you can run
'./configure --disable-gcc-warnings' or 'make WERROR_CFLAGS='
to build quietly or verbosely, respectively.
" Here, "other configurations" refers to what you're doing.
> (With GCC 12.1.1 I get the same error and also additional errors that might merit further investigation.)
Like most static analysis tools, GCC generates a bunch of false
positives unless you baby it just right. We do the babying only for the
latest GCC with the default configuration; otherwise, it's typically not
worth the trouble. Feel free to investigate the other warnings, but
they're important only if they're true positives (and most likely
they're not, because gcc -O0 is dumber than gcc -O2).
> there’s never a reason to call ptr_align with a const pointer, because if the memory is initialized the pointer would have already been aligned
First, a const pointer can point to uninitialized storage. Second, even
if the referenced memory is initialized the pointer need not be aligned
already. For example, this is valid:
char *p = malloc (1024);
if (!p) return;
char const *q = p; // q points to uninitialized storage
char const *r = ptr_align (q, 512); // q is not aligned already
memset (p, 127, 1024);
...
Replacing 'malloc (1024)' with 'calloc (1024, 1)' (thus initializing the
storage before aligning the pointer) wouldn't affect the validity of the
code.
> Also, the current signature converts a const pointer to a mutable pointer.
Yes, it's like strchr which is annoying but that's the best C can do.
You're right that changing it from void const * to void * won't hurt
coreutils' current callers but I'd rather not massage the code merely to
pacify nondefault configurations. There are too many nondefault
configurations to worry about and massaging the code to pacify them all
would waste our time and confuse the code. Instead, we pacify only
default configurations with current GCC.
Information forwarded
to
bug-coreutils <at> gnu.org
:
bug#55895
; Package
coreutils
.
(Sat, 11 Jun 2022 16:31:02 GMT)
Full text and
rfc822 format available.
Message #19 received at 55895 <at> debbugs.gnu.org (full text, mbox):
On 6/11/22 09:12, Paul Eggert wrote:
> First, a const pointer can point to uninitialized storage.
Of course it can, but my claim was there’s never a reason. A pointer to
uninitialized (or zero-initialized) memory that won’t be written is
valid but not _useful_. The reason you’d align a pointer is so you can
store something there that needs to be aligned. It’s not an accident
that all of the current callers work that way.
Anders
Information forwarded
to
bug-coreutils <at> gnu.org
:
bug#55895
; Package
coreutils
.
(Sat, 11 Jun 2022 17:14:02 GMT)
Full text and
rfc822 format available.
Message #22 received at 55895 <at> debbugs.gnu.org (full text, mbox):
On 6/11/22 09:30, Anders Kaseorg wrote:
> A pointer to uninitialized (or zero-initialized) memory that won’t be
> written is valid but not _useful_.
But in the example I gave, the memory *is* written to later.
A const * pointer lets a C program have a read-only window into memory
that other parts of the program can write to, which can be a useful
thing to have. In C and C++, "const *" doesn't mean a pointer to storage
that does not change; it merely means a pointer that can't be used to
write the referenced storage.
Information forwarded
to
bug-coreutils <at> gnu.org
:
bug#55895
; Package
coreutils
.
(Sat, 11 Jun 2022 21:19:01 GMT)
Full text and
rfc822 format available.
Message #25 received at 55895 <at> debbugs.gnu.org (full text, mbox):
I know C. I’m not saying that const implies writes don’t happen elsewhere. I’m saying that _aligning_ a const pointer implies it’s not _useful_ for _unaligned_ writes to happen elsewhere. And if you align the mutable pointer, you don’t need to separately align a const pointer.
Anders
Information forwarded
to
bug-coreutils <at> gnu.org
:
bug#55895
; Package
coreutils
.
(Sun, 12 Jun 2022 00:15:02 GMT)
Full text and
rfc822 format available.
Message #28 received at 55895 <at> debbugs.gnu.org (full text, mbox):
On 6/11/22 14:18, Anders Kaseorg wrote:
> if you align the mutable pointer, you don’t need to separately align a const pointer.
Of course one can alter code by aligning a mutable pointer first and
then converting it to a const pointer, instead of first converting it to
const and then aligning the result. But that might not be convenient.
The part of the code that needs alignment might have access to only the
const pointer, and should be able to align the const pointer on its own
without bothering the part of the code that doesn't need alignment.
Anyway, we're getting a long way from the original bug report. I'll let
you have the last word on this tangential topic, if you like.
bug archived.
Request was from
Debbugs Internal Request <help-debbugs <at> gnu.org>
to
internal_control <at> debbugs.gnu.org
.
(Sun, 10 Jul 2022 11:24:08 GMT)
Full text and
rfc822 format available.
This bug report was last modified 2 years and 341 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.