OSDN Git Service

* rtl.h (force_line_numbers, restore_line_number_status): Declare.
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Feb 1998 10:26:44 +0000 (10:26 +0000)
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Feb 1998 10:26:44 +0000 (10:26 +0000)
* emit-rtl.c (force_line_numbers, restore_line_number_status):
New functions.
* stmt.c (struct nesting): Replace seenlabel with line_number_status.
(expand_start_case): Adjust to this change.
(check_seenlabel): New function.
(pushcase, pushcase_range, expand_endcase): Use it.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@18031 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/emit-rtl.c
gcc/rtl.h
gcc/stmt.c

index 739ca53..3da217c 100644 (file)
@@ -3457,3 +3457,25 @@ init_emit_once (line_numbers)
   pic_offset_table_rtx = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
 #endif
 }
+\f
+/* Query and clear/ restore no_line_numbers.  This is used by the
+   switch / case handling in stmt.c to give proper line numbers in
+   warnings about unreachable code.  */
+
+int
+force_line_numbers ()
+{
+  int old = no_line_numbers;
+
+  no_line_numbers = 0;
+  if (old)
+    force_next_line_note ();
+  return old;
+}
+
+void
+restore_line_number_status (old_value)
+     int old_value;
+{
+  no_line_numbers = old_value;
+}
index f75ca1b..8109475 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1147,6 +1147,11 @@ extern void reorder_insns_with_line_notes        PROTO ((rtx, rtx, rtx));
 extern void emit_insn_after_with_line_notes    PROTO ((rtx, rtx, rtx));
 extern enum rtx_code classify_insn             PROTO ((rtx));
 extern rtx emit                                        PROTO ((rtx));
+/* Query and clear/ restore no_line_numbers.  This is used by the
+   switch / case handling in stmt.c to give proper line numbers in
+   warnings about unreachable code.  */
+int force_line_numbers PROTO((void));
+void restore_line_number_status PROTO((int old_value));
 
 /* In insn-emit.c */
 extern void add_clobbers               PROTO ((rtx, int));
index 42ebecb..57caad7 100644 (file)
@@ -316,8 +316,10 @@ struct nesting
          int num_ranges;
          /* Name of this kind of statement, for warnings.  */
          char *printname;
-         /* Nonzero if a case label has been seen in this case stmt.  */
-         char seenlabel;
+         /* Used to save no_line_numbers till we see the first case label.
+            We set this to -1 when we see the first case label in this
+            case statement.  */
+         int line_number_status;
        } case_stmt;
     } data;
 };
@@ -3759,7 +3761,7 @@ expand_start_case (exit_flag, expr, type, printname)
   thiscase->data.case_stmt.default_label = 0;
   thiscase->data.case_stmt.num_ranges = 0;
   thiscase->data.case_stmt.printname = printname;
-  thiscase->data.case_stmt.seenlabel = 0;
+  thiscase->data.case_stmt.line_number_status = force_line_numbers ();
   case_stack = thiscase;
   nesting_stack = thiscase;
 
@@ -3822,6 +3824,41 @@ case_index_expr_type ()
   return 0;
 }
 \f
+static void
+check_seenlabel ()
+{
+  /* If this is the first label, warn if any insns have been emitted.  */
+  if (case_stack->data.case_stmt.line_number_status >= 0)
+    {
+      rtx insn;
+
+      restore_line_number_status
+       (case_stack->data.case_stmt.line_number_status);
+      case_stack->data.case_stmt.line_number_status = -1;
+
+      for (insn = case_stack->data.case_stmt.start;
+          insn;
+          insn = NEXT_INSN (insn))
+       {
+         if (GET_CODE (insn) == CODE_LABEL)
+           break;
+         if (GET_CODE (insn) != NOTE
+             && (GET_CODE (insn) != INSN || GET_CODE (PATTERN (insn)) != USE))
+           {
+             do
+               insn = PREV_INSN (insn);
+             while (GET_CODE (insn) != NOTE || NOTE_LINE_NUMBER (insn) < 0);
+
+             warning_with_file_and_line (NOTE_SOURCE_FILE(insn),
+                                         NOTE_LINE_NUMBER(insn),
+                                         "unreachable code at beginning of %s",
+                                         case_stack->data.case_stmt.printname);
+             break;
+           }
+       }
+    }
+}
+
 /* Accumulate one case or default label inside a case or switch statement.
    VALUE is the value of the case (a null pointer, for a default label).
    The function CONVERTER, when applied to arguments T and V,
@@ -3858,6 +3895,8 @@ pushcase (value, converter, label, duplicate)
   index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr);
   nominal_type = case_stack->data.case_stmt.nominal_type;
 
+  check_seenlabel ();
+
   /* If the index is erroneous, avoid more problems: pretend to succeed.  */
   if (index_type == error_mark_node)
     return 0;
