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; }