cse.c (cse_insn): Call never_reached_warning when a jump is changed to be unconditional.
authorGeoff Keating <geoffk@cygnus.com>
Wed, 18 Aug 1999 10:43:26 +0000 (10:43 +0000)
committerGeoffrey Keating <geoffk@gcc.gnu.org>
Wed, 18 Aug 1999 10:43:26 +0000 (10:43 +0000)
* 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.

Also modify documentation to suit.

From-SVN: r28747

gcc/ChangeLog
gcc/cse.c
gcc/flags.h
gcc/flow.c
gcc/gcc.texi
gcc/invoke.texi
gcc/jump.c
gcc/rtl.h
gcc/toplev.c

index 63fe40b5195c897c062eee00e0e59c2d6257dae4..0cdd854f91e6a5b11439245b7f14f8c8db3b5186 100644 (file)
@@ -1,3 +1,19 @@
+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.
index 9eca723e442c6f0bebb9e5da867fd9f84028e6e5..f279cd152cc09434fd396cc54e9b1a206648d845 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -7419,6 +7419,8 @@ cse_insn (insn, libcall_insn)
             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
index 6f2f93fda75a376dfaa05bca1804d64238129b9d..9871fb88b78aec3f207d5150a20be75a8aed2df7 100644 (file)
@@ -79,6 +79,10 @@ extern int extra_warnings;
 
 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;
index 1154188684d04ff5ada792a19f883db861146799..c38d0b3638bd9bca3c8531d4195ee2441057a15d 100644 (file)
@@ -1682,6 +1682,8 @@ delete_block (b)
 
   insn = b->head;
   
+  never_reached_warning (insn);
+
   if (GET_CODE (insn) == CODE_LABEL)
     {
       rtx x, *prev = &exception_handler_labels;
index 7f8fdfb2bbdd9102e9699b06589cab5bef314107..3494de492a296e224b07693320a50af5c7547543 100644 (file)
@@ -1919,13 +1919,6 @@ Warning about assigning a signed value to an unsigned variable.
 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.
 
index b707cdb4fd6e185c272bcea886403a340af859c8..7dadd3f8db9a2561343e7a14f26e5cc49d4f94e6 100644 (file)
@@ -132,8 +132,8 @@ in the following sections.
 -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
@@ -1766,6 +1766,27 @@ cases where multiple declaration is valid and changes nothing.
 @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.
index 9ff6bc99ee9d60463c8bcfcf5729ec5621c1cf81..6e63322b611e8e964d0da99c19db3bbb9ebe96e3 100644 (file)
@@ -2149,6 +2149,9 @@ delete_barrier_successors (f)
       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
@@ -4245,6 +4248,52 @@ delete_for_peephole (from, to)
      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.  */
 
index 705da5e2cdd8f5d929712a45226620dc008137c2..4f01212ff03ca2cd77c1dc8a50bf15baa67791de 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1292,6 +1292,7 @@ extern int invert_exp                     PROTO ((rtx, rtx));
 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
index 1f1c3f533953c4962b18377861823b4a6b79bb19..5a727c65b94ea1f0d891a31097c549a52aaf5ddc 100644 (file)
@@ -1195,6 +1195,10 @@ int warnings_are_errors = 0;
 
 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;
@@ -1253,6 +1257,8 @@ lang_independent_options W_options[] =
    "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,
@@ -2944,7 +2950,8 @@ compile_file (name)
   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 ();