]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/c-iterate.c
Make more robust in two places.
[gcc.git] / gcc / c-iterate.c
index 04d4b7073ff79c7220f6a59e72d2963c42927295..99f9a794d2ae26dfac22c9db7a261ea57bd48217 100644 (file)
@@ -1,5 +1,5 @@
 /* Build expressions with type checking for C compiler.
-   Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -31,7 +31,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "rtl.h"
 
 static void expand_stmt_with_iterators_1 ();
-static tree collect_iterators();
+static tree collect_iterators ();
 static void iterator_loop_prologue ();
 static void iterator_loop_epilogue ();
 static void add_ixpansion ();
@@ -97,6 +97,9 @@ struct iter_stack_node
 struct iter_stack_node *iter_stack;
 
 struct iter_stack_node sublevel_ixpansions;
+
+/* During collect_iterators, a list of SAVE_EXPRs already scanned.  */
+static tree save_exprs;
 \f
 /* Initialize our obstack once per compilation.  */
 
@@ -144,7 +147,9 @@ void
 iterator_expand (stmt)
     tree stmt;
 {
-  tree iter_list = collect_iterators (stmt, NULL_TREE);
+  tree iter_list;
+  save_exprs = NULL_TREE;
+  iter_list = collect_iterators (stmt, NULL_TREE);
   expand_stmt_with_iterators_1 (stmt, iter_list);
   istack_sublevel_to_current ();
 }
@@ -202,6 +207,14 @@ collect_iterators (exp, list)
        return list;
       }
 
+    case SAVE_EXPR:
+      /* In each scan, scan a given save_expr only once.  */
+      if (value_member (exp, save_exprs))
+       return list;
+
+      save_exprs = tree_cons (NULL_TREE, exp, save_exprs);
+      return collect_iterators (TREE_OPERAND (exp, 0), list);
+
       /* we do not automatically iterate blocks -- one must */
       /* use the FOR construct to do that */
 
@@ -212,14 +225,36 @@ collect_iterators (exp, list)
       switch (TREE_CODE_CLASS (TREE_CODE (exp)))
        {
        case '1':
+         return collect_iterators (TREE_OPERAND (exp, 0), list);
+
        case '2':
        case '<':
+         return collect_iterators (TREE_OPERAND (exp, 0),
+                                   collect_iterators (TREE_OPERAND (exp, 1),
+                                                      list));
+
        case 'e':
        case 'r':
          {
-           int num_args = tree_code_length[TREE_CODE (exp)];
+           int num_args = tree_code_length[(int) TREE_CODE (exp)];
            int i;
 
+           /* Some tree codes have RTL, not trees, as operands.  */
+           switch (TREE_CODE (exp))
+             {
+             case CALL_EXPR:
+               num_args = 2;
+               break;
+             case METHOD_CALL_EXPR:
+               num_args = 3;
+               break;
+             case WITH_CLEANUP_EXPR:
+               num_args = 1;
+               break;
+             case RTL_EXPR:
+               return list;
+             }
+               
            for (i = 0; i < num_args; i++)
              list = collect_iterators (TREE_OPERAND (exp, i), list);
            return list;
@@ -243,19 +278,22 @@ iterator_loop_prologue (idecl, start_note, end_note)
      tree idecl;
      rtx *start_note, *end_note;
 {
+  tree expr;
+
   /* Force the save_expr in DECL_INITIAL to be calculated
      if it hasn't been calculated yet.  */
-  expand_expr (DECL_INITIAL (idecl), 0, VOIDmode, 0);
+  expand_expr (DECL_INITIAL (idecl), const0_rtx, VOIDmode, 0);
 
   if (DECL_RTL (idecl) == 0)
     expand_decl (idecl);
 
   if (start_note)
     *start_note = emit_note (0, NOTE_INSN_DELETED);
+
   /* Initialize counter.  */
-  expand_expr (build (MODIFY_EXPR, TREE_TYPE (idecl),
-                     idecl, integer_zero_node),
-              0, VOIDmode, 0);
+  expr = build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, integer_zero_node);
+  TREE_SIDE_EFFECTS (expr) = 1;
+  expand_expr (expr, const0_rtx, VOIDmode, 0);
 
   expand_start_loop_continue_elsewhere (1);
 
@@ -294,8 +332,9 @@ iterator_loop_epilogue (idecl, start_note, end_note)
     *start_note = emit_note (0, NOTE_INSN_DELETED);
   expand_loop_continue_here ();
   incr = build_binary_op (PLUS_EXPR, idecl, integer_one_node, 0);
-  expand_expr (build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, incr),
-              0, VOIDmode, 0);
+  incr = build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, incr);
+  TREE_SIDE_EFFECTS (incr) = 1;
+  expand_expr (incr, const0_rtx, VOIDmode, 0);
   test = build_binary_op (LT_EXPR, idecl, DECL_INITIAL (idecl), 0);
   expand_exit_loop_if_false (0, test);
   expand_end_loop ();
This page took 0.030563 seconds and 5 git commands to generate.