public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/94985] New: False-positive -Warray-bounds for char[1] on a non-zero offset in a referenced buffer
@ 2020-05-07 13:33 joeyjyliu at gmail dot com
2020-05-07 19:26 ` [Bug middle-end/94985] " msebor at gcc dot gnu.org
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: joeyjyliu at gmail dot com @ 2020-05-07 13:33 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94985
Bug ID: 94985
Summary: False-positive -Warray-bounds for char[1] on a
non-zero offset in a referenced buffer
Product: gcc
Version: 11.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: joeyjyliu at gmail dot com
Target Milestone: ---
Created attachment 48474
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48474&action=edit
patch for -Warray-bounds with test case
I think the assumption in builtin_memref::set_base_and_offset
(gimple-ssa-warn-restrict.c) is not necessarily correct. It is only applicable
for flexible arrays. Actually even for flexible arrays this check is
controversial as it assumes the pointer to the struct is always a pointer to
the array of structs.
In the attachment, there is a test file. The incorrect warning is like below.
error: ‘char* strncpy(char*, const char*, size_t)’ offset 1 from the object at
‘<unknown>’ is out of the bounds of referenced subobject ‘cstr<1>::m_data’ with
type ‘char [1]’ at offset 1 [-Werror=array-bounds]
8 | ::strncpy( data(), src, n );
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~
Also in the attachment there is a suggested change. With that, the warning goes
away and the regression tests still pass.
The original patch was sent to gcc-patches but I was advised to open a Bugzilla
ticket first. So here it is and the patch is modified to accommodate the
existing regression tests.
$ g++ -v
Using built-in specs.
COLLECT_GCC=/local/usr/bin/g++
COLLECT_LTO_WRAPPER=/local/usr/libexec/gcc/x86_64-pc-linux-gnu/11.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../configure --prefix=/local/usr --disable-multilib
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.0.0 20200505 (experimental) (GCC)
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug middle-end/94985] False-positive -Warray-bounds for char[1] on a non-zero offset in a referenced buffer
2020-05-07 13:33 [Bug c++/94985] New: False-positive -Warray-bounds for char[1] on a non-zero offset in a referenced buffer joeyjyliu at gmail dot com
@ 2020-05-07 19:26 ` msebor at gcc dot gnu.org
2020-05-07 19:26 ` msebor at gcc dot gnu.org
2020-05-07 20:23 ` joeyjyliu at gmail dot com
2 siblings, 0 replies; 4+ messages in thread
From: msebor at gcc dot gnu.org @ 2020-05-07 19:26 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94985
Martin Sebor <msebor at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Last reconfirmed| |2020-05-07
Ever confirmed|0 |1
Keywords| |diagnostic
CC| |msebor at gcc dot gnu.org
Component|c++ |middle-end
--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
Thanks for opening the bug. For reference, the gcc-patches thread is here:
https://gcc.gnu.org/pipermail/gcc-patches/2020-May/545280.html
As I said in response, I agree the warning in this instance (writing a single
byte into a one-element array) is a false positive, so confirmed. But the fix
in the submitted patch is not correct because it both introduces testsuite
regressions and other false negatives, and doesn't prevent other similar false
positives. A more comprehensive test with the expected diagnostics is below.
The root cause of the problem is that the builtin_memref::set_base_and_offset
(tree) function doesn't handle the sorts of cases where the access is to a
member of an object pointed to indirectly by some pointer. The IL for the
simple test case below is:
_1 = &q0_7(D)->a;
q0_7(D)->p = _1;
_2 = &MEM[(struct A1 *)q0_7(D) + 8B].a;
and set_base_and_offset() only considers A1::a when (for flexible array members
and arrays of size 0; I'm not sure we should cater to other array sizes) it
should look through the pointer and consider what it points to (i.e., look
through q0_7(D) and consider it points to &q0_7(D)->a).
The code in set_base_and_offset() is quite convoluted and should probably be
rewritten more cleanly.
That being said, the original test case, although valid, suggests it may be
derived from code that uses one-element trailing arrays as a substitute for
flexible array members (or zero-length arrays). If that's so, GCC has been
increasingly diagnosing such misuses and so while I will work on fixing this
bug it could well be that other similar uses of the class will continue to be
diagnosed.
typedef struct A1
{
char c;
char a[1];
} A1;
typedef struct BA1
{
struct A1 *p;
char a[4];
} BA1;
void test_a1 (BA1 *q0, BA1 *q1, BA1 *q2, char *s)
{
q0->p = (A1*)q0->a;
__builtin_strncpy (q0->p->a, s, 1); // { dg-bogus
"\\\[-Warray-bounds|-Wstringop-overflow" }
q0->p = (A1*)q0->a;
__builtin_strncpy (q0->p->a, s, 2); // { dg-bogus
"\\\[-Warray-bounds|-Wstringop-overflow" }
q0->p = (A1*)q0->a;
__builtin_strncpy (q0->p->a, s, 3); // { dg-bogus
"\\\[-Warray-bounds|-Wstringop-overflow" }
q1->p = (A1*)q1->a;
__builtin_strncpy (q1->p->a, s, 4); // { dg-bogus
"\\\[-Warray-bounds|-Wstringop-overflow" }
q2->p = (A1*)q2->a;
__builtin_strncpy (q2->p->a, s, 5); // { dg-warning
"\\\[-Warray-bounds|-Wstringop-overflow" }
}
struct A2
{
char c;
char a[2];
};
struct BA2
{
struct A2 *p;
char a[4];
};
void test_a2 (BA2 *q0, BA2 *q1, BA2 *q2, char *s)
{
q0->p = (A2*)q0->a;
__builtin_strncpy (q0->p->a, s, 1); // { dg-bogus
"\\\[-Warray-bounds|-Wstringop-overflow" }
q0->p = (A2*)q0->a;
__builtin_strncpy (q0->p->a, s, 2); // { dg-bogus
"\\\[-Warray-bounds|-Wstringop-overflow" }
q0->p = (A2*)q0->a;
__builtin_strncpy (q0->p->a, s, 3); // { dg-warning
"\\\[-Warray-bounds|-Wstringop-overflow" }
}
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug middle-end/94985] False-positive -Warray-bounds for char[1] on a non-zero offset in a referenced buffer
2020-05-07 13:33 [Bug c++/94985] New: False-positive -Warray-bounds for char[1] on a non-zero offset in a referenced buffer joeyjyliu at gmail dot com
2020-05-07 19:26 ` [Bug middle-end/94985] " msebor at gcc dot gnu.org
@ 2020-05-07 19:26 ` msebor at gcc dot gnu.org
2020-05-07 20:23 ` joeyjyliu at gmail dot com
2 siblings, 0 replies; 4+ messages in thread
From: msebor at gcc dot gnu.org @ 2020-05-07 19:26 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94985
Martin Sebor <msebor at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Assignee|unassigned at gcc dot gnu.org |msebor at gcc dot gnu.org
Status|NEW |ASSIGNED
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug middle-end/94985] False-positive -Warray-bounds for char[1] on a non-zero offset in a referenced buffer
2020-05-07 13:33 [Bug c++/94985] New: False-positive -Warray-bounds for char[1] on a non-zero offset in a referenced buffer joeyjyliu at gmail dot com
2020-05-07 19:26 ` [Bug middle-end/94985] " msebor at gcc dot gnu.org
2020-05-07 19:26 ` msebor at gcc dot gnu.org
@ 2020-05-07 20:23 ` joeyjyliu at gmail dot com
2 siblings, 0 replies; 4+ messages in thread
From: joeyjyliu at gmail dot com @ 2020-05-07 20:23 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94985
--- Comment #2 from Joey Liu <joeyjyliu at gmail dot com> ---
Just fyi, the patch attached in this ticket is slightly different than the
patch in the mailing list (I limit it to flexible array only). It can handle
the existing test cases (no regressions). However I do think we can do better
than that since it still can't deduce the correct refsize for my test case. For
now tree::component_ref_size just returns NULL_TREE as it can't really
distinguish the regular a[1] and the flexible array a[1].
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-05-07 20:23 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-07 13:33 [Bug c++/94985] New: False-positive -Warray-bounds for char[1] on a non-zero offset in a referenced buffer joeyjyliu at gmail dot com
2020-05-07 19:26 ` [Bug middle-end/94985] " msebor at gcc dot gnu.org
2020-05-07 19:26 ` msebor at gcc dot gnu.org
2020-05-07 20:23 ` joeyjyliu at gmail dot com
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).