https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93586
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED CC| |hubicka at gcc dot gnu.org Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org --- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> --- DSE also happily removes the initializer parts for int main () { char c[1][4][1] = { { { 7 }, { 0 }, { 5 }, { 5 } } }; for (int b = 0; b <= 3; b++) if (c[0][b][0]) __builtin_abort (); return 0; } the code contains commentary explicitely noting this situation: /* If index is non-zero we need to check whether the reference does not break the main invariant that bases are either disjoint or equal. Consider the example: unsigned char out[][1]; out[1]="a"; out[i][0]; Here bases out and out are same, but after removing the [i] index, this invariant no longer holds, because out[i] points to the middle of array out. TODO: If size of type of the skipped reference is an integer multiply of the size of type of the other reference this invariant can be verified, but even then it is not completely safe with !flag_strict_aliasing if the other reference contains unbounded array accesses. See */ but it gets defeated by the accesses having c[0] in the base (but not in the next dimension). Then we end up asking nonoverlapping_array_refs_p for c[0] vs. c[0][b_2] which are not matching dimensions thus -1 is returned. The next query is then for c[0][3] vs. c[0][b_2][0] which returns 1(!? why's that not a mismatch) and since there's no partial overlap we immeditately return success (but seen_unmatched_ref_p is true) /* Try to disambiguate matched arrays. */ for (unsigned int i = 0; i < narray_refs1; i++) { int cmp = nonoverlapping_array_refs_p (component_refs1.pop (), component_refs2.pop ()); if (cmp == 1 && !partial_overlap) { ++alias_stats .nonoverlapping_refs_since_match_p_no_alias; return 1; } partial_overlap = false; if (cmp == -1) seen_unmatched_ref_p = true; } The mismatch doesn't happen because sizeof(char[1]) == sizeof(char). @@ -1291,6 +1292,11 @@ nonoverlapping_array_refs_p (tree ref1, tree ref2) tree elmt_type1 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (ref1, 0))); tree elmt_type2 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (ref2, 0))); + /* If one element is an array but not the other there's an obvious + mismatch in dimensionality. */ + if ((TREE_CODE (elmt_type1) == ARRAY_TYPE) + != (TREE_CODE (elmt_type2) == ARRAY_TYPE)) + return -1; if (TREE_OPERAND (ref1, 3)) { fixes that. But maybe we're not even supposed to call the function with such cases? Honza?