aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/opt/alias4.C56
-rw-r--r--gcc/tree-ssa-alias.c7
3 files changed, 68 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b072bab..8044ed5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2006-06-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/27768
+ * tree-ssa-alias.c (compute_flow_insensitive_aliasing): Add
+ may_aliases already in the tag's annotations to the bitmap.
+
2006-06-28 Roger Sayle <roger@eyesopen.com>
* genpreds.c (write_predicate_stmts) <IOR>: Add missing break.
diff --git a/gcc/testsuite/g++.dg/opt/alias4.C b/gcc/testsuite/g++.dg/opt/alias4.C
new file mode 100644
index 0000000..6965b8c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/alias4.C
@@ -0,0 +1,56 @@
+// PR c++/27768
+// Alias grouping was losing some may_aliases, causing us to think
+// the store to w.p was dead.
+
+// { dg-do run }
+// { dg-options "-O2" }
+
+int N = 1;
+
+struct VA
+{
+ int *p, *q, *r;
+
+ VA() : p(), q() {}
+ VA(const VA&) : p(), q() {}
+ ~VA() { if (p) --N; }
+};
+
+inline void foo(VA, VA, VA) {}
+
+struct VB
+{
+ VA va;
+
+ VB() {}
+
+ VB(const VB&)
+ {
+ va.p = new int(va.q - va.p);
+ va.r = va.p + (va.q - va.p);
+ foo(va, va, va);
+ }
+};
+
+struct VC : VB { char c; };
+struct V : VC {};
+
+struct WA
+{
+ struct X {};
+ X **p, **q, **r;
+
+ WA() : p() {}
+ ~WA() { if (p) --N; }
+};
+
+struct W : WA {};
+
+int main()
+{
+ {
+ V v, u(v);
+ W w;
+ }
+ return N;
+}
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 2da4e61..1607c71 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -1162,6 +1162,7 @@ compute_flow_insensitive_aliasing (struct alias_info *ai)
struct alias_map_d *p_map = ai->pointers[i];
tree tag = var_ann (p_map->var)->symbol_mem_tag;
var_ann_t tag_ann = var_ann (tag);
+ tree var;
/* Call-clobbering information is not finalized yet at this point. */
if (PTR_IS_REF_ALL (p_map->var))
@@ -1170,11 +1171,15 @@ compute_flow_insensitive_aliasing (struct alias_info *ai)
p_map->total_alias_vops = 0;
p_map->may_aliases = BITMAP_ALLOC (&alias_obstack);
+ /* Add any pre-existing may_aliases to the bitmap used to represent
+ TAG's alias set in case we need to group aliases. */
+ for (j = 0; VEC_iterate (tree, tag_ann->may_aliases, j, var); ++j)
+ bitmap_set_bit (p_map->may_aliases, DECL_UID (var));
+
for (j = 0; j < ai->num_addressable_vars; j++)
{
struct alias_map_d *v_map;
var_ann_t v_ann;
- tree var;
bool tag_stored_p, var_stored_p;
v_map = ai->addressable_vars[j];