summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0162-2011-04-21-Richard-Guenther-rguenther-suse.de.patch
blob: fa83ccc5e68bafd9ccaf1c800892f121682a2d66 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
Upstream-Status: Inappropriate [Backport]
From d0c1a282504a0fa941a9ae22536c73f64d8c5762 Mon Sep 17 00:00:00 2001
From: rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Thu, 21 Apr 2011 14:40:53 +0000
Subject: [PATCH 162/200] 2011-04-21  Richard Guenther  <rguenther@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.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@172831 138bc75d-0d04-0410-961f-82ee72b054a4

index e26c75d..3b0e585 100644
new file mode 100644
index 0000000..44e6c77
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr48695.C
@@ -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 ();
+      }
+}
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index bd8953b..8434179 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -594,11 +594,11 @@ same_type_for_tbaa (tree type1, tree type2)
    are the respective alias sets.  */
 
 static bool
-aliasing_component_refs_p (tree ref1, tree type1,
+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, tree type2,
+			   tree ref2,
 			   alias_set_type ref2_alias_set,
 			   alias_set_type base2_alias_set,
 			   HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2,
@@ -610,9 +610,21 @@ aliasing_component_refs_p (tree ref1, tree type1,
        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;
@@ -628,6 +640,8 @@ aliasing_component_refs_p (tree ref1, tree type1,
       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.  */
@@ -644,6 +658,8 @@ aliasing_component_refs_p (tree ref1, tree type1,
       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);
     }
 
@@ -805,11 +821,10 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
       && 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),
+    return aliasing_component_refs_p (ref1,
 				      ref1_alias_set, base1_alias_set,
 				      offset1, max_size1,
-				      ref2, TREE_TYPE
-				              (reference_alias_ptr_type (ref2)),
+				      ref2,
 				      ref2_alias_set, base2_alias_set,
 				      offset2, max_size2, true);
 
@@ -952,10 +967,10 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
 	  || 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),
+    return aliasing_component_refs_p (ref1,
 				      ref1_alias_set, base1_alias_set,
 				      offset1, max_size1,
-				      ref2, TREE_TYPE (ptrtype2),
+				      ref2,
 				      ref2_alias_set, base2_alias_set,
 				      offset2, max_size2, false);
 
-- 
1.7.0.4

OpenPOWER on IntegriCloud