aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJoern Rennecke <amylaar@gcc.gnu.org>1998-02-17 10:26:44 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>1998-02-17 10:26:44 +0000
commita11759a38c42fd52cc46ebfeeec8f5bc98e9f1ed (patch)
tree7d919ed17c492831b64a4b11a496099612b303e7 /gcc
parent93f83bd58d196e279df4669628b54dd46b89f036 (diff)
downloadgcc-a11759a38c42fd52cc46ebfeeec8f5bc98e9f1ed.zip
gcc-a11759a38c42fd52cc46ebfeeec8f5bc98e9f1ed.tar.gz
gcc-a11759a38c42fd52cc46ebfeeec8f5bc98e9f1ed.tar.bz2
rtl.h (force_line_numbers, [...]): Declare.
* rtl.h (force_line_numbers, restore_line_number_status): Declare. * 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. From-SVN: r18031
Diffstat (limited to 'gcc')
-rw-r--r--gcc/emit-rtl.c22
-rw-r--r--gcc/rtl.h5
-rw-r--r--gcc/stmt.c105
3 files changed, 72 insertions, 60 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 739ca53..3da217c 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -3457,3 +3457,25 @@ init_emit_once (line_numbers)
pic_offset_table_rtx = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
#endif
}
+
+/* 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;
+}
diff --git a/gcc/rtl.h b/gcc/rtl.h
index f75ca1b..8109475 100644
--- 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));
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 42ebecb..57caad7 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -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;
}
+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)