re PR middle-end/17849 (intrinsic_pack.f90)
authorAndrew Pinski <pinskia@physics.uc.edu>
Wed, 6 Oct 2004 23:45:48 +0000 (23:45 +0000)
committerAndrew Pinski <pinskia@gcc.gnu.org>
Wed, 6 Oct 2004 23:45:48 +0000 (16:45 -0700)
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.

From-SVN: r88650

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.fortran-torture/compile/nested.f90 [new file with mode: 0644]
gcc/tree-nested.c

index 30e873f7a57d03e876d299b085fbe12f138a1394..ac4ef2164b520dd993910306f588886b6cd08b96 100644 (file)
@@ -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.
index b867e20e0f86c573c5b60c02a8912e15017bfae6..498f92d51ab87500aab50bcecb5594931365f2aa 100644 (file)
@@ -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 (file)
index 0000000..1059684
--- /dev/null
@@ -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
index d2608a837f0eed415dfaa1cbe39ad2c44ce6dc50..3f500f6f138914fcae2f05c2316735ce8ce0cedb 100644 (file)
@@ -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.  */