This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/83296] New: missing -Wstringop-overflow due to missing range info for MAX_EXPR
- From: "msebor at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 05 Dec 2017 23:20:53 +0000
- Subject: [Bug tree-optimization/83296] New: missing -Wstringop-overflow due to missing range info for MAX_EXPR
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83296
Bug ID: 83296
Summary: missing -Wstringop-overflow due to missing range info
for MAX_EXPR
Product: gcc
Version: 8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: msebor at gcc dot gnu.org
Target Milestone: ---
The call to strncpy() in the program below overflows the destination by 1 byte.
The overflow is diagnosed when compiled by GCC (as a C program) but not when
compiled by G++ (as a C++ program). The only difference between the two is
that in C, the prephitmp_10 strncpy argument has range info attached to it,
while in C++ it does not. As a result, the get_range_info() function used to
retrieve the range succeeds in C but fails in C++.
$ (set -x && cat a.c && for lang in c c++; do gcc -O2 -S -Wstringop-overflow=2
-fdump-tree-optimized=/dev/stdout -x$lang a.c; done)
+ cat a.c
struct S {
char a[5];
void (*pf)(void);
};
void f (struct S *s, int n)
{
if (n < sizeof s->a + 1)
n = sizeof s->a + 1;
__builtin_strncpy (s->a, "123456", n); // missing warning in C++
}
+ for lang in c c++
+ gcc -O2 -S -Wstringop-overflow=2 -fdump-tree-optimized=/dev/stdout -xc a.c
;; Function f (f, funcdef_no=0, decl_uid=1897, cgraph_uid=0, symbol_order=0)
f (struct S * s, int n)
{
unsigned int n.0_1;
char[5] * _3;
int _4;
long unsigned int prephitmp_10;
<bb 2> [local count: 1073741825]:
n.0_1 = (unsigned int) n_5(D);
if (n.0_1 <= 5)
goto <bb 3>; [50.00%]
else
goto <bb 4>; [50.00%]
<bb 3> [local count: 536870913]:
<bb 4> [local count: 1073741825]:
# _4 = PHI <n_5(D)(2), 6(3)>
prephitmp_10 = (long unsigned int) _4; // has range info
_3 = &s_6(D)->a;
__builtin_strncpy (_3, "123456", prephitmp_10); [tail call]
return;
}
a.c: In function ‘f’:
a.c:11:3: warning: ‘__builtin_strncpy’ writing 6 or more bytes into a region of
size 5 overflows the destination [-Wstringop-overflow=]
__builtin_strncpy (s->a, "123456", n); // missing warning in C++
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ for lang in c c++
+ gcc -O2 -S -Wstringop-overflow=2 -fdump-tree-optimized=/dev/stdout -xc++ a.c
;; Function f (_Z1fP1Si, funcdef_no=0, decl_uid=2330, cgraph_uid=0,
symbol_order=0)
f (struct S * s, int n)
{
long unsigned int _1;
char[5] * _3;
long unsigned int prephitmp_4;
<bb 2> [local count: 1073741825]:
_1 = (long unsigned int) n_5(D);
prephitmp_4 = MAX_EXPR <6, _1>; // no range info
_3 = &s_6(D)->a;
__builtin_strncpy (_3, "123456", prephitmp_4); [tail call]
return;
}