https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91219
Bug ID: 91219 Summary: missing warning on a past-the-end power of access by memcpy Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- The past-the-end access in f0 and g0 are diagnosed as expected (the specific warning could be debated) but the equivalent invalid accesses in f1 and g1 are not. The problem is due to the difference between memcpy and MEM_REF. $ cat a.c && gcc -O2 -S -Wall -fdump-tree-lower=/dev/stdout a.c char a[4], b[4]; void f0 (void) { __builtin_memcpy (a, b + 1, 4); // warning (good) } void g0 (void) { __builtin_memcpy (a + 1, b, 4); // warning (good) } void f1 (void) { char *p = a, *q = b + 1; __builtin_memcpy (p, q, 4); // missing warning } void g1 (void) { char *p = a + 1, *q = b; __builtin_memcpy (p, q, 4); // missing warning } ;; Function f0 (f0, funcdef_no=0, decl_uid=1910, cgraph_uid=1, symbol_order=2) f0 () { _1 = &b + 1; __builtin_memcpy (&a, _1, 4); return; } ;; Function g0 (g0, funcdef_no=1, decl_uid=1913, cgraph_uid=2, symbol_order=3) g0 () { _1 = &a + 1; __builtin_memcpy (_1, &b, 4); return; } ;; Function f1 (f1, funcdef_no=2, decl_uid=1916, cgraph_uid=3, symbol_order=4) f1 () { unsigned int D.1926; char * q; char * p; p = &a; q = &b + 1; D.1926 = MEM <unsigned int> [(char * {ref-all})q]; MEM <unsigned int> [(char * {ref-all})p] = D.1926; return; } ;; Function g1 (g1, funcdef_no=3, decl_uid=1921, cgraph_uid=4, symbol_order=5) g1 () { unsigned int D.1927; char * q; char * p; p = &a + 1; q = &b; D.1927 = MEM <unsigned int> [(char * {ref-all})q]; MEM <unsigned int> [(char * {ref-all})p] = D.1927; return; } a.c: In function ‘f0’: a.c:5:3: warning: ‘__builtin_memcpy’ forming offset 5 is out of the bounds [0, 4] of object ‘b’ with type ‘char[4]’ [-Warray-bounds] 5 | __builtin_memcpy (a, b + 1, 4); // warning (good) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ a.c:1:12: note: ‘b’ declared here 1 | char a[4], b[4]; | ^ a.c: In function ‘g0’: a.c:10:3: warning: ‘__builtin_memcpy’ forming offset 5 is out of the bounds [0, 4] of object ‘a’ with type ‘char[4]’ [-Warray-bounds] 10 | __builtin_memcpy (a + 1, b, 4); // warning (good) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ a.c:1:6: note: ‘a’ declared here 1 | char a[4], b[4]; | ^