diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c85ff0e8ba0..933b664d4b0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2009-10-24 Eric Botcazou + + * tree-ssa-alias.c (nonaliasing_component_refs_p): Rename into... + (aliasing_component_refs_p): ...this. Return true if there is no + common base and the base access types have the same alias set. + (indirect_ref_may_alias_decl_p): Adjust for above renaming. + (indirect_refs_may_alias_p): Likewise. + 2009-10-23 Joseph Myers PR c/40033 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e7ba1b656e0..481a82e6c78 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2009-10-24 Eric Botcazou + + * gnat.dg/opt4.adb: New test. + 2009-10-23 Joseph Myers PR c/40033 diff --git a/gcc/testsuite/gnat.dg/opt4.adb b/gcc/testsuite/gnat.dg/opt4.adb new file mode 100644 index 00000000000..caa5ab3a6cb --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt4.adb @@ -0,0 +1,22 @@ +-- { dg-do run } +-- { dg-options "-O2" } + +procedure Opt4 is + + type Rec (D : Natural) is record + S : String (1..D); + end record; + + procedure Test (R : Rec) is + begin + if R.D /= 9 then + raise Program_Error; + end if; + end; + + R : Rec(9); + +begin + R := (9, "123456789"); + Test (R); +end; diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index e619190386c..ba5cbbc9488 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -553,10 +553,10 @@ same_type_for_tbaa (tree type1, tree type2) on an indirect reference may alias. */ static bool -nonaliasing_component_refs_p (tree ref1, tree type1, - HOST_WIDE_INT offset1, HOST_WIDE_INT max_size1, - tree ref2, tree type2, - HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2) +aliasing_component_refs_p (tree ref1, tree type1, + HOST_WIDE_INT offset1, HOST_WIDE_INT max_size1, + tree ref2, tree type2, + HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2) { /* If one reference is a component references through pointers try to find a common base and apply offset based disambiguation. This handles @@ -600,9 +600,19 @@ nonaliasing_component_refs_p (tree ref1, tree type1, offset1 -= offadj; return ranges_overlap_p (offset1, max_size1, offset2, max_size2); } - /* If we have two type access paths B1.path1 and B2.path2 they may - only alias if either B1 is in B2.path2 or B2 is in B1.path1. */ - return false; + + /* We haven't found any common base to apply offset-based disambiguation. + There are two cases: + 1. The base access types have the same alias set. This can happen + in Ada when a function with an unconstrained parameter passed by + reference is called on a constrained object and inlined: the types + have the same alias set but aren't equivalent. The references may + alias in this case. + 2. The base access types don't have the same alias set, i.e. one set + is a subset of the other. We have proved that B1 is not in the + access path B2.path and that B2 is not in the access path B1.path + so the references may not alias. */ + return get_alias_set (type1) == get_alias_set (type2); } /* Return true if two memory references based on the variables BASE1 @@ -681,10 +691,10 @@ indirect_ref_may_alias_decl_p (tree ref1, tree ptr1, if (ref1 && ref2 && handled_component_p (ref1) && handled_component_p (ref2)) - return nonaliasing_component_refs_p (ref1, TREE_TYPE (TREE_TYPE (ptr1)), - offset1, max_size1, - ref2, TREE_TYPE (base2), - offset2, max_size2); + return aliasing_component_refs_p (ref1, TREE_TYPE (TREE_TYPE (ptr1)), + offset1, max_size1, + ref2, TREE_TYPE (base2), + offset2, max_size2); return true; } @@ -742,10 +752,10 @@ indirect_refs_may_alias_p (tree ref1, tree ptr1, if (ref1 && ref2 && handled_component_p (ref1) && handled_component_p (ref2)) - return nonaliasing_component_refs_p (ref1, TREE_TYPE (TREE_TYPE (ptr1)), - offset1, max_size1, - ref2, TREE_TYPE (TREE_TYPE (ptr2)), - offset2, max_size2); + return aliasing_component_refs_p (ref1, TREE_TYPE (TREE_TYPE (ptr1)), + offset1, max_size1, + ref2, TREE_TYPE (TREE_TYPE (ptr2)), + offset2, max_size2); return true; }