diff options
author | Richard Guenther <rguenther@suse.de> | 2010-05-06 08:53:19 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2010-05-06 08:53:19 +0000 |
commit | a81b065a47a134e66937060f7ae14f1ae939b7b5 (patch) | |
tree | fb40fc61a7dd82108d5aaff3589d2f98c91881e5 | |
parent | 369451ec60604a300eb85c57fc62284d1cd2f837 (diff) | |
download | gcc-a81b065a47a134e66937060f7ae14f1ae939b7b5.zip gcc-a81b065a47a134e66937060f7ae14f1ae939b7b5.tar.gz gcc-a81b065a47a134e66937060f7ae14f1ae939b7b5.tar.bz2 |
re PR middle-end/43987 (type-punning causes broken binaries unless -O0 is used)
2010-05-06 Richard Guenther <rguenther@suse.de>
PR tree-optimization/43987
* tree-ssa-structalias.c (could_have_pointers): For possibly
address-taken variables force pointers to be recorded.
(create_variable_info_for_1): Likewise.
(push_fields_onto_fieldstack): Pass in wheter all fields
must have pointers.
(find_func_aliases): Query types instead of vars whether
they contain pointers where appropriate.
* gcc.c-torture/execute/pr43987.c: New testcase.
* gcc.dg/torture/pta-escape-1.c: Adjust.
* gcc.dg/tree-ssa/pta-escape-1.c: Likewise.
* gcc.dg/tree-ssa/pta-escape-2.c: Likewise.
* gcc.dg/tree-ssa/pta-escape-3.c: Likewise.
* gcc.dg/ipa/ipa-pta-11.c: Likewise.
From-SVN: r159098
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr43987.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pta-escape-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.c | 24 |
8 files changed, 53 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3994866..4d0c54a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2010-05-06 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/43987 + * tree-ssa-structalias.c (could_have_pointers): For possibly + address-taken variables force pointers to be recorded. + (create_variable_info_for_1): Likewise. + (push_fields_onto_fieldstack): Pass in wheter all fields + must have pointers. + (find_func_aliases): Query types instead of vars whether + they contain pointers where appropriate. + 2010-05-06 Jan Hubicka <jh@suse.cz> * cgraphbuild.c (record_reference_ctx): Add varpool_node. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr43987.c b/gcc/testsuite/gcc.c-torture/execute/pr43987.c new file mode 100644 index 0000000..ee41bdf --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr43987.c @@ -0,0 +1,20 @@ +char B[256 * sizeof(void *)]; +typedef void *FILE; +typedef struct globals { + int c; + FILE *l; +} __attribute__((may_alias)) T; +void add_input_file(FILE *file) +{ + (*(T*)&B).l[0] = file; +} +extern void abort (void); +int main() +{ + FILE x; + (*(T*)&B).l = &x; + add_input_file ((void *)-1); + if ((*(T*)&B).l[0] != (void *)-1) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c index 6ef7438..947ab81 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c @@ -29,5 +29,5 @@ int main() /* It isn't clear if the escape if l is strictly necessary, if it were we should have i, r and s in ESCAPED as well. */ -/* { dg-final { scan-ipa-dump "ESCAPED = { l k }" "pta" } } */ +/* { dg-final { scan-ipa-dump "ESCAPED = { ESCAPED NONLOCAL l k }" "pta" } } */ /* { dg-final { cleanup-ipa-dump "pta" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/pta-escape-1.c b/gcc/testsuite/gcc.dg/torture/pta-escape-1.c index 39aefb5..3929d97 100644 --- a/gcc/testsuite/gcc.dg/torture/pta-escape-1.c +++ b/gcc/testsuite/gcc.dg/torture/pta-escape-1.c @@ -30,5 +30,5 @@ main() return 0; } -/* { dg-final { scan-tree-dump "ESCAPED = { i }" "alias" } } */ +/* { dg-final { scan-tree-dump "ESCAPED = { ESCAPED NONLOCAL i }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c index ee8a84b..50d7357 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c @@ -33,5 +33,5 @@ int main() return 0; } -/* { dg-final { scan-tree-dump "ESCAPED, points-to vars: { x }" "alias" } } */ +/* { dg-final { scan-tree-dump "ESCAPED, points-to non-local, points-to vars: { x }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c index ad5ed2e..226105e 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c @@ -34,5 +34,5 @@ int main() return 0; } -/* { dg-final { scan-tree-dump "ESCAPED, points-to vars: { x }" "alias" } } */ +/* { dg-final { scan-tree-dump "ESCAPED, points-to non-local, points-to vars: { x }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c index ea11c8a..15b06af 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c @@ -38,5 +38,5 @@ int main() return 0; } -/* { dg-final { scan-tree-dump "ESCAPED, points-to vars: { x }" "alias" } } */ +/* { dg-final { scan-tree-dump "ESCAPED, points-to non-local, points-to vars: { x }" "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index f688d9b..19aa5db 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -2959,7 +2959,11 @@ type_could_have_pointers (tree type) static bool could_have_pointers (tree t) { - return type_could_have_pointers (TREE_TYPE (t)); + return (((TREE_CODE (t) == VAR_DECL + || TREE_CODE (t) == PARM_DECL + || TREE_CODE (t) == RESULT_DECL) + && (TREE_PUBLIC (t) || DECL_EXTERNAL (t) || TREE_ADDRESSABLE (t))) + || type_could_have_pointers (TREE_TYPE (t))); } /* Return the position, in bits, of FIELD_DECL from the beginning of its @@ -4232,7 +4236,7 @@ find_func_aliases (gimple origt) /* If we are returning a value, assign it to the result. */ lhsop = gimple_call_lhs (t); if (lhsop - && could_have_pointers (lhsop)) + && type_could_have_pointers (TREE_TYPE (lhsop))) { struct constraint_expr rhs; struct constraint_expr *lhsp; @@ -4286,7 +4290,7 @@ find_func_aliases (gimple origt) operations with pointer result, others are dealt with as escape points if they have pointer operands. */ else if (is_gimple_assign (t) - && could_have_pointers (gimple_assign_lhs (t))) + && type_could_have_pointers (TREE_TYPE (gimple_assign_lhs (t)))) { /* Otherwise, just a regular assignment statement. */ tree lhsop = gimple_assign_lhs (t); @@ -4855,7 +4859,7 @@ var_can_have_subvars (const_tree v) static bool push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, - HOST_WIDE_INT offset) + HOST_WIDE_INT offset, bool must_have_pointers_p) { tree field; bool empty_p = true; @@ -4880,7 +4884,8 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) push = true; else if (!push_fields_onto_fieldstack - (TREE_TYPE (field), fieldstack, offset + foff) + (TREE_TYPE (field), fieldstack, offset + foff, + must_have_pointers_p) && (DECL_SIZE (field) && !integer_zerop (DECL_SIZE (field)))) /* Empty structures may have actual size, like in C++. So @@ -4906,6 +4911,7 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, && !pair->has_unknown_size && !has_unknown_size && pair->offset + (HOST_WIDE_INT)pair->size == offset + foff + && !must_have_pointers_p && !could_have_pointers (field)) { pair->size += TREE_INT_CST_LOW (DECL_SIZE (field)); @@ -4919,7 +4925,8 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, pair->size = TREE_INT_CST_LOW (DECL_SIZE (field)); else pair->size = -1; - pair->may_have_pointers = could_have_pointers (field); + pair->may_have_pointers + = must_have_pointers_p || could_have_pointers (field); pair->only_restrict_pointers = (!has_unknown_size && POINTER_TYPE_P (TREE_TYPE (field)) @@ -5196,7 +5203,10 @@ create_variable_info_for_1 (tree decl, const char *name) bool notokay = false; unsigned int i; - push_fields_onto_fieldstack (decl_type, &fieldstack, 0); + push_fields_onto_fieldstack (decl_type, &fieldstack, 0, + TREE_PUBLIC (decl) + || DECL_EXTERNAL (decl) + || TREE_ADDRESSABLE (decl)); for (i = 0; !notokay && VEC_iterate (fieldoff_s, fieldstack, i, fo); i++) if (fo->has_unknown_size |