https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83038
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |diagnostic Status|UNCONFIRMED |NEW Last reconfirmed| |2017-11-18 Component|regression |tree-optimization Summary|[8 regression] warning at |warning at random points in |random points in the input |the input (array subscript |(array subscript -1 is |-1 is below array bounds) |below array bounds) | Ever confirmed|0 |1 Known to fail| |8.0 --- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> --- I can reproduce the bad location after stripping line directives from the .i files and compiling the result as a .c file. There are many other warnings so I suppressed them to reduce the clutter, but they do suggest the reason for the warning. $ gcc -O2 -S -Wno-pointer-to-int-cast -Wno-builtin-declaration-mismatch -Wno-int-to-pointer-cast -Wno-attributes -Warray-bounds -Warray-bounds pr83038.c pr83038.c:56415:29: warning: array subscript -1 is below array bounds of ‘DIDEVICEOBJECTINSTANCEW[256] {aka struct DIDEVICEOBJECTINSTANCEW[256]}’ [-Warray-bounds] DIDEVICEOBJECTINSTANCEW ddo = device->ddo[obj]; ^~~ A dump shows that VRP thinks obj is (or might be) negative: _234: [-INF, -1] EQUIVALENCES: { _148 } (1 elements) Array bound warning for device_137->ddo[_234] ... _147 = SendDlgItemMessageW (dialog_25(D), 28, 4108, 18446744073709551615, 2); _148 = (int) _147; if (_148 < 0) goto <bb 39>; [1.19%] else goto <bb 26>; [98.81%] <bb 39> [local count: 21340]: _234 = ASSERT_EXPR <_148, _148 < 0>; <bb 25> [local count: 21340]: # _184 = PHI <-1(39)> item ={v} {CLOBBER}; _47 = &device_137->ddo[_234]; Negative index values into the last member array (like device->ddo) were not diagnosed prior to r254830 (due to bug 68325). With the bug resolved, these kinds of problems are now detected and diagnosed. If struct DeviceData is changed so that the ddo array is not last, the same warning is emitted even with GCC 7, with the same poor location. So both the location problem and the warning are latent issues (i.e., not a regression). The bad location aside, as some of the other warnings indicate, the source code in the translation unit takes liberties with conversions between integers (and pointers) of different sizes. The value of obj (which is an int) is the result of calling lv_get_cur_item(dialog) which returns a long converted to int. These conversions tend to cause "trouble," as in trigger warnings due to jump threading or other optimizations introducing paths that don't apparently exist in the original source code. If I'm reading the dumps right, this is also what happens in this case. Sometimes, although not always, these problems can be prevented by avoiding these kinds of conversions. In this case, changing the type of both obj and lv_get_cur_item() to long (to match the result of the SendDlgItemMessageW() function whose result lv_get_cur_item() returns) prevents jump threading from inserting a path along which the index is negative and makes the warning go away. With that, I can confirm both the poor location and the spurious warning.