Module Name:    src
Committed By:   rillig
Date:           Sun Jan 10 17:43:46 UTC 2021

Modified Files:
        src/distrib/sets/lists/tests: mi
        src/tests/usr.bin/xlint/lint1: Makefile t_integration.sh
Added Files:
        src/tests/usr.bin/xlint/lint1: d_c99_bool_strict.c
            d_c99_bool_strict.exp

Log Message:
lint: add test for treating _Bool as non-scalar type

This strict mode is not yet implemented.  The plan is to use it for
usr.bin/make, to get rid of the many possible variants of defining the
Boolean type in make.h.  These variants did find some bugs, but not
reliably so.  Using static analysis seems more promising for this.

In an early stage of developing this test, lint1 crashed in the enum
definition in line 213, where the node for the '?:' had been NULL.  This
can happen in other situations as well, such as with syntax errors, but
these should be rare, as lint is usually only run if the compiler has
accepted the source code.  Still, there should not be any assertion
failures while running lint1.


To generate a diff of this commit:
cvs rdiff -u -r1.1008 -r1.1009 src/distrib/sets/lists/tests/mi
cvs rdiff -u -r1.26 -r1.27 src/tests/usr.bin/xlint/lint1/Makefile
cvs rdiff -u -r0 -r1.1 src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.c \
    src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.exp
cvs rdiff -u -r1.22 -r1.23 src/tests/usr.bin/xlint/lint1/t_integration.sh

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/tests/mi
diff -u src/distrib/sets/lists/tests/mi:1.1008 src/distrib/sets/lists/tests/mi:1.1009
--- src/distrib/sets/lists/tests/mi:1.1008	Sun Jan 10 11:24:42 2021
+++ src/distrib/sets/lists/tests/mi	Sun Jan 10 17:43:46 2021
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1008 2021/01/10 11:24:42 rillig Exp $
+# $NetBSD: mi,v 1.1009 2021/01/10 17:43:46 rillig Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -5747,6 +5747,8 @@
 ./usr/tests/usr.bin/xlint/lint1/d_c99_anon_union.c		tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/xlint/lint1/d_c99_bool.c			tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/xlint/lint1/d_c99_bool.exp			tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/d_c99_bool_strict.c		tests-usr.bin-tests	compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/d_c99_bool_strict.exp		tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/xlint/lint1/d_c99_complex_num.c		tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/xlint/lint1/d_c99_complex_split.c		tests-usr.bin-tests	compattestfile,atf
 ./usr/tests/usr.bin/xlint/lint1/d_c99_compound_literal_comma.c	tests-usr.bin-tests	compattestfile,atf

Index: src/tests/usr.bin/xlint/lint1/Makefile
diff -u src/tests/usr.bin/xlint/lint1/Makefile:1.26 src/tests/usr.bin/xlint/lint1/Makefile:1.27
--- src/tests/usr.bin/xlint/lint1/Makefile:1.26	Sun Jan 10 11:24:42 2021
+++ src/tests/usr.bin/xlint/lint1/Makefile	Sun Jan 10 17:43:46 2021
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.26 2021/01/10 11:24:42 rillig Exp $
+# $NetBSD: Makefile,v 1.27 2021/01/10 17:43:46 rillig Exp $
 
 NOMAN=		# defined
 
@@ -13,6 +13,8 @@ FILES+=		d_alignof.c
 FILES+=		d_bltinoffsetof.c
 FILES+=		d_c99_bool.c
 FILES+=		d_c99_bool.exp
+FILES+=		d_c99_bool_strict.c
+FILES+=		d_c99_bool_strict.exp
 FILES+=		d_c99_anon_struct.c
 FILES+=		d_c99_anon_union.c
 FILES+=		d_c99_complex_num.c

Index: src/tests/usr.bin/xlint/lint1/t_integration.sh
diff -u src/tests/usr.bin/xlint/lint1/t_integration.sh:1.22 src/tests/usr.bin/xlint/lint1/t_integration.sh:1.23
--- src/tests/usr.bin/xlint/lint1/t_integration.sh:1.22	Sun Jan 10 11:24:42 2021
+++ src/tests/usr.bin/xlint/lint1/t_integration.sh	Sun Jan 10 17:43:46 2021
@@ -1,4 +1,4 @@
-# $NetBSD: t_integration.sh,v 1.22 2021/01/10 11:24:42 rillig Exp $
+# $NetBSD: t_integration.sh,v 1.23 2021/01/10 17:43:46 rillig Exp $
 #
 # Copyright (c) 2008, 2010 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -66,6 +66,7 @@ test_case bltinoffsetof
 test_case c99_anon_struct
 test_case c99_anon_union
 test_case c99_bool
