Module Name:    src
Committed By:   rillig
Date:           Sun May 12 12:28:35 UTC 2024

Modified Files:
        src/tests/usr.bin/xlint/lint1: d_c99_bool_strict.c
            d_c99_bool_strict_syshdr.c
        src/usr.bin/xlint/lint1: ckbool.c externs1.h func.c

Log Message:
lint: in strict bool mode, allow do-while-0

Even though 0 is not a boolean constant, allow this common idiom, to
help in those cases where the C preprocessor used by lint does not mark
tokens as coming from system headers (Clang).


To generate a diff of this commit:
cvs rdiff -u -r1.49 -r1.50 src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.c
cvs rdiff -u -r1.23 -r1.24 \
    src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c
cvs rdiff -u -r1.30 -r1.31 src/usr.bin/xlint/lint1/ckbool.c
cvs rdiff -u -r1.227 -r1.228 src/usr.bin/xlint/lint1/externs1.h
cvs rdiff -u -r1.186 -r1.187 src/usr.bin/xlint/lint1/func.c

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.49 src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.c:1.50
--- src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.c:1.49	Sun May 12 11:46:14 2024
+++ src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.c	Sun May 12 12:28:35 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: d_c99_bool_strict.c,v 1.49 2024/05/12 11:46:14 rillig Exp $	*/
+/*	$NetBSD: d_c99_bool_strict.c,v 1.50 2024/05/12 12:28:35 rillig Exp $	*/
 # 3 "d_c99_bool_strict.c"
 
 /*
@@ -476,7 +476,6 @@ strict_bool_controlling_expression(bool 
 	// or nowhere.
 	/* expect+1: warning: loop not entered at top [207] */
 	do {
-	/* expect+1: error: controlling expression must be bool, not 'int' [333] */
 	} while (0);
 }
 

Index: src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c
diff -u src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c:1.23 src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c:1.24
--- src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c:1.23	Sun May 12 11:46:14 2024
+++ src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c	Sun May 12 12:28:35 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: d_c99_bool_strict_syshdr.c,v 1.23 2024/05/12 11:46:14 rillig Exp $	*/
+/*	$NetBSD: d_c99_bool_strict_syshdr.c,v 1.24 2024/05/12 12:28:35 rillig Exp $	*/
 # 3 "d_c99_bool_strict_syshdr.c"
 
 /*
@@ -17,33 +17,33 @@ extern const unsigned short *ctype_table
 
 extern void println(const char *);
 
+
+
+
 /*
- * On NetBSD 8, <sys/select.h> defines FD_ISSET by enclosing the statements
- * in the well-known 'do { ... } while (CONSTCOND 0)' loop.  The 0 in the
- * controlling expression has type INT but should be allowed nevertheless
- * since that header does not have a way to distinguish between bool and int.
- * It just follows the C99 standard, unlike the lint-provided stdbool.h,
- * which redefines 'false' to '__lint_false'.
+ * No matter whether the code is from a system header or not, the idiom
+ * 'do { ... } while (0)' is well known, and using the integer constant 0
+ * instead of the boolean constant 'false' neither creates any type confusion
+ * nor does its value take place in any conversions, as its scope is limited
+ * to the controlling expression of the loop.
  */
 void
-strict_bool_system_header_statement_macro(void)
+statement_macro(void)
 {
 
 	do {
 		println("nothing");
 	} while (/*CONSTCOND*/0);
-	/* expect-1: error: controlling expression must be bool, not 'int' [333] */
 
-# 38 "d_c99_bool_strict_syshdr.c" 3 4
+# 39 "d_c99_bool_strict_syshdr.c" 3 4
 	do {
 		println("nothing");
-	} while (/*CONSTCOND*/0);	/* ok */
+	} while (/*CONSTCOND*/0);
 
-# 43 "d_c99_bool_strict_syshdr.c"
+# 44 "d_c99_bool_strict_syshdr.c"
 	do {
 		println("nothing");
 	} while (/*CONSTCOND*/0);
-	/* expect-1: error: controlling expression must be bool, not 'int' [333] */
 }
 
 

Index: src/usr.bin/xlint/lint1/ckbool.c
diff -u src/usr.bin/xlint/lint1/ckbool.c:1.30 src/usr.bin/xlint/lint1/ckbool.c:1.31
--- src/usr.bin/xlint/lint1/ckbool.c:1.30	Sat Mar  9 13:54:47 2024
+++ src/usr.bin/xlint/lint1/ckbool.c	Sun May 12 12:28:34 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: ckbool.c,v 1.30 2024/03/09 13:54:47 rillig Exp $ */
+/* $NetBSD: ckbool.c,v 1.31 2024/05/12 12:28:34 rillig Exp $ */
 
 /*-
  * Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
 #include <sys/cdefs.h>
 
 #if defined(__RCSID)
-__RCSID("$NetBSD: ckbool.c,v 1.30 2024/03/09 13:54:47 rillig Exp $");
+__RCSID("$NetBSD: ckbool.c,v 1.31 2024/05/12 12:28:34 rillig Exp $");
 #endif
 
 #include <string.h>
@@ -149,7 +149,7 @@ typeok_scalar_strict_bool(op_t op, const
 
 	if (mp->m_compares_with_zero) {
 		bool binary = mp->m_binary;
-		bool lbool = is_typeok_bool_compares_with_zero(ln);
+		bool lbool = is_typeok_bool_compares_with_zero(ln, false);
 		bool ok = true;
 
 		if (!binary && !lbool) {
@@ -163,7 +163,7 @@ typeok_scalar_strict_bool(op_t op, const
 			ok = false;
 		}
 		if (binary && op != QUEST &&
-		    !is_typeok_bool_compares_with_zero(rn)) {
+		    !is_typeok_bool_compares_with_zero(rn, false)) {
 			/* right operand of '%s' must be bool, not '%s' */
 			error(332, op_name(op), tspec_name(rt));
 			ok = false;
