From 3404891cd4ca72c8b379dd1d1b66598afb1a5a8c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 26 Apr 2014 00:54:08 +0300 Subject: [PATCH] unreachable: don't print a warning if we jump to the middle of a loop There is a some code like this: goto first; for (;;) { XXX_frob(); first: more_frob(); } Smatch sees the start of the for loop as unreachable. There isn't really a good way to fix this so I just ignore any unreachable loops if they are preceded by a goto. It's not beautiful, but it's better to not print false positives. Signed-off-by: Dan Carpenter --- check_unreachable.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/check_unreachable.c b/check_unreachable.c index ceeaa999..9beab208 100644 --- a/check_unreachable.c +++ b/check_unreachable.c @@ -100,6 +100,31 @@ static int prev_line_was_endif(struct statement *stmt) return 0; } +static int we_jumped_into_the_middle_of_a_loop(struct statement *stmt) +{ + struct statement *prev; + + /* + * Smatch doesn't handle loops correctly and this is a hack. What we + * do is that if the first unreachable statement is a loop and the + * previous statement was a goto then it's probably code like this: + * goto first; + * for (;;) { + * frob(); + * first: + * more_frob(); + * } + * Every statement is reachable but only on the second iteration. + */ + + if (stmt->type != STMT_ITERATOR) + return 0; + prev = get_prev_statement(); + if (prev && prev->type == STMT_GOTO) + return 1; + return 0; +} + static void unreachable_stmt(struct statement *stmt) { @@ -116,6 +141,8 @@ static void unreachable_stmt(struct statement *stmt) print_unreached = 0; if (prev_line_was_endif(stmt)) print_unreached = 0; + if (we_jumped_into_the_middle_of_a_loop(stmt)) + print_unreached = 0; if (!print_unreached) return; -- 2.11.4.GIT