+test_case c99_bool_strict
 test_case c99_compound_literal_comma
 test_case c99_decls_after_stmt2
 test_case c99_flex_array_packed

Added files:

Index: src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.c:1.1
--- /dev/null	Sun Jan 10 17:43:46 2021
+++ src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.c	Sun Jan 10 17:43:46 2021
@@ -0,0 +1,252 @@
+/*	$NetBSD: d_c99_bool_strict.c,v 1.1 2021/01/10 17:43:46 rillig Exp $	*/
+# 3 "d_c99_bool_strict.c"
+
+/*
+ * Experimental feature:  allow to treat _Bool as incompatible with all
+ * scalar types.  This means:
+ *
+ * SB001: Controlling expressions in 'if', 'while', 'for', '?:' must be of
+ * type _Bool instead of scalar.
+ *
+ * SB002: The operators '!', '==', '!=', '<', '<=', '>=', '>', '&&', '||'
+ * return _Bool instead of int.
+ *
+ * SB003: The operators '!', '&&', '||' take _Bool instead of scalar.
+ *
+ * SB004: The only operators that take _Bool are '!', '==', '!=',
+ * '&', '^', '|', '&&', '||', '?', ':', '=', '&=', '^=', '|='.
+ *
+ * SB005: There is no implicit conversion from _Bool to any other type.
+ *
+ * SB006: A constant integer expression is compatible with type _Bool if
+ * it is an integer constant with value 0 or 1, or if the result type of
+ * its main operator is _Bool.
+ */
+
+// Not yet implemented: /* lint1-extra-flags: -B */
+
+/*
+ * The header <stdbool.h> defines the macros bool = _Bool, false = 0 and
+ * true = 1.  Therefore, constant expressions of integer type have to be
+ * regarded as possible boolean constants if their value is either 0 or 1.
+ * At this point of the translation, the preprocessor has already removed
+ * the words "false" and "true" from the source code.
+ */
+
+/*
+ * Using a typedef for bool does not hurt the checks, they all use the
+ * underlying basic type (see tspec_t), which is BOOL.
+ */
+typedef _Bool bool;
+
+void
+SB001_controlling_expression(bool b, int i, double d, const void *p)
+{
+
+	/* Fine due to SB006. */
+	if (/*CONSTCOND*/0)
+		return;
+
+	/* Fine due to SB006. */
+	if (/*CONSTCOND*/1)
+		return;
+
+	/* Not allowed: 2 is not a boolean expression. */
+	if (/*CONSTCOND*/2)
+		return;
+
+	/* Not allowed: There is no implicit conversion from scalar to bool. */
+	if (i)
+		return;
+	if (i != 0)
+		return;
+
+	/* Not allowed: There is no implicit conversion from scalar to bool. */
+	if (d)
+		return;
+	if (d != 0.0)
+		return;
+
+	/* Not allowed: There is no implicit conversion from scalar to bool. */
+	if (p)
+		return;
+	if (p != (void *)0)
+		return;
+
+	/* Using a bool expression is allowed. */
+	if (b)
+		return;
+}
+
+void
+SB002_operator_result(bool b)
+{
+	b = b;
+	char c = b;
+	int i = b;
+	double d = b;
+	void *p = b;
+
+	/* These assignments are all ok. */
+	b = !b;
+	b = i == i;
+	b = i != i;
+	b = i < i;
+	b = i <= i;
+	b = i >= i;
+	b = i > i;
+	b = b && b;
+	b = b || b;
+
+	/*
+	 * These assignments are not ok, they implicitly convert from bool
+	 * to int.
+	 */
+	i = !b;
+	i = i == i;
+	i = i != i;
+	i = i < i;
+	i = i <= i;
+	i = i >= i;
+	i = i > i;
+	i = b && b;
+	i = b || b;
+}
+
+void
+SB003_operands(bool b, int i)
+{
+
+	/* These assignments are ok. */
+	b = !b;
+	b = b && b;
+	b = b || b;
+
+	/* These assignments implicitly convert from scalar to bool. */
+	b = !i;
+	b = i && i;
+	b = i || i;
+}
+
+void
+SB004_non_bool_operands(bool b, unsigned u)
+{
+	b = !b;			/* ok */
+	b = ~b;			/* not ok */
+	++b;			/* not ok */
+	--b;			/* not ok */
+	b++;			/* not ok */
+	b--;			/* not ok */
+	b = +b;			/* not ok */
+	b = -b;			/* not ok */
+
+	b = b * b;		/* not ok */
+	b = b / b;		/* not ok */
+	b = b % b;		/* not ok */
+	b = b + b;		/* not ok */
+	b = b - b;		/* not ok */
+	b = b << b;		/* not ok */
+	b = b >> b;		/* not ok */
+
+	b = b < b;		/* not ok */
+	b = b <= b;		/* not ok */
+	b = b > b;		/* not ok */
+	b = b >= b;		/* not ok */
+	b = b == b;		/* ok */
+	b = b != b;		/* ok */
+
+	b = b & b;		/* ok */
+	b = b ^ b;		/* ok */
+	b = b | b;		/* ok */
+	b = b && b;		/* ok */
+	b = b || b;		/* ok */
+	b = b ? b : b;		/* ok */
+
+	b = b;			/* ok */
+	b *= b;			/* not ok */
+	b /= b;			/* not ok */
+	b %= b;			/* not ok */
+	b += b;			/* not ok */
+	b -= b;			/* not ok */
+	b <<= b;		/* not ok */
+	b >>= b;		/* not ok */
+	b &= b;			/* ok */
+	b ^= b;			/* ok */
+	b |= b;			/* ok */
+
+	/* Operations with mixed types. */
+	u = b * u;		/* not ok */
+	u = u * b;		/* not ok */
+	u = b / u;		/* not ok */
+	u = u / b;		/* not ok */
+	u = b % u;		/* not ok */
+	u = u % b;		/* not ok */
+	u = b + u;		/* not ok */
+	u = u + b;		/* not ok */
+	u = b - u;		/* not ok */
+	u = u - b;		/* not ok */
+	u = b << u;		/* not ok */
+	u = u << b;		/* not ok */
+	u = b >> u;		/* not ok */
+	u = u >> b;		/* not ok */
+	u = b ? u : u;		/* ok */
+	u = b ? b : u;		/* not ok */
+	u = b ? u : b;		/* not ok */
+}
+
+void
+SB005_convert_from_bool_to_scalar(bool b)
+{
+	int i;
+	unsigned u;
+	double d;
+	void *p;
+
+	i = b;			/* not ok */
+	u = b;			/* not ok */
+	d = b;			/* not ok */
+	p = b;			/* not ok */
+}
+
+enum SB006_bool_constant_expression {
+	/* Ok: 0 is a boolean constant expression. */
+	INT0 = 0 ? 100 : 101,
+
+	/* Ok: 1 is a boolean constant expression. */
+	INT1 = 1 ? 100 : 101,
+
+	/* Not ok: 2 is not a boolean constant (neither 0 nor 1). */
+	INT2 = 2 ? 100 : 101,
+
+	/*
+	 * Not ok: the intermediate expression "2 - 2" has return type
+	 * scalar, not bool.  It is irrelevant that the final result
+	 * is 0, which would be a boolean constant.
+	 */
+	ARITH = (2 - 2) ? 100 : 101,
+
+	/*
+	 * Ok: The 13 and 12 are not boolean expressions, but they
+	 * are not in the calculation path that leads to the final
+	 * result.  The important point is that the operator '>' has
+	 * return type bool.
+	 */
+	Q1 = (13 > 12) ? 100 : 101,
+
+	/*
+	 * Not ok: The 7 is irrelevant for the final result of the
+	 * expression, yet it turns the result type of the operator
+	 * '?:' to be int, not bool.
+	 */
+	Q2 = (13 > 12 ? 1 : 7) ? 100 : 101,
+
+	BINAND = 0 & 1,		/* ok */
+
+	BINXOR = 0 ^ 1,		/* ok */
+
+	BINOR = 0 | 1,		/* ok */
+
+	LOGOR = 0 || 1,		/* ok */
+
+	LOGAND = 0 && 1,	/* ok */
+};
Index: src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.exp
diff -u /dev/null src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.exp:1.1
--- /dev/null	Sun Jan 10 17:43:46 2021
+++ src/tests/usr.bin/xlint/lint1/d_c99_bool_strict.exp	Sun Jan 10 17:43:46 2021
@@ -0,0 +1,2 @@
+d_c99_bool_strict.c(88): warning: illegal combination of pointer (pointer to void) and integer (_Bool), op = [123]
+d_c99_bool_strict.c(208): warning: illegal combination of pointer (pointer to void) and integer (_Bool), op = [123]

Reply via email to