diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fb927823d83..9b8f86cc5a5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2005-08-14 Daniel Berlin + + 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 * 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 00000000000..a8936c4cb65 --- /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 13b9751288f..cad485abd77 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; }