Module Name: src
Committed By: rillig
Date: Sun Mar 21 14:36:59 UTC 2021
Modified Files:
src/tests/usr.bin/xlint/lint1: d_c99_bool_strict.c
d_c99_bool_strict.exp msg_193.c msg_193.exp msg_217.c msg_217.exp
msg_333.c msg_333.exp
src/usr.bin/xlint/lint1: func.c lint1.h
Log Message:
lint: fix reachability computation in if statements
Previously, only loop statements were considered for reachability. This
ignored the possibility of an early return in an if statement, or
unreachable branches.
To generate a diff of this commit:
cvs rdiff -u -r1.25 -r1.26 src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.c
cvs rdiff -u -r1.21 -r1.22 \
src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.exp
cvs rdiff -u -r1.3 -r1.4 src/tests/usr.bin/xlint/lint1/msg_193.c \
src/tests/usr.bin/xlint/lint1/msg_193.exp
cvs rdiff -u -r1.7 -r1.8 src/tests/usr.bin/xlint/lint1/msg_217.c
cvs rdiff -u -r1.6 -r1.7 src/tests/usr.bin/xlint/lint1/msg_217.exp
cvs rdiff -u -r1.2 -r1.3 src/tests/usr.bin/xlint/lint1/msg_333.c \
src/tests/usr.bin/xlint/lint1/msg_333.exp
cvs rdiff -u -r1.87 -r1.88 src/usr.bin/xlint/lint1/func.c
cvs rdiff -u -r1.85 -r1.86 src/usr.bin/xlint/lint1/lint1.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.c
diff -u src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.c:1.25 src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.c:1.26
--- src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.c:1.25 Sun Mar 21 14:12:46 2021
+++ src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.c Sun Mar 21 14:36:59 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: d_c99_bool_strict.c,v 1.25 2021/03/21 14:12:46 rillig Exp $ */
+/* $NetBSD: d_c99_bool_strict.c,v 1.26 2021/03/21 14:36:59 rillig Exp $ */
# 3 "d_c99_bool_strict.c"
/*
@@ -365,7 +365,7 @@ void
strict_bool_controlling_expression(bool b, int i, double d, const void *p)
{
if (__lint_false) /* expect: 161 */
- do_nothing();
+ do_nothing(); /* expect: statement not reached */
if (__lint_true) /* expect: 161 */
do_nothing();
Index: src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.exp
diff -u src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.exp:1.21 src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.exp:1.22
--- src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.exp:1.21 Sun Mar 21 14:12:46 2021
+++ src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.exp Sun Mar 21 14:36:59 2021
@@ -55,6 +55,7 @@ d_c99_bool_strict.c(354): operands of '=
d_c99_bool_strict.c(355): operands of '=' have incompatible types (pointer != _Bool) [107]
d_c99_bool_strict.c(345): warning: argument b unused in function strict_bool_conversion_from_bool_to_scalar [231]
d_c99_bool_strict.c(367): warning: constant in conditional context [161]
+d_c99_bool_strict.c(368): warning: statement not reached [193]
d_c99_bool_strict.c(370): warning: constant in conditional context [161]
d_c99_bool_strict.c(376): controlling expression must be bool, not 'int' [333]
d_c99_bool_strict.c(379): controlling expression must be bool, not 'int' [333]
Index: src/tests/usr.bin/xlint/lint1/msg_193.c
diff -u src/tests/usr.bin/xlint/lint1/msg_193.c:1.3 src/tests/usr.bin/xlint/lint1/msg_193.c:1.4
--- src/tests/usr.bin/xlint/lint1/msg_193.c:1.3 Sun Mar 21 14:09:40 2021
+++ src/tests/usr.bin/xlint/lint1/msg_193.c Sun Mar 21 14:36:59 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: msg_193.c,v 1.3 2021/03/21 14:09:40 rillig Exp $ */
+/* $NetBSD: msg_193.c,v 1.4 2021/03/21 14:36:59 rillig Exp $ */
# 3 "msg_193.c"
// Test for message: statement not reached [193]
@@ -52,7 +52,7 @@ test_if_statement(void)
reachable();
reachable();
if (0)
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
reachable();
}
@@ -71,12 +71,12 @@ test_if_compound_statement(void)
}
if (0) {
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
}
if (0) {
{
{
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
}
}
}
@@ -90,7 +90,7 @@ test_if_without_else(void)
reachable();
if (0)
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
reachable();
}
@@ -100,11 +100,11 @@ test_if_with_else(void)
if (1)
reachable();
else
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
reachable();
if (0)
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
else
reachable();
reachable();
@@ -115,22 +115,22 @@ test_if_else_if_else(void)
{
if (1)
reachable();
- else if (1)
- unreachable(); /* TODO: expect: 193 */
+ else if (1) /* expect: 193 */
+ unreachable();
else
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
if (0)
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
else if (1)
reachable();
else
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
if (0)
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
else if (0)
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
else
reachable();
}
@@ -149,7 +149,7 @@ test_if_else_return(void)
if (1)
reachable();
else
- return;
+ return; /* expect: 193 */
reachable();
}
@@ -194,7 +194,7 @@ test_for_if_break(void)
for (;;) {
reachable();
if (0) {
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
break;
unreachable(); /* expect: 193 */
}
@@ -225,7 +225,7 @@ test_for_if_continue(void)
for (;;) {
reachable();
if (0) {
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
continue;
unreachable(); /* expect: 193 */
}
@@ -256,7 +256,7 @@ test_for_if_return(void)
for (;;) {
reachable();
if (0) {
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
return;
unreachable(); /* expect: 193 */
}
@@ -303,7 +303,7 @@ test_while_if_break(void)
while (1) {
reachable();
if (0) {
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
break;
unreachable(); /* expect: 193 */
}
@@ -334,7 +334,7 @@ test_while_if_continue(void)
while (1) {
reachable();
if (0) {
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
continue;
unreachable(); /* expect: 193 */
}
@@ -365,7 +365,7 @@ test_while_if_return(void)
while (1) {
reachable();
if (0) {
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
return;
unreachable(); /* expect: 193 */
}
@@ -414,7 +414,7 @@ test_do_while_if_break(void)
do {
reachable();
if (0) {
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
break;
unreachable(); /* expect: 193 */
}
@@ -445,7 +445,7 @@ test_do_while_if_continue(void)
do {
reachable();
if (0) {
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
continue;
unreachable(); /* expect: 193 */
}
@@ -476,7 +476,7 @@ test_do_while_if_return(void)
do {
reachable();
if (0) {
- unreachable(); /* TODO: expect: 193 */
+ unreachable(); /* expect: 193 */
return;
unreachable(); /* expect: 193 */
}
Index: src/tests/usr.bin/xlint/lint1/msg_193.exp
diff -u src/tests/usr.bin/xlint/lint1/msg_193.exp:1.3 src/tests/usr.bin/xlint/lint1/msg_193.exp:1.4
--- src/tests/usr.bin/xlint/lint1/msg_193.exp:1.3 Sun Mar 21 14:09:40 2021
+++ src/tests/usr.bin/xlint/lint1/msg_193.exp Sun Mar 21 14:36:59 2021
@@ -1,43 +1,65 @@
+msg_193.c(55): warning: statement not reached [193]
+msg_193.c(74): warning: statement not reached [193]
+msg_193.c(79): warning: statement not reached [193]
+msg_193.c(93): warning: statement not reached [193]
+msg_193.c(103): warning: statement not reached [193]
+msg_193.c(107): warning: statement not reached [193]
+msg_193.c(118): warning: statement not reached [193]
+msg_193.c(121): warning: statement not reached [193]
+msg_193.c(124): warning: statement not reached [193]
+msg_193.c(128): warning: statement not reached [193]
+msg_193.c(131): warning: statement not reached [193]
+msg_193.c(133): warning: statement not reached [193]
+msg_193.c(152): warning: statement not reached [193]
msg_193.c(161): warning: statement not reached [193]
msg_193.c(169): warning: statement not reached [193]
msg_193.c(186): warning: statement not reached [193]
+msg_193.c(197): warning: statement not reached [193]
msg_193.c(199): warning: statement not reached [193]
msg_193.c(204): warning: statement not reached [193]
msg_193.c(217): warning: statement not reached [193]
msg_193.c(219): warning: statement not reached [193]
+msg_193.c(228): warning: statement not reached [193]
msg_193.c(230): warning: statement not reached [193]
msg_193.c(235): warning: statement not reached [193]
msg_193.c(239): warning: statement not reached [193]
msg_193.c(248): warning: statement not reached [193]
msg_193.c(250): warning: statement not reached [193]
+msg_193.c(259): warning: statement not reached [193]
msg_193.c(261): warning: statement not reached [193]
msg_193.c(266): warning: statement not reached [193]
msg_193.c(270): warning: statement not reached [193]
msg_193.c(278): warning: statement not reached [193]
msg_193.c(295): warning: statement not reached [193]
+msg_193.c(306): warning: statement not reached [193]
msg_193.c(308): warning: statement not reached [193]
msg_193.c(313): warning: statement not reached [193]
msg_193.c(326): warning: statement not reached [193]
msg_193.c(328): warning: statement not reached [193]
+msg_193.c(337): warning: statement not reached [193]
msg_193.c(339): warning: statement not reached [193]
msg_193.c(344): warning: statement not reached [193]
msg_193.c(348): warning: statement not reached [193]
msg_193.c(357): warning: statement not reached [193]
msg_193.c(359): warning: statement not reached [193]
+msg_193.c(368): warning: statement not reached [193]
msg_193.c(370): warning: statement not reached [193]
msg_193.c(375): warning: statement not reached [193]
msg_193.c(379): warning: statement not reached [193]
msg_193.c(388): warning: statement not reached [193]
msg_193.c(406): warning: statement not reached [193]
+msg_193.c(417): warning: statement not reached [193]
msg_193.c(419): warning: statement not reached [193]
msg_193.c(424): warning: statement not reached [193]
msg_193.c(437): warning: statement not reached [193]
msg_193.c(439): warning: statement not reached [193]
+msg_193.c(448): warning: statement not reached [193]
msg_193.c(450): warning: statement not reached [193]
msg_193.c(455): warning: statement not reached [193]
msg_193.c(459): warning: statement not reached [193]
msg_193.c(468): warning: statement not reached [193]
msg_193.c(470): warning: statement not reached [193]
+msg_193.c(479): warning: statement not reached [193]
msg_193.c(481): warning: statement not reached [193]
msg_193.c(486): warning: statement not reached [193]
msg_193.c(490): warning: statement not reached [193]
Index: src/tests/usr.bin/xlint/lint1/msg_217.c
diff -u src/tests/usr.bin/xlint/lint1/msg_217.c:1.7 src/tests/usr.bin/xlint/lint1/msg_217.c:1.8
--- src/tests/usr.bin/xlint/lint1/msg_217.c:1.7 Sun Mar 21 12:19:36 2021
+++ src/tests/usr.bin/xlint/lint1/msg_217.c Sun Mar 21 14:36:59 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: msg_217.c,v 1.7 2021/03/21 12:19:36 rillig Exp $ */
+/* $NetBSD: msg_217.c,v 1.8 2021/03/21 14:36:59 rillig Exp $ */
# 3 "msg_217.c"
// Test for message: function %s falls off bottom without returning value [217]
@@ -62,7 +62,7 @@ unreachable_continue_falls_through(void)
{
for (;;) {
if (0)
- continue;
+ continue; /* expect: statement not reached */
break;
}
} /* expect: 217 */
Index: src/tests/usr.bin/xlint/lint1/msg_217.exp
diff -u src/tests/usr.bin/xlint/lint1/msg_217.exp:1.6 src/tests/usr.bin/xlint/lint1/msg_217.exp:1.7
--- src/tests/usr.bin/xlint/lint1/msg_217.exp:1.6 Sun Mar 21 12:19:36 2021
+++ src/tests/usr.bin/xlint/lint1/msg_217.exp Sun Mar 21 14:36:59 2021
@@ -1,3 +1,4 @@
msg_217.c(11): warning: function random falls off bottom without returning value [217]
msg_217.c(58): warning: function reachable_continue_leads_to_endless_loop falls off bottom without returning value [217]
+msg_217.c(65): warning: statement not reached [193]
msg_217.c(68): warning: function unreachable_continue_falls_through falls off bottom without returning value [217]
Index: src/tests/usr.bin/xlint/lint1/msg_333.c
diff -u src/tests/usr.bin/xlint/lint1/msg_333.c:1.2 src/tests/usr.bin/xlint/lint1/msg_333.c:1.3
--- src/tests/usr.bin/xlint/lint1/msg_333.c:1.2 Sat Jan 16 16:03:47 2021
+++ src/tests/usr.bin/xlint/lint1/msg_333.c Sun Mar 21 14:36:59 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: msg_333.c,v 1.2 2021/01/16 16:03:47 rillig Exp $ */
+/* $NetBSD: msg_333.c,v 1.3 2021/03/21 14:36:59 rillig Exp $ */
# 3 "msg_333.c"
// Test for message: controlling expression must be bool, not '%s' [333]
@@ -19,7 +19,7 @@ example(bool b, int i, const char *p)
if (p) /* expect: 333 */
return "pointer";
if (__lint_false)
- return "bool constant";
+ return "bool constant"; /* expect: statement not reached */
if (0) /* expect: 333 */
return "integer constant";
return p + i;
Index: src/tests/usr.bin/xlint/lint1/msg_333.exp
diff -u src/tests/usr.bin/xlint/lint1/msg_333.exp:1.2 src/tests/usr.bin/xlint/lint1/msg_333.exp:1.3
--- src/tests/usr.bin/xlint/lint1/msg_333.exp:1.2 Sat Jan 16 16:03:47 2021
+++ src/tests/usr.bin/xlint/lint1/msg_333.exp Sun Mar 21 14:36:59 2021
@@ -1,3 +1,4 @@
msg_333.c(17): controlling expression must be bool, not 'int' [333]
msg_333.c(19): controlling expression must be bool, not 'pointer' [333]
+msg_333.c(22): warning: statement not reached [193]
msg_333.c(23): controlling expression must be bool, not 'int' [333]
Index: src/usr.bin/xlint/lint1/func.c
diff -u src/usr.bin/xlint/lint1/func.c:1.87 src/usr.bin/xlint/lint1/func.c:1.88
--- src/usr.bin/xlint/lint1/func.c:1.87 Sun Mar 21 13:03:42 2021
+++ src/usr.bin/xlint/lint1/func.c Sun Mar 21 14:36:59 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: func.c,v 1.87 2021/03/21 13:03:42 rillig Exp $ */
+/* $NetBSD: func.c,v 1.88 2021/03/21 14:36:59 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: func.c,v 1.87 2021/03/21 13:03:42 rillig Exp $");
+__RCSID("$NetBSD: func.c,v 1.88 2021/03/21 14:36:59 rillig Exp $");
#endif
#include <stdlib.h>
@@ -605,6 +605,11 @@ if1(tnode_t *tn)
if (tn != NULL)
expr(tn, false, true, false, false);
pushctrl(T_IF);
+
+ if (tn != NULL && tn->tn_op == CON && !tn->tn_system_dependent) {
+ reached = constant_is_nonzero(tn);
+ cstmt->c_always_then = reached;
+ }
}
/*
@@ -616,7 +621,7 @@ if2(void)
{
cstmt->c_reached_end_of_then = reached;
- reached = true; /* XXX: sure? */
+ reached = !cstmt->c_always_then;
}
/*
Index: src/usr.bin/xlint/lint1/lint1.h
diff -u src/usr.bin/xlint/lint1/lint1.h:1.85 src/usr.bin/xlint/lint1/lint1.h:1.86
--- src/usr.bin/xlint/lint1/lint1.h:1.85 Sun Mar 21 13:03:42 2021
+++ src/usr.bin/xlint/lint1/lint1.h Sun Mar 21 14:36:59 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: lint1.h,v 1.85 2021/03/21 13:03:42 rillig Exp $ */
+/* $NetBSD: lint1.h,v 1.86 2021/03/21 14:36:59 rillig Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@@ -289,7 +289,7 @@ typedef struct tnode {
bool tn_cast : 1; /* if tn_op == CVT, it's an explicit cast */
bool tn_parenthesized : 1;
bool tn_from_system_header : 1;
- bool tn_system_dependent : 1;
+ bool tn_system_dependent : 1; /* depends on sizeof or offsetof */
union {
struct {
struct tnode *_tn_left; /* (left) operand */
@@ -393,6 +393,7 @@ typedef struct control_statement {
* always true (as in 'for (;;)' or
* 'while (1)'), there may be break
* statements though */
+ bool c_always_then : 1;
bool c_reached_end_of_then : 1;
bool c_had_return_noval : 1; /* had "return;" */
bool c_had_return_value : 1; /* had "return (e);" */