From 832a0c1d090950cef0735c66b16955944b063579 Mon Sep 17 00:00:00 2001 From: Daniel Berlin Date: Wed, 3 May 2006 03:19:22 +0000 Subject: [PATCH] re PR tree-optimization/26626 (ICE in in add_virtual_operand) 2006-05-02 Daniel Berlin Fix PR tree-optimization/26626 * tree-ssa-structalias.c (compute_points_to_sets): For now, solve always. * tree-ssa-operands.c (access_can_touch_variable): Allow typecasting through union pointers. From-SVN: r113493 --- gcc/ChangeLog | 8 +++++++ gcc/testsuite/gcc.c-torture/compile/pr26626.c | 13 ++++++++++++ gcc/tree-ssa-operands.c | 21 +++++++++++++++++++ gcc/tree-ssa-structalias.c | 2 +- 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr26626.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 162af2fe98ca..6e73c304f345 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2006-05-02 Daniel Berlin + + Fix PR tree-optimization/26626 + * tree-ssa-structalias.c (compute_points_to_sets): For now, solve + always. + * tree-ssa-operands.c (access_can_touch_variable): Allow + typecasting through union pointers. + 2006-05-02 Jakub Jelinek PR c++/26943 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr26626.c b/gcc/testsuite/gcc.c-torture/compile/pr26626.c new file mode 100644 index 000000000000..a4e03012b253 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr26626.c @@ -0,0 +1,13 @@ +typedef union { + int d; +} U; + +int rv; +void breakme() +{ + U *rv0; + U *pretmp = (U*)&rv; + rv0 = pretmp; + rv0->d = 42; +} + diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index e979b4ce65aa..68613fe9564a 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -1118,11 +1118,32 @@ access_can_touch_variable (tree ref, tree alias, HOST_WIDE_INT offset, { return (struct foos *)&foo; } (taken from 20000623-1.c) + + The docs also say/imply that access through union pointers + is legal (but *not* if you take the address of the union member, + i.e. the inverse), such that you can do + + typedef union { + int d; + } U; + + int rv; + void breakme() + { + U *rv0; + U *pretmp = (U*)&rv; + rv0 = pretmp; + rv0->d = 42; + } + To implement this, we just punt on accesses through union + pointers entirely. */ else if (ref && flag_strict_aliasing && TREE_CODE (ref) != INDIRECT_REF && !MTAG_P (alias) + && (TREE_CODE (base) != INDIRECT_REF + || TREE_CODE (TREE_TYPE (base)) != UNION_TYPE) && !AGGREGATE_TYPE_P (TREE_TYPE (alias)) && TREE_CODE (TREE_TYPE (alias)) != COMPLEX_TYPE && !POINTER_TYPE_P (TREE_TYPE (alias))) diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 7a00de456117..c5b6cabaadb9 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -4485,7 +4485,7 @@ compute_points_to_sets (struct alias_info *ai) dump_constraints (dump_file); } - if (need_to_solve ()) + if (1 || need_to_solve ()) { if (dump_file) fprintf (dump_file,