aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr22615.C28
-rw-r--r--gcc/tree-ssa-structalias.c15
3 files changed, 53 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fb92782..9b8f86c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2005-08-14 Daniel Berlin <dberlin@dberlin.org>
+
+ Fix PR tree-optimization/22615
+
+ * tree-ssa-structalias.c (solution_set_add): Handle
+ first_vi_for_offset returning NULL.
+ (do_da_constraint): Ditto.
+ (do_sd_constraint): Ditto.
+ (do_ds_constraint): Ditto
+ (find_func_aliases): Ditto.
+ (build_constraint_graph): RHS is allowed be ANYTHING.
+ (first_vi_for_offset): Return NULL if we couldn't find anything at
+ the offset.
+
2005-08-14 Ulrich Weigand <uweigand@de.ibm.com>
* config/s390/s390.c (s390_canonicalize_comparison): Prefer register
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr22615.C b/gcc/testsuite/g++.dg/tree-ssa/pr22615.C
new file mode 100644
index 0000000..a8936c4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr22615.C
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+/* Ensure that we don't crash when people decide to return the address of padding. */
+
+struct A
+{
+ char c;
+ int i;
+};
+
+A a;
+
+struct B
+{
+ char c, d;
+};
+
+union C
+{
+ A *p;
+ B *q;
+
+ C() : p(&a) {}
+ char& foo() { return q->d; }
+};
+void bar() { C().foo() = 0; }
+
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 13b9751..cad485a 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -612,6 +612,8 @@ solution_set_add (bitmap set, unsigned HOST_WIDE_INT offset)
{
unsigned HOST_WIDE_INT fieldoffset = get_varinfo (i)->offset + offset;
varinfo_t v = first_vi_for_offset (get_varinfo (i), fieldoffset);
+ if (!v)
+ continue;
bitmap_set_bit (result, v->id);
}
else if (get_varinfo (i)->is_artificial_var
@@ -997,7 +999,7 @@ build_constraint_graph (void)
/* x = &y */
bitmap_set_bit (get_varinfo (lhs.var)->solution, rhs.var);
}
- else if (rhs.var > anything_id && lhs.var > anything_id)
+ else if (lhs.var > anything_id)
{
/* Ignore 0 weighted self edges, as they can't possibly contribute
anything */
@@ -1332,6 +1334,8 @@ do_da_constraint (constraint_graph_t graph ATTRIBUTE_UNUSED,
unsigned HOST_WIDE_INT fieldoffset = get_varinfo (j)->offset + offset;
v = first_vi_for_offset (get_varinfo (j), fieldoffset);
+ if (!v)
+ continue;
t = v->node;
sol = get_varinfo (t)->solution;
if (!bitmap_bit_p (sol, rhs))
@@ -1375,6 +1379,8 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c,
unsigned int t;
v = first_vi_for_offset (get_varinfo (j), fieldoffset);
+ if (!v)
+ continue;
t = v->node;
if (int_add_graph_edge (graph, lhs, t, 0))
flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
@@ -1419,6 +1425,8 @@ do_ds_constraint (constraint_graph_t graph, constraint_t c, bitmap delta)
unsigned HOST_WIDE_INT fieldoffset = get_varinfo (j)->offset + loff;
v = first_vi_for_offset (get_varinfo (j), fieldoffset);
+ if (!v)
+ continue;
t = v->node;
if (int_add_graph_edge (graph, t, rhs, roff))
{
@@ -2878,7 +2886,7 @@ find_func_aliases (tree t, struct alias_info *ai)
OFFSET.
Effectively, walk the chain of fields for the variable START to find the
first field that overlaps with OFFSET.
- Abort if we can't find one. */
+ Return NULL if we can't find one. */
static varinfo_t
first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset)
@@ -2894,8 +2902,7 @@ first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset)
return curr;
curr = curr->next;
}
-
- gcc_unreachable ();
+ return NULL;
}