Module Name:    src
Committed By:   rillig
Date:           Sun Jan 17 23:04:09 UTC 2021

Modified Files:
        src/tests/usr.bin/xlint/lint1: d_c99_bool_strict_syshdr.c
            d_c99_bool_strict_syshdr.exp
        src/usr.bin/xlint/lint1: externs1.h scan.l tree.c

Log Message:
lint: allow system headers to use int as bool, even in strict bool mode


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 \
    src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c \
    src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp
cvs rdiff -u -r1.57 -r1.58 src/usr.bin/xlint/lint1/externs1.h
cvs rdiff -u -r1.120 -r1.121 src/usr.bin/xlint/lint1/scan.l
cvs rdiff -u -r1.180 -r1.181 src/usr.bin/xlint/lint1/tree.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_syshdr.c
diff -u src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c:1.1 src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c:1.2
--- src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c:1.1	Sun Jan 17 23:00:41 2021
+++ src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c	Sun Jan 17 23:04:09 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: d_c99_bool_strict_syshdr.c,v 1.1 2021/01/17 23:00:41 rillig Exp $	*/
+/*	$NetBSD: d_c99_bool_strict_syshdr.c,v 1.2 2021/01/17 23:04:09 rillig Exp $	*/
 # 3 "d_c99_bool_strict_syshdr.c"
 
 /*
@@ -26,7 +26,7 @@ strict_bool_system_header_statement_macr
 # 27 "d_c99_bool_strict_syshdr.c" 3 4
 	do {
 		println("nothing");
-	} while (/*CONSTCOND*/0);	/*FIXME*//* expect: 333 */
+	} while (/*CONSTCOND*/0);	/* ok */
 
 # 32 "d_c99_bool_strict_syshdr.c"
 	do {
Index: src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp
diff -u src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp:1.1 src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp:1.2
--- src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp:1.1	Sun Jan 17 23:00:41 2021
+++ src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp	Sun Jan 17 23:04:09 2021
@@ -1,5 +1,4 @@
 d_c99_bool_strict_syshdr.c(24): controlling expression must be bool, not 'int' [333]
-d_c99_bool_strict_syshdr.c(29): controlling expression must be bool, not 'int' [333]
 d_c99_bool_strict_syshdr.c(34): controlling expression must be bool, not 'int' [333]
 d_c99_bool_strict_syshdr.c(71): operands of '=' have incompatible types (_Bool != int) [107]
 d_c99_bool_strict_syshdr.c(77): operands of '=' have incompatible types (int != _Bool) [107]

Index: src/usr.bin/xlint/lint1/externs1.h
diff -u src/usr.bin/xlint/lint1/externs1.h:1.57 src/usr.bin/xlint/lint1/externs1.h:1.58
--- src/usr.bin/xlint/lint1/externs1.h:1.57	Sun Jan 17 15:40:27 2021
+++ src/usr.bin/xlint/lint1/externs1.h	Sun Jan 17 23:04:09 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: externs1.h,v 1.57 2021/01/17 15:40:27 rillig Exp $	*/
+/*	$NetBSD: externs1.h,v 1.58 2021/01/17 23:04:09 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -71,6 +71,7 @@ extern	int	yyparse(void);
 extern  bool	attron;
 extern	pos_t	curr_pos;
 extern	pos_t	csrc_pos;
+extern	bool	in_system_header;
 extern	symt_t	symtyp;
 extern	FILE	*yyin;
 extern	uint64_t qbmasks[], qlmasks[], qumasks[];

Index: src/usr.bin/xlint/lint1/scan.l
diff -u src/usr.bin/xlint/lint1/scan.l:1.120 src/usr.bin/xlint/lint1/scan.l:1.121
--- src/usr.bin/xlint/lint1/scan.l:1.120	Sun Jan 17 15:09:56 2021
+++ src/usr.bin/xlint/lint1/scan.l	Sun Jan 17 23:04:09 2021
@@ -1,5 +1,5 @@
 %{
-/* $NetBSD: scan.l,v 1.120 2021/01/17 15:09:56 rillig Exp $ */
+/* $NetBSD: scan.l,v 1.121 2021/01/17 23:04:09 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -35,7 +35,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: scan.l,v 1.120 2021/01/17 15:09:56 rillig Exp $");
+__RCSID("$NetBSD: scan.l,v 1.121 2021/01/17 23:04:09 rillig Exp $");
 #endif
 
 #include <ctype.h>
@@ -63,6 +63,8 @@ pos_t	csrc_pos = { 1, "", 0 };
 /* Are we parsing a gcc attribute? */
 bool attron;
 
+bool in_system_header = false;
+
 static	void	incline(void);
 static	void	badchar(int);
 static	sbuf_t	*allocsb(void);
@@ -1115,6 +1117,29 @@ getescc(int d)
 	return c;
 }
 
