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);" */

Reply via email to