@@ -198,7 +198,7 @@ typeok_scalar_strict_bool(op_t op, const
 }
 
 bool
-is_typeok_bool_compares_with_zero(const tnode_t *tn)
+is_typeok_bool_compares_with_zero(const tnode_t *tn, bool is_do_while)
 {
 	while (tn->tn_op == COMMA)
 		tn = tn->u.ops.right;
@@ -206,6 +206,7 @@ is_typeok_bool_compares_with_zero(const 
 
 	return tn->tn_type->t_tspec == BOOL
 	    || tn->tn_op == BITAND
+	    || (is_do_while && is_int_constant_zero(tn, tn->tn_type->t_tspec))
 	    || (tn->tn_sys && is_scalar(tn->tn_type->t_tspec));
 }
 

Index: src/usr.bin/xlint/lint1/externs1.h
diff -u src/usr.bin/xlint/lint1/externs1.h:1.227 src/usr.bin/xlint/lint1/externs1.h:1.228
--- src/usr.bin/xlint/lint1/externs1.h:1.227	Sun May 12 08:48:36 2024
+++ src/usr.bin/xlint/lint1/externs1.h	Sun May 12 12:28:34 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: externs1.h,v 1.227 2024/05/12 08:48:36 rillig Exp $	*/
+/*	$NetBSD: externs1.h,v 1.228 2024/05/12 12:28:34 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -288,7 +288,7 @@ tnode_t *build_binary(tnode_t *, op_t, b
 tnode_t *build_unary(op_t, bool, tnode_t *);
 tnode_t *build_member_access(tnode_t *, op_t, bool, sbuf_t *);
 tnode_t *cconv(tnode_t *);
-bool is_typeok_bool_compares_with_zero(const tnode_t *);
+bool is_typeok_bool_compares_with_zero(const tnode_t *, bool);
 bool typeok(op_t, int, const tnode_t *, const tnode_t *);
 tnode_t *promote(op_t, bool, tnode_t *);
 tnode_t *convert(op_t, int, type_t *, tnode_t *);

Index: src/usr.bin/xlint/lint1/func.c
diff -u src/usr.bin/xlint/lint1/func.c:1.186 src/usr.bin/xlint/lint1/func.c:1.187
--- src/usr.bin/xlint/lint1/func.c:1.186	Fri Mar 29 08:35:32 2024
+++ src/usr.bin/xlint/lint1/func.c	Sun May 12 12:28:34 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: func.c,v 1.186 2024/03/29 08:35:32 rillig Exp $	*/
+/*	$NetBSD: func.c,v 1.187 2024/05/12 12:28:34 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: func.c,v 1.186 2024/03/29 08:35:32 rillig Exp $");
+__RCSID("$NetBSD: func.c,v 1.187 2024/05/12 12:28:34 rillig Exp $");
 #endif
 
 #include <stdlib.h>
@@ -548,7 +548,7 @@ default_label(void)
 }
 
 static tnode_t *
-check_controlling_expression(tnode_t *tn)
+check_controlling_expression(tnode_t *tn, bool is_do_while)
 {
 	tn = cconv(tn);
 	if (tn != NULL)
@@ -563,7 +563,8 @@ check_controlling_expression(tnode_t *tn
 		return NULL;
 	}
 
-	if (tn != NULL && Tflag && !is_typeok_bool_compares_with_zero(tn)) {
+	if (tn != NULL && Tflag
+	    && !is_typeok_bool_compares_with_zero(tn, is_do_while)) {
 		/* controlling expression must be bool, not '%s' */
 		error(333, tn->tn_type->t_is_enum ? type_name(tn->tn_type)
 		    : tspec_name(tn->tn_type->t_tspec));
@@ -576,7 +577,7 @@ void
 stmt_if_expr(tnode_t *tn)
 {
 	if (tn != NULL)
-		tn = check_controlling_expression(tn);
+		tn = check_controlling_expression(tn, false);
 	if (tn != NULL)
 		expr(tn, false, true, false, false);
 	begin_control_statement(CS_IF);
@@ -721,7 +722,7 @@ stmt_while_expr(tnode_t *tn)
 	}
 
 	if (tn != NULL)
-		tn = check_controlling_expression(tn);
+		tn = check_controlling_expression(tn, false);
 
 	begin_control_statement(CS_WHILE);
 	cstmt->c_loop = true;
@@ -762,7 +763,7 @@ stmt_do_while_expr(tnode_t *tn)
 		set_reached(true);
 
 	if (tn != NULL)
-		tn = check_controlling_expression(tn);
+		tn = check_controlling_expression(tn, true);
 
 	if (tn != NULL && tn->tn_op == CON) {
 		cstmt->c_maybe_endless = constant_is_nonzero(tn);
@@ -811,7 +812,7 @@ stmt_for_exprs(tnode_t *tn1, tnode_t *tn
 		expr(tn1, false, false, true, false);
 
 	if (tn2 != NULL)
-		tn2 = check_controlling_expression(tn2);
+		tn2 = check_controlling_expression(tn2, false);
 	if (tn2 != NULL)
 		expr(tn2, false, true, true, false);
 

Reply via email to