This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] high priority PR c/8828
- From: Steven Bosscher <s dot bosscher at student dot tudelft dot nl>
- To: gcc-patches at gcc dot gnu dot org
- Date: 16 Feb 2003 12:44:52 +0100
- Subject: [PATCH] high priority PR c/8828
With -Wunreachable-code, we incorrectly flag case blocks as unreachable
for testcases such as this one:
/* { dg-do compile } */
/* { dg-options "-Wunreachable-code" } */
void foo (int i)
{
switch (i)
{
case 0: break; /* { dg-bogus "will never be executed" } */
case 1: break;
}
}
BARRIER insns are ignored in jump.c:never_reached_warning(), so the loop
that looks for unreachable insns falls through to the next basic block
(for "case 1") and thinks that the jump_insn for "break;" is an
unreachable insn.
With the attached patch, the loop terminates when it hits a barrier.
This would fix high priority PR c/8828 for the 3.2 and 3.3 branches and
on the mainline. The snippet above should be added to the test suite
(as testsuite/gcc.dg/Wunreachable-3.c ?)
This still leaves PR c/5897 for -Wunreachable-code...
Bootstrapped C and made sure all test cases that are compiled with
-Wunreachable-code still pass. This patch only affects compilations with
-Wunreachable-code, so bootstrap is not affected.
Greetz
Steven
2003-02-16 Steven Bosscher <s.bosscher@student.tudelft.nl>
PR c/8828
* jump.c (never_reached_warning): Don't fall through
BARRRIER insns. Update comments to reflect what the
function really does.
Index: gcc/jump.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/jump.c,v
retrieving revision 1.216
diff -c -3 -p -r1.216 jump.c
*** gcc/jump.c 10 Jan 2003 13:44:28 -0000 1.216
--- gcc/jump.c 16 Feb 2003 11:17:35 -0000
*************** delete_for_peephole (from, to)
*** 1893,1906 ****
is also an unconditional jump in that case. */
}
! /* 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, finish)
--- 1893,1906 ----
is also an unconditional jump in that case. */
}
! /* We have determined that AVOIDED_INSN is never reached, and are
! about to delete it. If the insn chain between AVOIDED_INSN and
! FINISH contains more than one line from the current function, and
! contains at least one operation, print a warning if the user asked
! for it. If FINISH is NULL, look between AVOIDED_INSN and a LABEL.
! CSE and inlining can duplicate insns, so it's possible to get
! spurious warnings from this. */
void
never_reached_warning (avoided_insn, finish)
*************** never_reached_warning (avoided_insn, fin
*** 1910,1924 ****
rtx a_line_note = NULL;
int two_avoided_lines = 0, contains_insn = 0, reached_end = 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 (finish == NULL && GET_CODE (insn) == CODE_LABEL)
break;
if (GET_CODE (insn) == NOTE /* A line number note? */
--- 1910,1925 ----
rtx a_line_note = NULL;
int two_avoided_lines = 0, contains_insn = 0, reached_end = 0;
! if (!warn_notreached)
return;
! /* Scan forwards, looking at LINE_NUMBER notes, until we hit a LABEL
! in case FINISH is NULL, otherwise until we run out of insns. */
for (insn = avoided_insn; insn != NULL; insn = NEXT_INSN (insn))
{
! if ((finish == NULL && GET_CODE (insn) == CODE_LABEL)
! || GET_CODE (insn) == BARRIER)
break;
if (GET_CODE (insn) == NOTE /* A line number note? */