+Sat Aug 14 00:54:57 1999 Geoffrey Keating <geoffk@cygnus.com>
+
+ * cse.c (cse_insn): Call never_reached_warning when a jump is
+ changed to be unconditional.
+ * flags.h: Declare warn_notreached.
+ * flow.c (delete_block): Call never_reached_warning when
+ a block is deleted.
+ * jump.c (delete_barrier_successors): Call never_reached_warning
+ when we delete everything after a BARRIER.
+ (never_reached_warning): New function.
+ * rtl.h: Declare never_reached_warning.
+ * toplev.c (warn_notreached): New variable.
+ (lang_independent_options): Set warn_notreached
+ when -Wunreachable-code.
+ (compile_file): We need line numbers for -Wunreachable-code.
+
Tue Aug 17 22:06:11 1999 Jan Hubicka <hubicka@freesoft.cz>
* haifa-sched.c (insn_unit): Fix typo on out of range test.
not delete NOTEs except for NOTE_INSN_DELETED since later
phases assume these notes are retained. */
+ never_reached_warning (insn);
+
p = insn;
while (NEXT_INSN (p) != 0
extern int warn_unused;
+/* Nonzero to warn about code which is never reached. */
+
+extern int warn_notreached;
+
/* Nonzero means warn if inline function is too large. */
extern int warn_inline;
insn = b->head;
+ never_reached_warning (insn);
+
if (GET_CODE (insn) == CODE_LABEL)
{
rtx x, *prev = &exception_handler_labels;
Such assignments must be very common; warning about them would cause
more annoyance than good.
-@item
-Warning about unreachable code.
-
-It's very common to have unreachable code in machine-generated
-programs. For example, this happens normally in some files of GNU C
-itself.
-
@item
Warning when a non-void function value is ignored.
-Wparentheses -Wpointer-arith -Wredundant-decls
-Wreturn-type -Wshadow -Wsign-compare -Wstrict-prototypes
-Wswitch -Wtraditional
--Wtrigraphs -Wundef -Wuninitialized -Wunused -Wwrite-strings
--Wunknown-pragmas
+-Wtrigraphs -Wundef -Wuninitialized -Wunknown-pragmas -Wunreachable-code
+-Wunused -Wwrite-strings
@end smallexample
@item Debugging Options
@item -Wnested-externs
Warn if an @code{extern} declaration is encountered within an function.
+@item -Wunreachable-code
+Warn if the compiler detects that code will never be executed.
+
+This option is intended to warn when the compiler detects that at
+least a whole line of source code will never be executed, because
+some condition is never satisfied or because it is after a
+procedure that never returns.
+
+It is possible for this option to produce a warning even though there
+are circumstances under which part of the affected line can be executed,
+so care should be taken when removing apparently-unreachable code.
+
+For instance, when a function is inlined, a warning may mean that the
+line is unreachable in only one inlined copy of the function.
+
+This option is not made part of @samp{-Wall} because in a debugging
+version of a program there is often substantial code which checks
+correct functioning of the program and is, hopefully, unreachable
+because the program does work. Another common use of unreachable
+code is to provide behaviour which is selectable at compile-time.
+
@item -Winline
Warn if a function can not be inlined, and either it was declared as inline,
or else the @samp{-finline-functions} option was given.
if (GET_CODE (insn) == BARRIER)
{
insn = NEXT_INSN (insn);
+
+ never_reached_warning (insn);
+
while (insn != 0 && GET_CODE (insn) != CODE_LABEL)
{
if (GET_CODE (insn) == NOTE
is also an unconditional jump in that case. */
}
\f
+/* We have determined that INSN is never reached, and are about to
+ delete it. Print a warning if the user asked for one.
+
+ To try to make this warning more useful, this should only be called
+ once per basic block not reached, and it only warns when the basic
+ block contains more than one line from the current function, and
+ contains at least one operation. CSE and inlining can duplicate insns,
+ so it's possible to get spurious warnings from this. */
+
+void
+never_reached_warning (avoided_insn)
+ rtx avoided_insn;
+{
+ rtx insn;
+ rtx a_line_note = NULL;
+ int two_avoided_lines = 0;
+ int contains_insn = 0;
+
+ if (! warn_notreached)
+ return;
+
+ /* Scan forwards, looking at LINE_NUMBER notes, until
+ we hit a LABEL or we run out of insns. */
+
+ for (insn = avoided_insn; insn != NULL; insn = NEXT_INSN (insn))
+ {
+ if (GET_CODE (insn) == CODE_LABEL)
+ break;
+ else if (GET_CODE (insn) == NOTE /* A line number note? */
+ && NOTE_LINE_NUMBER (insn) >= 0)
+ {
+ if (a_line_note == NULL)
+ a_line_note = insn;
+ else
+ two_avoided_lines |= (NOTE_LINE_NUMBER (a_line_note)
+ != NOTE_LINE_NUMBER (insn));
+ }
+ else if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ contains_insn = 1;
+ }
+ if (two_avoided_lines && contains_insn)
+ warning_with_file_and_line (NOTE_SOURCE_FILE (a_line_note),
+ NOTE_LINE_NUMBER (a_line_note),
+ "will never be executed");
+}
+\f
/* Invert the condition of the jump JUMP, and make it jump
to label NLABEL instead of where it jumps now. */
extern int can_reverse_comparison_p PROTO ((rtx, rtx));
extern void delete_for_peephole PROTO ((rtx, rtx));
extern int condjump_in_parallel_p PROTO ((rtx));
+extern void never_reached_warning PROTO ((rtx));
/* Flags for jump_optimize() */
#define JUMP_CROSS_JUMP 1
int warn_unused;
+/* Nonzero to warn about code which is never reached. */
+
+int warn_notreached;
+
/* Nonzero to warn about variables used before they are initialized. */
int warn_uninitialized;
"Warn about returning structures, unions or arrays" },
{"cast-align", &warn_cast_align, 1,
"Warn about pointer casts which increase alignment" },
+ {"unreachable-code", &warn_notreached, 1,
+ "Warn about code that will never be executed" },
{"uninitialized", &warn_uninitialized, 1,
"Warn about unitialized automatic variables"},
{"inline", &warn_inline, 1,
init_rtl ();
init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
|| debug_info_level == DINFO_LEVEL_VERBOSE
- || flag_test_coverage);
+ || flag_test_coverage
+ || warn_notreached);
init_regs ();
init_decl_processing ();
init_optabs ();