+/* See https://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html */
+static void
+parse_line_directive_flags(const char *p)
+{
+
+	in_system_header = false;
+
+	while (ch_isspace(*p))
+		p++;
+	while (ch_isdigit(*p)) {
+		if (*p == '3' && !ch_isdigit(p[1]))
+			in_system_header = true;
+		p++;
+		while (ch_isspace(*p))
+			p++;
+	}
+
+#if 0
+	if (c != '\0')
+		warning("extra character(s) after directive");
+#endif
+}
+
 /*
  * Called for preprocessor directives. Currently implemented are:
  *	# lineno
@@ -1158,12 +1183,7 @@ directive(void)
 			goto error;
 		if ((fnl = cp++ - fn) > PATH_MAX)
 			goto error;
-		while ((c = *cp++) == ' ' || c == '\t')
-			continue;
-#if 0
-		if (c != '\0')
-			warning("extra character(s) after directive");
-#endif
+		parse_line_directive_flags(cp);
 
 		/* empty string means stdin */
 		if (fnl == 0) {

Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.180 src/usr.bin/xlint/lint1/tree.c:1.181
--- src/usr.bin/xlint/lint1/tree.c:1.180	Sun Jan 17 17:16:47 2021
+++ src/usr.bin/xlint/lint1/tree.c	Sun Jan 17 23:04:09 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.180 2021/01/17 17:16:47 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.181 2021/01/17 23:04:09 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: tree.c,v 1.180 2021/01/17 17:16:47 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.181 2021/01/17 23:04:09 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -723,6 +723,15 @@ before_conversion(const tnode_t *tn)
 	return tn;
 }
 
+static bool
+is_bool_compatible(tspec_t t, const tnode_t *tn)
+{
+	if (t == BOOL)
+		return true;
+	return in_system_header && t == INT && tn->tn_op == CON &&
+	       (tn->tn_val->v_quad == 0 || tn->tn_val->v_quad == 1);
+}
+
 /* In strict bool mode, see if the node's type is compatible with bool. */
 bool
 is_strict_bool(const tnode_t *tn)
@@ -732,7 +741,7 @@ is_strict_bool(const tnode_t *tn)
 	tn = before_conversion(tn);
 	t = tn->tn_type->t_tspec;
 
-	if (t == BOOL)
+	if (is_bool_compatible(t, tn))
 		return true;
 
 	/* For enums that are used as bit sets, allow "flags & FLAG". */
@@ -1115,11 +1124,14 @@ needs_compatible_types(op_t op)
  * behavior.
  */
 static bool
-typeok_strict_bool_compatible(op_t op, int arg, tspec_t lt, tspec_t rt)
+typeok_strict_bool_compatible(op_t op, int arg,
+			      const tnode_t *ln, tspec_t lt,
+			      const tnode_t *rn, tspec_t rt)
 {
+
 	if (!needs_compatible_types(op))
 		return true;
-	if ((lt == BOOL) == (rt == BOOL))
+	if (is_bool_compatible(lt, ln) == is_bool_compatible(rt, rn))
 		return true;
 
 	if (op == FARG) {
@@ -1158,7 +1170,7 @@ typeok_scalar_strict_bool(op_t op, const
 		rt = NOTSPEC;
 	}
 
-	if (!typeok_strict_bool_compatible(op, arg, lt, rt))
+	if (!typeok_strict_bool_compatible(op, arg, ln, lt, rn, rt))
 		return false;
 
 	if (mp->m_requires_bool || op == QUEST) {

Reply via email to