@@ -3866,27 +3905,6 @@ pushcase (value, converter, label, duplicate)
   if (value != 0)
     value = (*converter) (nominal_type, value);
 
-  /* If this is the first label, warn if any insns have been emitted.  */
-  if (case_stack->data.case_stmt.seenlabel == 0)
-    {
-      rtx insn;
-      for (insn = case_stack->data.case_stmt.start;
-          insn;
-          insn = NEXT_INSN (insn))
-       {
-         if (GET_CODE (insn) == CODE_LABEL)
-           break;
-         if (GET_CODE (insn) != NOTE
-             && (GET_CODE (insn) != INSN || GET_CODE (PATTERN (insn)) != USE))
-           {
-             warning ("unreachable code at beginning of %s",
-                      case_stack->data.case_stmt.printname);
-             break;
-           }
-       }
-    }
-  case_stack->data.case_stmt.seenlabel = 1;
-
   /* Fail if this value is out of range for the actual type of the index
      (which may be narrower than NOMINAL_TYPE).  */
   if (value != 0 && ! int_fits_type_p (value, index_type))
@@ -3943,26 +3961,7 @@ pushcase_range (value1, value2, converter, label, duplicate)
   if (index_type == error_mark_node)
     return 0;
 
-  /* If this is the first label, warn if any insns have been emitted.  */
-  if (case_stack->data.case_stmt.seenlabel == 0)
-    {
-      rtx insn;
-      for (insn = case_stack->data.case_stmt.start;
-          insn;
-          insn = NEXT_INSN (insn))
-       {
-         if (GET_CODE (insn) == CODE_LABEL)
-           break;
-         if (GET_CODE (insn) != NOTE
-             && (GET_CODE (insn) != INSN || GET_CODE (PATTERN (insn)) != USE))
-           {
-             warning ("unreachable code at beginning of %s",
-                      case_stack->data.case_stmt.printname);
-             break;
-           }
-       }
-    }
-  case_stack->data.case_stmt.seenlabel = 1;
+  check_seenlabel ();
 
   /* Convert VALUEs to type in which the comparisons are nominally done
      and replace any unspecified value with the corresponding bound.  */
@@ -4613,6 +4612,8 @@ expand_end_case (orig_index)
 
   do_pending_stack_adjust ();
 
+  check_seenlabel ();
+
   /* An ERROR_MARK occurs for various reasons including invalid data type.  */
   if (index_type != error_mark_node)
     {
@@ -4625,22 +4626,6 @@ expand_end_case (orig_index)
          && TREE_CODE (index_expr) != INTEGER_CST)
        check_for_full_enumeration_handling (TREE_TYPE (orig_index));
 
-      /* If this is the first label, warn if any insns have been emitted.  */
-      if (thiscase->data.case_stmt.seenlabel == 0)
-       {
-         rtx insn;
-         for (insn = get_last_insn ();
-              insn != case_stack->data.case_stmt.start;
-              insn = PREV_INSN (insn))
-           if (GET_CODE (insn) != NOTE
-               && (GET_CODE (insn) != INSN || GET_CODE (PATTERN (insn))!= USE))
-             {
-               warning ("unreachable code at beginning of %s",
-                        case_stack->data.case_stmt.printname);
-               break;
-             }
-       }
-
       /* If we don't have a default-label, create one here,
         after the body of the switch.  */
       if (thiscase->data.case_stmt.default_label == 0)