Index: gcc/tree-ssa-alias.c =================================================================== --- gcc/tree-ssa-alias.c (revision 243099) +++ gcc/tree-ssa-alias.c (working copy) @@ -1355,7 +1355,10 @@ indirect_refs_may_alias_p (tree ref1 ATT && same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1 && same_type_for_tbaa (TREE_TYPE (base2), TREE_TYPE (ptrtype2)) == 1 && same_type_for_tbaa (TREE_TYPE (ptrtype1), - TREE_TYPE (ptrtype2)) == 1) + TREE_TYPE (ptrtype2)) == 1 + /* But avoid treating arrays as "objects", instead assume they + can overlap by an exact multiple of their element size. */ + && TREE_CODE (TREE_TYPE (ptrtype1)) != ARRAY_TYPE) return ranges_overlap_p (offset1, max_size1, offset2, max_size2); /* Do type-based disambiguation. */ Index: gcc/testsuite/gcc.dg/torture/alias-2.c =================================================================== --- gcc/testsuite/gcc.dg/torture/alias-2.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/alias-2.c (working copy) @@ -0,0 +1,17 @@ +/* { dg-do run } */ + +/* We do not want to treat int[3] as an object that cannot overlap + itself but treat it as arbitrary sub-array of a larger array object. */ +int ar1(int (*p)[3], int (*q)[3]) +{ + (*p)[0] = 1; + (*q)[1] = 2; + return (*p)[0]; +} +int main() +{ + int a[4]; + if (ar1 ((int (*)[3])&a[1], (int (*)[3])&a[0]) != 2) + __builtin_abort (); + return 0; +}