stmt.c (expand_start_null_loop): New.
authorRichard Henderson <rth@redhat.com>
Wed, 1 Nov 2000 10:28:32 +0000 (02:28 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 1 Nov 2000 10:28:32 +0000 (02:28 -0800)
        * stmt.c (expand_start_null_loop): New.
        (expand_end_null_loop): New.
        * c-semantics.c (genrtl_do_stmt): Use them.
        * tree.h: Declare them.

From-SVN: r37186

gcc/ChangeLog
gcc/c-semantics.c
gcc/stmt.c
gcc/tree.h

index a29f68c5804c960b409133f73ca24a87531bbec7..c8b0dff26d3b94e253e2d7e9c8cd2a2dc7989e21 100644 (file)
@@ -1,3 +1,10 @@
+2000-11-01  Richard Henderson  <rth@redhat.com>
+
+       * stmt.c (expand_start_null_loop): New.
+       (expand_end_null_loop): New.    
+       * c-semantics.c (genrtl_do_stmt): Use them.
+       * tree.h: Declare them.
+
 2000-11-01  Richard Henderson  <rth@redhat.com>
 
        * cppmain.c (scan_buffer): Don't avoid paste for assembly.
index 625f7261a92de9c5bf181e172a09feadca25f09f..f3210633ad9229278bae19ea3a80b5c5e6aa53e6 100644 (file)
@@ -487,7 +487,11 @@ genrtl_do_stmt (t)
      avoids cluttering the rtl with dummy loop notes, which can affect
      alignment of adjacent labels.  */
   if (integer_zerop (cond))
-    expand_stmt (DO_BODY (t));
+    {
+      expand_start_null_loop ();
+      expand_stmt (DO_BODY (t));
+      expand_end_null_loop ();
+    }
   else
     {
       emit_nop ();
index 927748178247df9a8a435843b3c82da3c4d06fd7..fd0647aef18cc667a278b6a3923c01e8d139411e 100644 (file)
@@ -2294,6 +2294,30 @@ expand_start_loop_continue_elsewhere (exit_flag)
   return thisloop;
 }
 
+/* Begin a null, aka do { } while (0) "loop".  But since the contents
+   of said loop can still contain a break, we must frob the loop nest.  */
+
+struct nesting *
+expand_start_null_loop ()
+{
+  register struct nesting *thisloop = ALLOC_NESTING ();
+
+  /* Make an entry on loop_stack for the loop we are entering.  */
+
+  thisloop->next = loop_stack;
+  thisloop->all = nesting_stack;
+  thisloop->depth = ++nesting_depth;
+  thisloop->data.loop.start_label = emit_note (NULL, NOTE_INSN_DELETED);
+  thisloop->data.loop.end_label = gen_label_rtx ();
+  thisloop->data.loop.alt_end_label = NULL_RTX;
+  thisloop->data.loop.continue_label = NULL_RTX;
+  thisloop->exit_label = thisloop->data.loop.end_label;
+  loop_stack = thisloop;
+  nesting_stack = thisloop;
+
+  return thisloop;
+}
+
 /* Specify the continuation point for a loop started with
    expand_start_loop_continue_elsewhere.
    Use this at the point in the code to which a continue statement
@@ -2620,6 +2644,19 @@ expand_end_loop ()
   last_expr_type = 0;
 }
 
+/* Finish a null loop, aka do { } while (0).  */
+
+void
+expand_end_null_loop ()
+{
+  do_pending_stack_adjust ();
+  emit_label (loop_stack->data.loop.end_label);
+
+  POPSTACK (loop_stack);
+
+  last_expr_type = 0;
+}
+
 /* Generate a jump to the current loop's continue-point.
    This is usually the top of the loop, but may be specified
    explicitly elsewhere.  If not currently inside a loop,
index 17f09a13acf37094320c41483d88b946bacadb87..2c8e1fa2cd489e47b898a36df8fa5833654d0ef8 100644 (file)
@@ -2460,8 +2460,10 @@ extern void expand_start_else                    PARAMS ((void));
 extern void expand_start_elseif                        PARAMS ((tree));
 extern struct nesting *expand_start_loop       PARAMS ((int));
 extern struct nesting *expand_start_loop_continue_elsewhere    PARAMS ((int));
+extern struct nesting *expand_start_null_loop  PARAMS ((void));
 extern void expand_loop_continue_here          PARAMS ((void));
 extern void expand_end_loop                    PARAMS ((void));
+extern void expand_end_null_loop               PARAMS ((void));
 extern int expand_continue_loop                        PARAMS ((struct nesting *));
 extern int expand_exit_loop                    PARAMS ((struct nesting *));
 extern int expand_exit_loop_if_false           PARAMS ((struct nesting *,