This fixes PR48965, not handling mem-refs properly within aliasing_component_refs_p. We disregarded the offset for the decl base.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2011-04-20 Richard Guenther <rguent...@suse.de> PR middle-end/48695 * tree-ssa-alias.c (aliasing_component_refs_p): Compute base objects and types here. Adjust for their offset before comparing. * g++.dg/torture/pr48695.C: New testcase. Index: gcc/tree-ssa-alias.c =================================================================== *** gcc/tree-ssa-alias.c (revision 172759) --- gcc/tree-ssa-alias.c (working copy) *************** same_type_for_tbaa (tree type1, tree typ *** 593,603 **** are the respective alias sets. */ static bool ! aliasing_component_refs_p (tree ref1, tree type1, alias_set_type ref1_alias_set, alias_set_type base1_alias_set, HOST_WIDE_INT offset1, HOST_WIDE_INT max_size1, ! tree ref2, tree type2, alias_set_type ref2_alias_set, alias_set_type base2_alias_set, HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2, --- 593,603 ---- are the respective alias sets. */ static bool ! aliasing_component_refs_p (tree ref1, alias_set_type ref1_alias_set, alias_set_type base1_alias_set, HOST_WIDE_INT offset1, HOST_WIDE_INT max_size1, ! tree ref2, alias_set_type ref2_alias_set, alias_set_type base2_alias_set, HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2, *************** aliasing_component_refs_p (tree ref1, tr *** 609,617 **** --- 609,629 ---- struct A { int i; int j; } *q; struct B { struct A a; int k; } *p; disambiguating q->i and p->a.j. */ + tree base1, base2; + tree type1, type2; tree *refp; int same_p; + /* Choose bases and base types to search for. */ + base1 = ref1; + while (handled_component_p (base1)) + base1 = TREE_OPERAND (base1, 0); + type1 = TREE_TYPE (base1); + base2 = ref2; + while (handled_component_p (base2)) + base2 = TREE_OPERAND (base2, 0); + type2 = TREE_TYPE (base2); + /* Now search for the type1 in the access path of ref2. This would be a common base for doing offset based disambiguation on. */ refp = &ref2; *************** aliasing_component_refs_p (tree ref1, tr *** 627,632 **** --- 639,646 ---- HOST_WIDE_INT offadj, sztmp, msztmp; get_ref_base_and_extent (*refp, &offadj, &sztmp, &msztmp); offset2 -= offadj; + get_ref_base_and_extent (base1, &offadj, &sztmp, &msztmp); + offset1 -= offadj; return ranges_overlap_p (offset1, max_size1, offset2, max_size2); } /* If we didn't find a common base, try the other way around. */ *************** aliasing_component_refs_p (tree ref1, tr *** 643,648 **** --- 657,664 ---- HOST_WIDE_INT offadj, sztmp, msztmp; get_ref_base_and_extent (*refp, &offadj, &sztmp, &msztmp); offset1 -= offadj; + get_ref_base_and_extent (base2, &offadj, &sztmp, &msztmp); + offset2 -= offadj; return ranges_overlap_p (offset1, max_size1, offset2, max_size2); } *************** indirect_ref_may_alias_decl_p (tree ref1 *** 804,814 **** && TREE_CODE (base1) != TARGET_MEM_REF && (TREE_CODE (base1) != MEM_REF || same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1)) ! return aliasing_component_refs_p (ref1, TREE_TYPE (ptrtype1), ref1_alias_set, base1_alias_set, offset1, max_size1, ! ref2, TREE_TYPE ! (reference_alias_ptr_type (ref2)), ref2_alias_set, base2_alias_set, offset2, max_size2, true); --- 820,829 ---- && TREE_CODE (base1) != TARGET_MEM_REF && (TREE_CODE (base1) != MEM_REF || same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1)) ! return aliasing_component_refs_p (ref1, ref1_alias_set, base1_alias_set, offset1, max_size1, ! ref2, ref2_alias_set, base2_alias_set, offset2, max_size2, true); *************** indirect_refs_may_alias_p (tree ref1 ATT *** 951,960 **** || same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1) && (TREE_CODE (base2) != MEM_REF || same_type_for_tbaa (TREE_TYPE (base2), TREE_TYPE (ptrtype2)) == 1)) ! return aliasing_component_refs_p (ref1, TREE_TYPE (ptrtype1), ref1_alias_set, base1_alias_set, offset1, max_size1, ! ref2, TREE_TYPE (ptrtype2), ref2_alias_set, base2_alias_set, offset2, max_size2, false); --- 966,975 ---- || same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1) && (TREE_CODE (base2) != MEM_REF || same_type_for_tbaa (TREE_TYPE (base2), TREE_TYPE (ptrtype2)) == 1)) ! return aliasing_component_refs_p (ref1, ref1_alias_set, base1_alias_set, offset1, max_size1, ! ref2, ref2_alias_set, base2_alias_set, offset2, max_size2, false); Index: gcc/testsuite/g++.dg/torture/pr48695.C =================================================================== *** gcc/testsuite/g++.dg/torture/pr48695.C (revision 0) --- gcc/testsuite/g++.dg/torture/pr48695.C (revision 0) *************** *** 0 **** --- 1,38 ---- + // { dg-do run } + + typedef __SIZE_TYPE__ size_t; + + inline void *operator new (size_t, void *__p) throw() { return __p; } + + struct _Vector_impl + { + int *_M_start; + int *_M_finish; + _Vector_impl () :_M_start (0), _M_finish (0) {} + }; + + struct vector + { + _Vector_impl _M_impl; + int *_M_allocate (size_t __n) + { + return __n != 0 ? new int[__n] : 0; + } + void push_back () + { + new (this->_M_impl._M_finish) int (); + this->_M_impl._M_finish = + this->_M_allocate (this->_M_impl._M_finish - this->_M_impl._M_start) + 1; + } + }; + + int + main () + { + for (int i = 0; i <= 1; i++) + for (int j = 0; j <= 1; j++) + { + vector a[2]; + a[i].push_back (); + } + }