https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89720
Bug ID: 89720 Summary: [9 Regression] Spurious -Warray-bounds warning Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: steinar+gcc at gunderson dot no Target Milestone: --- Hi, The following is a reduced test case from MySQL: char func(long j) { char h[65536]; char *copy = h + (j & 0xffffffff3fffffffL); return *(copy - 6); } GCC 9-20190302-1 from Debian gives, with -O2: test.cpp: In function ‘char func(long int)’: test.cpp:5:20: warning: array subscript [-3221225479, -6] is outside array bounds of ‘char [65536]’ [-Warray-bounds] 5 | return *(copy - 6); | ^ test.cpp:3:8: note: while referencing ‘h’ 3 | char h[65536]; | ^ I believe there's some sort of signedness confusion here; the actual offset can certainly be far above -6. There's an additional problem in the un-reduced case, in that the diagnostic is very hard to understand; the reference happens several levels away from the definition of the buffer, with no indication about the call stack: In file included from /home/sesse/nmu/mysql-server/storage/innobase/include/mach0data.h:319, from /home/sesse/nmu/mysql-server/storage/innobase/include/data0type.ic:34, from /home/sesse/nmu/mysql-server/storage/innobase/include/data0type.h:531, from /home/sesse/nmu/mysql-server/storage/innobase/include/data0data.h:38, from /home/sesse/nmu/mysql-server/storage/innobase/include/que0que.h:36, from /home/sesse/nmu/mysql-server/storage/innobase/include/api0misc.h:41, from /home/sesse/nmu/mysql-server/storage/innobase/api/api0api.cc:41: /home/sesse/nmu/mysql-server/storage/innobase/include/mach0data.ic: In function ‘ib_err_t ib_cursor_delete_row(ib_crsr_t)’: /home/sesse/nmu/mysql-server/storage/innobase/include/mach0data.ic:67:26: warning: array subscript [-3221225479, -6] is outside array bounds of ‘unsigned char [65536]’ [-Warray-bounds] 67 | return ((uint8_t)(b[0])); | ^ The function with the warning on reads: UNIV_INLINE uint8_t mach_read_from_1(const byte *b) { ut_ad(b); // This is a custom assert macro. return ((uint8_t)(b[0])); } and the chain from ib_cursor_delete_row() to mach_read_from_1() is difficult to track own manually. Having some sort of trace here would be very useful.