aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-11-26 16:12:49 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2010-11-26 16:12:49 +0000
commit67701d1ddcc49905765c0a7b6610e9c284f467cd (patch)
treecdc2196f719da34e91111fc8b84478b26194f103 /gcc
parenta50c005fea650125aa5bd574b64dd0aae9b206a4 (diff)
downloadgcc-67701d1ddcc49905765c0a7b6610e9c284f467cd.zip
gcc-67701d1ddcc49905765c0a7b6610e9c284f467cd.tar.gz
gcc-67701d1ddcc49905765c0a7b6610e9c284f467cd.tar.bz2
re PR lto/46648 (type mismatch in array reference; verify_stmts failed)
2010-11-26 Richard Guenther <rguenther@suse.de> PR lto/46648 * gimple.c (gtc_visit): Do not return true for members of an SCC still being processed but the current lattice value of the member. Treat SCC members comparison state as lattice, starting at equal, eventually dropping to unequal. (gimple_types_compatible_p_1): Likewise. * gcc.dg/lto/20101125-1_0.c: New testcase. * gcc.dg/lto/20101125-1_1.c: Likewise. From-SVN: r167183
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/gimple.c33
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/lto/20101125-1_0.c24
-rw-r--r--gcc/testsuite/gcc.dg/lto/20101125-1_1.c17
5 files changed, 72 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2687d4e..810590c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,14 @@
2010-11-26 Richard Guenther <rguenther@suse.de>
+ PR lto/46648
+ * gimple.c (gtc_visit): Do not return true for members of an
+ SCC still being processed but the current lattice value of
+ the member. Treat SCC members comparison state as lattice,
+ starting at equal, eventually dropping to unequal.
+ (gimple_types_compatible_p_1): Likewise.
+
+2010-11-26 Richard Guenther <rguenther@suse.de>
+
PR middle-end/46559
* dwarf2out.c (dwarf2out_finish): Use comp_unit_die as root
for location list processing.
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 851e30f..67c80e3 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -3515,27 +3515,23 @@ gtc_visit (tree t1, tree t2, enum gtc_mode mode,
if ((slot = pointer_map_contains (sccstate, p)) != NULL)
cstate = (struct sccs *)*slot;
+ /* Not yet visited. DFS recurse. */
if (!cstate)
{
- bool res;
- /* Not yet visited. DFS recurse. */
- res = gimple_types_compatible_p_1 (t1, t2, mode, p,
- sccstack, sccstate, sccstate_obstack);
- if (!cstate)
- cstate = (struct sccs *)* pointer_map_contains (sccstate, p);
+ gimple_types_compatible_p_1 (t1, t2, mode, p,
+ sccstack, sccstate, sccstate_obstack);
+ cstate = (struct sccs *)* pointer_map_contains (sccstate, p);
state->low = MIN (state->low, cstate->low);
- /* If the type is no longer on the SCC stack and thus is not part
- of the parents SCC, return its state. Otherwise we will
- ignore this pair and assume equality. */
- if (!cstate->on_sccstack)
- return res;
}
+ /* If the type is still on the SCC stack adjust the parents low. */
if (cstate->dfsnum < state->dfsnum
&& cstate->on_sccstack)
state->low = MIN (cstate->dfsnum, state->low);
- /* We are part of our parents SCC, skip this entry and return true. */
- return true;
+ /* Return the current lattice value. We start with an equality
+ assumption so types part of a SCC will be optimistically
+ treated equal unless proven otherwise. */
+ return cstate->u.same_p;
}
/* Worker for gimple_types_compatible.
@@ -3559,6 +3555,9 @@ gimple_types_compatible_p_1 (tree t1, tree t2, enum gtc_mode mode,
state->dfsnum = gtc_next_dfs_num++;
state->low = state->dfsnum;
state->on_sccstack = true;
+ /* Start with an equality assumption. As we DFS recurse into child
+ SCCs this assumption may get revisited. */
+ state->u.same_p = 1;
/* If their attributes are not the same they can't be the same type. */
if (!attribute_list_equal (TYPE_ATTRIBUTES (t1), TYPE_ATTRIBUTES (t2)))
@@ -3822,22 +3821,22 @@ different_types:
/* Common exit path for types that are compatible. */
same_types:
- state->u.same_p = 1;
- goto pop;
+ gcc_assert (state->u.same_p == 1);
pop:
if (state->low == state->dfsnum)
{
type_pair_t x;
- /* Pop off the SCC and set its cache values. */
+ /* Pop off the SCC and set its cache values to the final
+ comparison result. */
do
{
struct sccs *cstate;
x = VEC_pop (type_pair_t, *sccstack);
cstate = (struct sccs *)*pointer_map_contains (sccstate, x);
cstate->on_sccstack = false;
- x->same_p[mode] = cstate->u.same_p;
+ x->same_p[mode] = state->u.same_p;
}
while (x != p);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 57a7b42..80706c0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2010-11-26 Richard Guenther <rguenther@suse.de>
+
+ PR lto/46648
+ * gcc.dg/lto/20101125-1_0.c: New testcase.
+ * gcc.dg/lto/20101125-1_1.c: Likewise.
+
2010-11-22 Bud Davis <jmdavis@link.com>
* arith_divide_no_check.f
diff --git a/gcc/testsuite/gcc.dg/lto/20101125-1_0.c b/gcc/testsuite/gcc.dg/lto/20101125-1_0.c
new file mode 100644
index 0000000..662dd24
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/20101125-1_0.c
@@ -0,0 +1,24 @@
+/* { dg-lto-do link } */
+
+struct X {
+ int i;
+};
+
+struct W {
+ struct U *p;
+ struct X *q;
+};
+
+struct U {
+ struct W a[1];
+};
+
+void foo(struct U *ptr)
+{
+ ptr->a[0].p = 0;
+}
+
+int main(void)
+{
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/lto/20101125-1_1.c b/gcc/testsuite/gcc.dg/lto/20101125-1_1.c
new file mode 100644
index 0000000..2924e3f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/20101125-1_1.c
@@ -0,0 +1,17 @@
+struct X {
+ char i;
+};
+
+struct W {
+ struct U *p;
+ struct X *q;
+};
+
+struct U {
+ struct W a[1];
+};
+
+void bar(struct U *ptr)
+{
+ ptr->a[0].p = 0;
+}