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]