This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: Top-of-tree GCC/glibc build problem
- From: Zack Weinberg <zackw at panix dot com>
- To: Steve Ellcey <sellcey at marvell dot com>
- Cc: "libc-alpha at sourceware dot org" <libc-alpha at sourceware dot org>
- Date: Mon, 7 Oct 2019 12:09:59 -0400
- Subject: Re: Top-of-tree GCC/glibc build problem
- References: <db63aef83bfdb68cefbbb78d53ca2f24d31939f1.camel@marvell.com>
On Mon, Oct 7, 2019 at 11:46 AM Steve Ellcey <sellcey@marvell.com> wrote:
>
> Looks like we have another new warning that is blocking top-of-tree glibc
> from being built with top-of-tree gcc.
...
> zic.c: In function ‘inzsub’:
> zic.c:1369:23: error: writing 8 bytes into a region of size 1 [-Werror=stringop-
> overflow=]
> 1369 | z.z_format_specifier = cp ? *cp : '\0';
> | ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
> zic.c:124:8: note: destination object declared here
> 124 | char z_format_specifier;
> | ^~~~~~~~~~~~~~~~~~
...
> Would using 'cp[0]' instead of '*cp' be the right fix here?
`*cp` and `cp[0]` are two ways of writing the exact same thing; if
replacing `*cp` with `cp[0]` causes the compiler to do _anything
whatsoever_ different, that's a bug.
`cp` is declared as a `char *`. So `*cp` has type `char` and
`z.z_format_specifier = *cp` should not warn. The construct `cp ? *cp
: '\0'`, however, has type `int` because of the usual arithmetic
conversions and because character constants have type `int` in C (not
in C++). I think that is probably where the warning is coming from;
technically the value might get truncated in the assignment. The
diagnostic message is misleading; there's no possibility of an
out-of-bounds memory scribble here, only data loss due to integer
truncation. A very simple value propagation analysis would reveal that
truncation is not possible in this case. I don't understand why it
says "writing 8 bytes" - do we even _have_ any ABIs where `sizeof(int)
== 8`?
I think this warning is bogus and should be reported to the GCC team
as such; it's liable to get false positives on lots of old code like
this. If we need to change the code to work around the warning,
changes that would probably actually help are either
/* Cast back from promoted type to 'char' to avoid a GCC 10 warning. */
z.z_format_specifier = (char) (cp ? *cp : '\0');
or
if (cp)
z.z_format_specifier = *cp;
else
z.z_format_specifier = '\0';
zw