diff options
author | pinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-10-06 23:45:48 +0000 |
---|---|---|
committer | pinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-10-06 23:45:48 +0000 |
commit | 93910a1b3d7eec75d284edf1d790a5fcfa822c69 (patch) | |
tree | dac70c341cb889c3838311318e51b6b4b07c3376 /gcc | |
parent | 5c50ce6234b2fbab98643799d865a7db7c1bb1ad (diff) | |
download | gcc-93910a1b3d7eec75d284edf1d790a5fcfa822c69.tar.gz |
2004-10-06 Andrew Pinski <pinskia@physics.uc.edu>
PR middle-end/17849
* gfortran.fortran-torture/compile/nested.f90: New test
2004-10-06 Andrew Pinski <pinskia@physics.uc.edu>
PR middle-end/17849
* tree-nested.c (walk_stmt_info): Add changed field.
(convert_nonlocal_reference): Set changed to when we
change a decl to unnested decl.
<case ADDR_EXPR>: Instead of checking if the immediate part
of the ADDR_EXPR changed, check the field changed.
Use recompute_tree_invarant_for_addr_expr instead of unsetting
TREE_INVARIANT.
(convert_local_reference): Set changed to when we
change a decl to unnested decl.
<case ADDR_EXPR>: Instead of checking if the immediate part
of the ADDR_EXPR changed, check the field changed.
Also call recompute_tree_invarant_for_addr_expr on the ADDR_EXPR.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@88650 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.fortran-torture/compile/nested.f90 | 23 | ||||
-rw-r--r-- | gcc/tree-nested.c | 15 |
4 files changed, 54 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 30e873f7a57..ac4ef2164b5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2004-10-06 Andrew Pinski <pinskia@physics.uc.edu> + + PR middle-end/17849 + * tree-nested.c (walk_stmt_info): Add changed field. + (convert_nonlocal_reference): Set changed to when we + change a decl to unnested decl. + <case ADDR_EXPR>: Instead of checking if the immediate part + of the ADDR_EXPR changed, check the field changed. + Use recompute_tree_invarant_for_addr_expr instead of unsetting + TREE_INVARIANT. + (convert_local_reference): Set changed to when we + change a decl to unnested decl. + <case ADDR_EXPR>: Instead of checking if the immediate part + of the ADDR_EXPR changed, check the field changed. + Also call recompute_tree_invarant_for_addr_expr on the ADDR_EXPR. + 2004-10-06 Kazu Hirata <kazu@cs.umass.edu> * defaults.h (DWARF2_GENERATE_TEXT_SECTION_LABEL): Remove. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b867e20e0f8..498f92d51ab 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-10-06 Andrew Pinski <pinskia@physics.uc.edu> + + PR middle-end/17849 + * gfortran.fortran-torture/compile/nested.f90: New test + 2004-10-06 Joseph S. Myers <jsm@polyomino.org.uk> * gcc.dg/Wconversion-2.c, gcc.dg/func-args-1.c: New tests. diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/nested.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/nested.f90 new file mode 100644 index 00000000000..1059684ddd5 --- /dev/null +++ b/gcc/testsuite/gfortran.fortran-torture/compile/nested.f90 @@ -0,0 +1,23 @@ +! Program to test the nested functions +program intrinsic_pack + integer, parameter :: val(9) = (/0,0,0,0,9,0,0,0,7/) + integer, dimension(3, 3) :: a + integer, dimension(6) :: b + + a = reshape (val, (/3, 3/)) + b = 0 + b(1:6:3) = pack (a, a .ne. 0); + if (any (b(1:6:3) .ne. (/9, 7/))) call abort + b = pack (a(2:3, 2:3), a(2:3, 2:3) .ne. 0, (/1, 2, 3, 4, 5, 6/)); + if (any (b .ne. (/9, 7, 3, 4, 5, 6/))) call abort + +contains + subroutine tests_with_temp + ! A few tests which involve a temporary + if (any (pack(a, a.ne.0) .ne. (/9, 7/))) call abort + if (any (pack(a, .true.) .ne. val)) call abort + if (size(pack (a, .false.)) .ne. 0) call abort + if (any (pack(a, .false., (/1,2,3/)).ne. (/1,2,3/))) call abort + + end subroutine tests_with_temp +end program diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index d2608a837f0..3f500f6f138 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -518,6 +518,7 @@ struct walk_stmt_info tree_stmt_iterator tsi; struct nesting_info *info; bool val_only; + bool changed; }; /* A subroutine of walk_function. Iterate over all sub-statements of *TP. */ @@ -732,6 +733,7 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data) tree target_context = decl_function_context (t); struct nesting_info *i; tree x; + wi->changed = true; for (i = info->outer; i->context != target_context; i = i->outer) continue; @@ -770,17 +772,17 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data) case ADDR_EXPR: { bool save_val_only = wi->val_only; - tree save_sub = TREE_OPERAND (t, 0); + wi->changed = false; wi->val_only = false; walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference, wi, NULL); wi->val_only = true; - if (save_sub != TREE_OPERAND (t, 0)) + if (wi->changed) { /* If we changed anything, then TREE_INVARIANT is be wrong, since we're no longer directly referencing a decl. */ - TREE_INVARIANT (t) = 0; + recompute_tree_invarant_for_addr_expr (t); /* If the callback converted the address argument in a context where we only accept variables (and min_invariant, presumably), @@ -874,6 +876,7 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data) field = lookup_field_for_decl (info, t, NO_INSERT); if (!field) break; + wi->changed = true; x = get_frame_field (info, info->context, field, &wi->tsi); if (wi->val_only) @@ -885,17 +888,19 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data) case ADDR_EXPR: { bool save_val_only = wi->val_only; - tree save_sub = TREE_OPERAND (t, 0); + wi->changed = false; wi->val_only = false; walk_tree (&TREE_OPERAND (t, 0), convert_local_reference, wi, NULL); wi->val_only = save_val_only; /* If we converted anything ... */ - if (TREE_OPERAND (t, 0) != save_sub) + if (wi->changed) { /* Then the frame decl is now addressable. */ TREE_ADDRESSABLE (info->frame_decl) = 1; + + recompute_tree_invarant_for_addr_expr (t); /* If we are in a context where we only accept values, then compute the address into a temporary. */ |