https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66974
Manuel López-Ibáñez <manu at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |diagnostic CC| |manu at gcc dot gnu.org --- Comment #3 from Manuel López-Ibáñez <manu at gcc dot gnu.org> --- The reason seems to be that GCC unrolls the inner loop completely to something like: if (i / 2 != 0) { // i > 1 c[0] += c[i] * c[i-1]; c[i-1] += c[i] * c[0]; if (i / 2 > 1) { // i > 3 c[1] += c[i] * c[i-2]; c[i-2] += c[i] * c[1]; if (i / 2 > 2) { // i > 5 c[2] += c[i] * c[i-3]; c[i-3] += c[i] * c[2]; } } } by reasoning that j < 3. However, it is not able to remove the two inner conditions by reasoning that i < 3 Since i's upper-bound depends on order and order is a parameter, it should be able to assume it (or at least say "may be above"). Interestingly, if one changes the function to: int foo(unsigned order) { int c[3] = {1, 2, 3}; if (order >= 5) return 0; unsigned i, j; for (i = 1; i < order; i++) { for (j = 0; j < i / 2; j++) { c[j] += c[i] * c[i-j-1]; c[i-j-1] += c[i] * c[j]; } } return c[0]; } There is an out-of-bounds access that is not detected by -Warray-bounds, but it is detected by -Wuninitialized: test.c:7:16: warning: ‘c[3u]’ may be used uninitialized in this function [-Wmaybe-uninitialized] c[j] += c[i] * c[i-j-1]; ^