https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66286
Bug ID: 66286 Summary: Inconsistent handling of array sections Product: gcc Version: 5.1.1 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: jakub at gcc dot gnu.org CC: ienkovich at gcc dot gnu.org, izamyatin at gmail dot com, kyukhin at gcc dot gnu.org Target Milestone: --- int main () { int a[10], i; a[0:10] = 10; a[0:2] *= 2; a[5:2] *= 3; for (i = 0; i < 10; i++) if (a[i] != (i < 2 ? 20 : (i - 5U <= 1U ? 30 : 10))) __builtin_abort (); return 0; } passes in C++, but not in C, and passes with icc (both C and C++). https://www.cilkplus.org/tutorial-array-notation says that omitted stride defaults to 1 and that is what the C++ FE does: if (!stride) stride = build_one_cst (ptrdiff_type_node); in build_array_notation_ref. But the C FE does something different: if (!stride) { if (TREE_CONSTANT (start_index) && TREE_CONSTANT (length) && tree_int_cst_lt (length, start_index)) stride = build_int_cst (TREE_TYPE (start_index), -1); else stride = build_int_cst (TREE_TYPE (start_index), 1); } Not to mention that TREE_CONSTANT doesn't necessarily imply INTEGER_CST that can be passed to tree_int_cst_lt... IMHO we should just replace that hunk with if (!stride) stride = build_int_cst (TREE_TYPE (start_index), 1); but I'd like to understand why this has been added there at all. Seems the C++ FE had similar code too, but that got removed in r200554 without mentioning it as a wrong-code bugfix.