https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63441
Bug ID: 63441 Summary: incorrect "array subscript is below/above array bounds" diagnostic Product: gcc Version: 5.0 Status: UNCONFIRMED Severity: minor Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: rschiele at gmail dot com I found a case where gcc diagnostic "array subscript is below/above array bounds" is wrong in my opinion. I simplified the test case as much as possible and got it down to: typedef struct { int a[2]; int b; } c; int f(c *d, int e) { int r = 0; int p; int i; switch(e) { case 0: i = 0; break; default: i = -1; break; }; p = d->a[i]; if (p > 0) r = 0; else { switch(e) { case 0: r = 1; break; } } return r; } The basic idea of the function f was that the parameter e is only allowed to get a certain set of permitted values. In that example the set was reduced to only 0 being the permitted value (which obviously does no longer make a lot of sense but the original code with a larger set did show the same problem). Based on that value a specific action is taken in the first switch statement and a default case is given, which sets the value i to an invalid one (-1). I agree this is not particularly intelligent error handling but was found with that pattern in real code.) Later this value i is used for indexing an array. This is diagnosed by gcc to be below array bounds (or above for a value too high), which would obviously make sense for (i == -1) but on the other hand I don't see any reason gcc should assume this default case to ever happen. Further analysis reveals that this behavior appeared in the development phase of gcc 4.8 with this commit: commit 78b7a67520737f2e029383dd5a89ba8c1c4a3ef9 Author: steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Mon Jul 2 18:50:51 2012 +0000 gcc/ * stmt.c (emit_case_bit_tests): Remove. (expand_case): Remove expand_switch_using_bit_tests_p code. * tree-switch-conversion.c (hoist_edge_and_branch_if_true): New. (MAX_CASE_BIT_TESTS): Moved from stmt.c to here. (lshift_cheap_p): Likewise. (expand_switch_using_bit_tests_p): Likewise. (struct case_bit_test): Likewise. (case_bit_test_cmp): Likewise. (emit_case_bit_tests): New implementation for GIMPLE. (gen_inbound_check): Do not release post-dominator info here. (process_switch): Reorder code. Expand as bit tests if it looks like a win. (do_switchconv): Release post-dominator info here if something changed. (struct gimple_opt_pass): Verify more. * tree.h (expand_switch_using_bit_tests_p): Remove prototype. testsuite/ * gcc.dg/tree-ssa/pr36881.c: Fix test case to not expand as bit tests. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189173 138bc75d-0d04-0410-961f-82ee72b054a4 This obviously does not necessarily mean that it was introduced here since this could have been just the trigger for that. Another interesting observation is that if I replace the second, not directly related switch statement with an if statement with the same semantics the obscure diagnostic goes away. It seems that this problem is independent of the architecture but I actually tested this on arm-*-linux-gnueabihf and i686-*-linux-gnu. Do people here agree this is a bug in diagnostics or do people think that it is legitimate to assume that the default case actually can happen?