lint: in strict bool mode, integer constants do not have type bool

Previously, lint1 allowed integer constants such as 0 and 1 to be used
as bool constants.  This was only half-baked since after fixing all
error messages from that strict mode, there may still be integer
literals in the code that should be replaced with true or false.  This
would stop a migration from int to bool in the middle, leaving
inconsistent code around.

To find the remaining type inconsistencies, treat integers and bool as
completely incompatible, even for compile time constants.
This commit is contained in:
rillig 2021-01-16 16:03:46 +00:00
parent 89f30dcf4f
commit 9f199e7ddf
23 changed files with 165 additions and 91 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.2368 2021/01/08 09:41:24 uki Exp $
# $NetBSD: mi,v 1.2369 2021/01/16 16:03:46 rillig Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
./etc/mtree/set.comp comp-sys-root
@ -4011,6 +4011,8 @@
./usr/libdata/debug/usr/tests/crypto/libcrypto/h_shatest.debug comp-obsolete openssl=11,obsolete
./usr/libdata/debug/usr/tests/crypto/libcrypto/h_x509v3test.debug comp-obsolete openssl=11,obsolete
./usr/libdata/ldscripts/kmodule comp-util-share binutils,kmod
./usr/libdata/lint/strict-bool comp-c-bin lint
./usr/libdata/lint/strict-bool/stdbool.h comp-c-bin lint
./usr/libdata/lint/llib-larchive.ln comp-c-lintlib lint
./usr/libdata/lint/llib-lasn1.ln comp-krb5-lintlib lint,kerberos
./usr/libdata/lint/llib-lbind9.ln comp-bind-lintlib lint

View File

@ -1,4 +1,4 @@
/* $NetBSD: d_c99_bool_strict.c,v 1.8 2021/01/16 15:02:11 rillig Exp $ */
/* $NetBSD: d_c99_bool_strict.c,v 1.9 2021/01/16 16:03:47 rillig Exp $ */
# 3 "d_c99_bool_strict.c"
/*
@ -123,8 +123,8 @@ strict_bool_constant(void)
{
accept_bool(__lint_false);
accept_bool(__lint_true);
accept_bool(0); /* TODO: expect: 334 */
accept_bool(1); /* TODO: expect: 334 */
accept_bool(0); /* expect: 334 */
accept_bool(1); /* expect: 334 */
accept_bool(2); /* expect: 334 */
}
@ -136,16 +136,16 @@ enum strict_bool_constant_expressions {
TRUE = __lint_true ? 100 : 101,
/* Not ok: an integer is not a boolean constant expression. */
INT0 = 0 ? 100 : 101, /* TODO: expect: 331 */
INT0 = 0 ? 100 : 101, /* expect: 331 */
/* Not ok: an integer is not a boolean constant expression. */
INT1 = 1 ? 100 : 101, /* TODO: expect: 331 */
INT1 = 1 ? 100 : 101, /* expect: 331 */
/* Not ok: 2 is not a boolean constant. */
INT2 = 2 ? 100 : 101, /* expect: 331 */
/* Not ok: compound integer expressions are not bool. */
ARITH = (2 - 2) ? 100 : 101, /* TODO: expect: 331 */
ARITH = (2 - 2) ? 100 : 101, /* expect: 331 */
/*
* Without strict bool mode, these two variants of an expression can
@ -155,8 +155,8 @@ enum strict_bool_constant_expressions {
* TODO: figure out an elegant way to achieve the same effect in
* strict bool mode.
*/
BINARY_PLUS = (1 + 0) ? 100 : 101, /* TODO: expect: 331 */
UNARY_PLUS = (+0) ? 100 : 101, /* TODO: expect: 331 */
BINARY_PLUS = (1 + 0) ? 100 : 101, /* expect: 331 */
UNARY_PLUS = (+0) ? 100 : 101, /* expect: 331 */
/* The main operator '>' has return type bool. */
Q1 = (13 > 12) ? 100 : 101,
@ -165,7 +165,7 @@ enum strict_bool_constant_expressions {
* The parenthesized expression has type int and thus cannot be
* used as the controlling expression in the '?:' operator.
*/
Q2 = (13 > 12 ? 1 : 7) ? 100 : 101,
Q2 = (13 > 12 ? 1 : 7) ? 100 : 101, /* expect: 331 */
BINAND_BOOL = __lint_false & __lint_true,
BINAND_INT = 0 & 1,
@ -177,10 +177,10 @@ enum strict_bool_constant_expressions {
BINOR_INT = 0 | 1,
LOGOR_BOOL = __lint_false || __lint_true,
LOGOR_INT = 0 || 1, /* TODO: expect: 331, 332 */
LOGOR_INT = 0 || 1, /* expect: 331, 332 */
LOGAND_BOOL = __lint_false && __lint_true,
LOGAND_INT = 0 && 1, /* TODO: expect: 331, 332 */
LOGAND_INT = 0 && 1, /* expect: 331, 332 */
};
/*
@ -249,13 +249,13 @@ strict_bool_conversion_return_bool(bool b)
bool
strict_bool_conversion_return_0(void)
{
return 0; /* TODO: expect: 211 */
return 0; /* expect: 211 */
}
bool
strict_bool_conversion_return_1(void)
{
return 1; /* TODO: expect: 211 */
return 1; /* expect: 211 */
}
bool
@ -315,8 +315,8 @@ strict_bool_conversion_function_argument_pass(bool b, int i, const char *p)
take_arguments(__lint_true, i, p);
/* Trying to pass integer constants. */
take_arguments(0, i, p); /* TODO: expect: 334 */
take_arguments(1, i, p); /* TODO: expect: 334 */
take_arguments(0, i, p); /* expect: 334 */
take_arguments(1, i, p); /* expect: 334 */
take_arguments(2, i, p); /* expect: 334 */
}
@ -326,9 +326,9 @@ strict_bool_conversion_between_bool_and_int(void)
bool b;
int i;
b = 0;
b = __lint_false; /* TODO: expect: 107 */
b = 1;
b = 0; /* expect: 107 */
b = __lint_false;
b = 1; /* expect: 107 */
b = __lint_true;
i = 0;
@ -372,10 +372,10 @@ strict_bool_controlling_expression(bool b, int i, double d, const void *p)
if (b)
do_nothing();
if (0) /* TODO: expect: 333 */
if (0) /* expect: 333 */
do_nothing();
if (1) /* TODO: expect: 333 */
if (1) /* expect: 333 */
do_nothing();
if (2) /* expect: 333 */
@ -422,8 +422,8 @@ strict_bool_operand_unary_not(void)
i = !i; /* expect: 330 */
i = !!!i; /* expect: 330 */
i = !0; /* expect: 107 */
i = !1; /* expect: 107 */
i = !0; /* expect: 330 */
i = !1; /* expect: 330 */
}
void
@ -476,13 +476,13 @@ strict_bool_operand_binary_dot_arrow(void)
struct bool_struct bs = { __lint_true };
b = bs.b;
bs.b = b;
bs.b = 0; /* TODO: expect: incompatible types */
bs.b = 0; /* expect: 107 */
/* Access a struct member using the '->' operator. */
struct bool_struct *bsp = &bs;
b = bsp->b;
bsp->b = b;
bsp->b = 0;
bsp->b = 0; /* expect: 107 */
}
int
@ -502,10 +502,10 @@ strict_bool_operand_binary(bool b, int i)
b = i && i; /* expect: 331, 332 */
b = i || i; /* expect: 331, 332 */
b = b && 0;
b = 0 && b;
b = b || 0;
b = 0 || b;
b = b && 0; /* expect: 332 */
b = 0 && b; /* expect: 331 */
b = b || 0; /* expect: 332 */
b = 0 || b; /* expect: 331 */
return i;
}

View File

@ -1,10 +1,24 @@
d_c99_bool_strict.c(126): argument #1 expects '_Bool', gets passed 'int' [334]
d_c99_bool_strict.c(127): argument #1 expects '_Bool', gets passed 'int' [334]
d_c99_bool_strict.c(128): argument #1 expects '_Bool', gets passed 'int' [334]
d_c99_bool_strict.c(139): left operand of '?' must be bool, not 'int' [331]
d_c99_bool_strict.c(142): left operand of '?' must be bool, not 'int' [331]
d_c99_bool_strict.c(145): left operand of '?' must be bool, not 'int' [331]
d_c99_bool_strict.c(148): left operand of '?' must be bool, not 'int' [331]
d_c99_bool_strict.c(158): left operand of '?' must be bool, not 'int' [331]
d_c99_bool_strict.c(159): left operand of '?' must be bool, not 'int' [331]
d_c99_bool_strict.c(168): left operand of '?' must be bool, not 'int' [331]
d_c99_bool_strict.c(180): left operand of '||' must be bool, not 'int' [331]
d_c99_bool_strict.c(180): right operand of '||' must be bool, not 'int' [332]
d_c99_bool_strict.c(183): left operand of '&&' must be bool, not 'int' [331]
d_c99_bool_strict.c(183): right operand of '&&' must be bool, not 'int' [332]
d_c99_bool_strict.c(203): operands of '=' have incompatible types (_Bool != unsigned int) [107]
d_c99_bool_strict.c(205): operands of '=' have incompatible types (unsigned int != _Bool) [107]
d_c99_bool_strict.c(208): operands of '=' have incompatible types (_Bool != unsigned int) [107]
d_c99_bool_strict.c(210): operands of '=' have incompatible types (unsigned int != _Bool) [107]
d_c99_bool_strict.c(224): operands of '=' have incompatible types (_Bool != int) [107]
d_c99_bool_strict.c(252): return value type mismatch (_Bool) and (int) [211]
d_c99_bool_strict.c(258): return value type mismatch (_Bool) and (int) [211]
d_c99_bool_strict.c(264): return value type mismatch (_Bool) and (int) [211]
d_c99_bool_strict.c(270): return value type mismatch (_Bool) and (pointer to const void) [211]
d_c99_bool_strict.c(268): warning: argument p unused in function strict_bool_conversion_return_pointer [231]
@ -16,7 +30,11 @@ d_c99_bool_strict.c(303): argument #1 expects '_Bool', gets passed 'int' [334]
d_c99_bool_strict.c(303): warning: illegal combination of pointer (pointer to const char) and integer (int), arg #3 [154]
d_c99_bool_strict.c(306): argument #1 expects '_Bool', gets passed 'pointer' [334]
d_c99_bool_strict.c(306): warning: illegal combination of integer (int) and pointer (pointer to const char), arg #2 [154]
d_c99_bool_strict.c(318): argument #1 expects '_Bool', gets passed 'int' [334]
d_c99_bool_strict.c(319): argument #1 expects '_Bool', gets passed 'int' [334]
d_c99_bool_strict.c(320): argument #1 expects '_Bool', gets passed 'int' [334]
d_c99_bool_strict.c(329): operands of '=' have incompatible types (_Bool != int) [107]
d_c99_bool_strict.c(331): operands of '=' have incompatible types (_Bool != int) [107]
d_c99_bool_strict.c(335): operands of '=' have incompatible types (int != _Bool) [107]
d_c99_bool_strict.c(337): operands of '=' have incompatible types (int != _Bool) [107]
d_c99_bool_strict.c(339): operands of '=' have incompatible types (int != _Bool) [107]
@ -26,19 +44,27 @@ d_c99_bool_strict.c(352): operands of '=' have incompatible types (unsigned int
d_c99_bool_strict.c(353): operands of '=' have incompatible types (double != _Bool) [107]
d_c99_bool_strict.c(354): operands of '=' have incompatible types (pointer != _Bool) [107]
d_c99_bool_strict.c(344): warning: argument b unused in function strict_bool_conversion_from_bool_to_scalar [231]
d_c99_bool_strict.c(375): controlling expression must be bool, not 'int' [333]
d_c99_bool_strict.c(378): controlling expression must be bool, not 'int' [333]
d_c99_bool_strict.c(381): controlling expression must be bool, not 'int' [333]
d_c99_bool_strict.c(385): controlling expression must be bool, not 'int' [333]
d_c99_bool_strict.c(391): controlling expression must be bool, not 'double' [333]
d_c99_bool_strict.c(397): controlling expression must be bool, not 'pointer' [333]
d_c99_bool_strict.c(423): operand of '!' must be bool, not 'int' [330]
d_c99_bool_strict.c(424): operand of '!' must be bool, not 'int' [330]
d_c99_bool_strict.c(425): operands of '=' have incompatible types (int != _Bool) [107]
d_c99_bool_strict.c(426): operands of '=' have incompatible types (int != _Bool) [107]
d_c99_bool_strict.c(425): operand of '!' must be bool, not 'int' [330]
d_c99_bool_strict.c(426): operand of '!' must be bool, not 'int' [330]
d_c99_bool_strict.c(479): operands of '=' have incompatible types (_Bool != int) [107]
d_c99_bool_strict.c(485): operands of '=' have incompatible types (_Bool != int) [107]
d_c99_bool_strict.c(501): operand of '!' must be bool, not 'int' [330]
d_c99_bool_strict.c(502): left operand of '&&' must be bool, not 'int' [331]
d_c99_bool_strict.c(502): right operand of '&&' must be bool, not 'int' [332]
d_c99_bool_strict.c(503): left operand of '||' must be bool, not 'int' [331]
d_c99_bool_strict.c(503): right operand of '||' must be bool, not 'int' [332]
d_c99_bool_strict.c(505): right operand of '&&' must be bool, not 'int' [332]
d_c99_bool_strict.c(506): left operand of '&&' must be bool, not 'int' [331]
d_c99_bool_strict.c(507): right operand of '||' must be bool, not 'int' [332]
d_c99_bool_strict.c(508): left operand of '||' must be bool, not 'int' [331]
d_c99_bool_strict.c(517): operand of '~' must not be bool [335]
d_c99_bool_strict.c(518): operand of '++x' must not be bool [335]
d_c99_bool_strict.c(519): operand of '--x' must not be bool [335]

View File

@ -1,4 +1,4 @@
/* $NetBSD: msg_330.c,v 1.2 2021/01/16 12:57:37 rillig Exp $ */
/* $NetBSD: msg_330.c,v 1.3 2021/01/16 16:03:47 rillig Exp $ */
# 3 "msg_330.c"
// Test for message: operand of '%s' must be bool, not '%s' [330]
@ -17,6 +17,6 @@ void
example(bool b, char c, int i)
{
called(!b);
called(!c); /* expect: 330 */
called(!i); /* expect: 330 */
called(!c); /* expect: 330, 334 */
called(!i); /* expect: 330, 334 */
}

View File

@ -1,2 +1,4 @@
msg_330.c(20): operand of '!' must be bool, not 'char' [330]
msg_330.c(20): argument #1 expects '_Bool', gets passed 'int' [334]
msg_330.c(21): operand of '!' must be bool, not 'int' [330]
msg_330.c(21): argument #1 expects '_Bool', gets passed 'int' [334]

View File

@ -1,4 +1,4 @@
/* $NetBSD: msg_331.c,v 1.1 2021/01/14 22:18:14 rillig Exp $ */
/* $NetBSD: msg_331.c,v 1.2 2021/01/16 16:03:47 rillig Exp $ */
# 3 "msg_331.c"
// Test for message: left operand of '%s' must be bool, not '%s' [331]
@ -16,8 +16,8 @@ void
example(bool b, char c, int i)
{
test(b && b);
test(c && b); /* expect: 331 */
test(i && b); /* expect: 331 */
test(c && b); /* expect: 331, 334 */
test(i && b); /* expect: 331, 334 */
test(c != '\0');
test(i != 0);

View File

@ -1,2 +1,4 @@
msg_331.c(19): left operand of '&&' must be bool, not 'char' [331]
msg_331.c(19): argument #1 expects '_Bool', gets passed 'int' [334]
msg_331.c(20): left operand of '&&' must be bool, not 'int' [331]
msg_331.c(20): argument #1 expects '_Bool', gets passed 'int' [334]

View File

@ -1,4 +1,4 @@
/* $NetBSD: msg_332.c,v 1.1 2021/01/14 22:18:14 rillig Exp $ */
/* $NetBSD: msg_332.c,v 1.2 2021/01/16 16:03:47 rillig Exp $ */
# 3 "msg_332.c"
// Test for message: right operand of '%s' must be bool, not '%s' [332]
@ -16,8 +16,8 @@ void
example(bool b, char c, int i)
{
test(b && b);
test(b && c); /* expect: 332 */
test(b && i); /* expect: 332 */
test(b && c); /* expect: 332, 334 */
test(b && i); /* expect: 332, 334 */
test(c != '\0');
test(i != 0);

View File

@ -1,2 +1,4 @@
msg_332.c(19): right operand of '&&' must be bool, not 'char' [332]
msg_332.c(19): argument #1 expects '_Bool', gets passed 'int' [334]
msg_332.c(20): right operand of '&&' must be bool, not 'int' [332]
msg_332.c(20): argument #1 expects '_Bool', gets passed 'int' [334]

View File

@ -1,4 +1,4 @@
/* $NetBSD: msg_333.c,v 1.1 2021/01/14 22:18:14 rillig Exp $ */
/* $NetBSD: msg_333.c,v 1.2 2021/01/16 16:03:47 rillig Exp $ */
# 3 "msg_333.c"
// Test for message: controlling expression must be bool, not '%s' [333]
@ -18,7 +18,9 @@ example(bool b, int i, const char *p)
return "int";
if (p) /* expect: 333 */
return "pointer";
if (0)
return "constant int or bool";
if (__lint_false)
return "bool constant";
if (0) /* expect: 333 */
return "integer constant";
return p + i;
}

View File

@ -1,2 +1,3 @@
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(23): controlling expression must be bool, not 'int' [333]

View File

@ -1,4 +1,4 @@
/* $NetBSD: msg_336.c,v 1.1 2021/01/14 22:18:14 rillig Exp $ */
/* $NetBSD: msg_336.c,v 1.2 2021/01/16 16:03:47 rillig Exp $ */
# 3 "msg_336.c"
// Test for message: left operand of '%s' must not be bool [336]
@ -15,7 +15,7 @@ test(bool);
void
example(bool b, int i)
{
test(b + i); /* expect: 336 */
test(b + i); /* expect: 336, 334 */
test(b);
test(i != 0);
}

View File

@ -1 +1,2 @@
msg_336.c(18): left operand of '+' must not be bool [336]
msg_336.c(18): argument #1 expects '_Bool', gets passed 'int' [334]

View File

@ -1,4 +1,4 @@
/* $NetBSD: msg_337.c,v 1.1 2021/01/14 22:18:14 rillig Exp $ */
/* $NetBSD: msg_337.c,v 1.2 2021/01/16 16:03:47 rillig Exp $ */
# 3 "msg_337.c"
// Test for message: right operand of '%s' must not be bool [337]
@ -15,7 +15,7 @@ test(bool);
void
example(bool b, int i)
{
test(i + b); /* expect: 337 */
test(i + b); /* expect: 337, 334 */
test(b);
test(i != 0);
}

View File

@ -1 +1,2 @@
msg_337.c(18): right operand of '+' must not be bool [337]
msg_337.c(18): argument #1 expects '_Bool', gets passed 'int' [334]

View File

@ -1,5 +1,5 @@
%{
/* $NetBSD: cgram.y,v 1.140 2021/01/16 02:40:02 rillig Exp $ */
/* $NetBSD: cgram.y,v 1.141 2021/01/16 16:03:46 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: cgram.y,v 1.140 2021/01/16 02:40:02 rillig Exp $");
__RCSID("$NetBSD: cgram.y,v 1.141 2021/01/16 16:03:46 rillig Exp $");
#endif
#include <limits.h>
@ -923,7 +923,7 @@ enum_spec:
enum:
T_ENUM {
symtyp = FTAG;
pushdecl(ENUMCON);
pushdecl(CTCONST);
}
;

View File

@ -1,4 +1,4 @@
/* $NetBSD: decl.c,v 1.122 2021/01/16 02:40:02 rillig Exp $ */
/* $NetBSD: decl.c,v 1.123 2021/01/16 16:03:46 rillig Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
__RCSID("$NetBSD: decl.c,v 1.122 2021/01/16 02:40:02 rillig Exp $");
__RCSID("$NetBSD: decl.c,v 1.123 2021/01/16 16:03:46 rillig Exp $");
#endif
#include <sys/param.h>
@ -614,11 +614,11 @@ popdecl(void)
switch (di->d_ctx) {
case MOS:
case MOU:
case ENUMCON:
case CTCONST:
/*
* Symbols declared in (nested) structs or enums are
* part of the next level (they are removed from the
* symbol table if the symbols of the outher level are
* symbol table if the symbols of the outer level are
* removed).
*/
if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL)
@ -1851,7 +1851,7 @@ enumeration_constant(sym_t *sym, int val, bool impl)
}
sym = pushdown(sym);
}
sym->s_scl = ENUMCON;
sym->s_scl = CTCONST;
sym->s_type = dcs->d_tagtyp;
sym->s_value.v_tspec = INT;
sym->s_value.v_quad = val;
@ -2010,7 +2010,7 @@ check_redeclaration(sym_t *dsym, bool *dowarn)
{
sym_t *rsym;
if ((rsym = dcs->d_rdcsym)->s_scl == ENUMCON) {
if ((rsym = dcs->d_rdcsym)->s_scl == CTCONST) {
/* redeclaration of %s */
error(27, dsym->s_name);
print_previous_declaration(-1, rsym);
@ -3175,7 +3175,7 @@ static void
check_global_variable(const sym_t *sym)
{
if (sym->s_scl == TYPEDEF || sym->s_scl == ENUMCON)
if (sym->s_scl == TYPEDEF || sym->s_scl == CTCONST)
return;
if (sym->s_scl == NOSCL)

View File

@ -1,4 +1,4 @@
/* $NetBSD: lint1.h,v 1.55 2021/01/16 02:40:02 rillig Exp $ */
/* $NetBSD: lint1.h,v 1.56 2021/01/16 16:03:46 rillig Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@ -205,7 +205,7 @@ typedef enum {
ENUMTAG,
MOS, /* member of struct */
MOU, /* member of union */
ENUMCON, /* enumerator, enum constant */
CTCONST, /* enumerator, enum constant or bool constant */
ABSTRACT, /* abstract symbol (sizeof, casts, unnamed argument) */
ARG, /* argument */
PARG, /* used in declaration stack during prototype
@ -244,7 +244,7 @@ typedef struct sym {
int s_blklev; /* level of declaration, -1 if not in symbol
table */
type_t *s_type;
val_t s_value; /* value (if enum constant) */
val_t s_value; /* value (if enum or bool constant) */
union {
str_t *_s_st; /* tag, if it is a struct/union member */
tenum_t *_s_et; /* tag, if it is an enumerator */
@ -314,7 +314,7 @@ typedef struct tnode {
* one of
* EXTERN global declarations
* MOS oder MOU declarations of struct or union members
* ENUMCON declarations of enums
* CTCONST declarations of enums
* ARG declaration of arguments in old style function definitions
* PARG declaration of arguments in function prototypes
* AUTO declaration of local symbols

View File

@ -1,4 +1,4 @@
/* $NetBSD: tree.c,v 1.155 2021/01/16 15:02:11 rillig Exp $ */
/* $NetBSD: tree.c,v 1.156 2021/01/16 16:03:46 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.155 2021/01/16 15:02:11 rillig Exp $");
__RCSID("$NetBSD: tree.c,v 1.156 2021/01/16 16:03:46 rillig Exp $");
#endif
#include <float.h>
@ -228,14 +228,14 @@ new_name_node(sym_t *sym, int ntok)
sym->s_type = incref(sym->s_type, FUNC);
} else {
if (Tflag && strcmp(sym->s_name, "__lint_false") == 0) {
sym->s_scl = ENUMCON; /* close enough */
sym->s_scl = CTCONST; /* close enough */
sym->s_type = gettyp(BOOL);
sym->s_value.v_tspec = BOOL;
sym->s_value.v_ansiu = false;
sym->s_value.v_quad = 0;
} else if (Tflag &&
strcmp(sym->s_name, "__lint_true") == 0) {
sym->s_scl = ENUMCON; /* close enough */
sym->s_scl = CTCONST; /* close enough */
sym->s_type = gettyp(BOOL);
sym->s_value.v_tspec = BOOL;
sym->s_value.v_ansiu = false;
@ -274,7 +274,7 @@ new_name_node(sym_t *sym, int ntok)
n = getnode();
n->tn_type = sym->s_type;
if (sym->s_scl != ENUMCON) {
if (sym->s_scl != CTCONST) {
n->tn_op = NAME;
n->tn_sym = sym;
if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC)
@ -716,21 +716,6 @@ before_conversion(const tnode_t *tn)
return tn;
}
static bool
is_strict_bool_constant(const tnode_t *tn)
{
tspec_t t;
tn = before_conversion(tn);
t = tn->tn_type->t_tspec;
if (t == BOOL)
return true;
return 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)
@ -743,10 +728,6 @@ is_strict_bool(const tnode_t *tn)
if (t == BOOL)
return true;
if (t == INT && tn->tn_op == CON &&
(tn->tn_val->v_quad == 0 || tn->tn_val->v_quad == 1))
return true;
/* For enums that are used as bit sets, allow "flags & FLAG". */
if (tn->tn_op == AND &&
tn->tn_left->tn_op == CVT &&
@ -1114,7 +1095,7 @@ typeok_strict_bool_assign(op_t op, int arg,
if ((lt == BOOL) == (rt == BOOL))
return true;
if (lt == BOOL && is_strict_bool_constant(rn))
if (lt == BOOL && before_conversion(rn)->tn_type->t_tspec == BOOL)
return true;
if (op == FARG) {

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.16 2008/01/11 00:38:10 lukem Exp $
# $NetBSD: Makefile,v 1.17 2021/01/16 16:03:46 rillig Exp $
.PATH: ${.CURDIR}/../lint1
.PATH: ${.CURDIR}/../../mkdep
@ -16,4 +16,8 @@ DPADD+= ${LIBUTIL}
LDADD+= -lutil
.endif
FILES+= strict-bool-stdbool.h
FILESDIR= /usr/libdata/lint/strict-bool
FILESNAME_strict-bool-stdbool.h= stdbool.h
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
/* $NetBSD: pathnames.h,v 1.4 2001/08/14 10:18:29 tv Exp $ */
/* $NetBSD: pathnames.h,v 1.5 2021/01/16 16:03:46 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@ -41,3 +41,6 @@
/* default library search path */
#define PATH_LINTLIB "/usr/libdata/lint"
/* overridden system headers */
#define PATH_STRICT_BOOL_INCLUDE PATH_LINTLIB "/strict-bool"

View File

@ -0,0 +1,41 @@
/* $NetBSD: strict-bool-stdbool.h,v 1.1 2021/01/16 16:03:46 rillig Exp $ */
/*-
* Copyright (c) 2021 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Roland Illig.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LINT_STDBOOL_H
#define _LINT_STDBOOL_H
#define bool _Bool
#define false __lint_false
#define true __lint_true
#define __bool_true_false_are_defined 1
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: xlint.c,v 1.54 2021/01/16 02:40:03 rillig Exp $ */
/* $NetBSD: xlint.c,v 1.55 2021/01/16 16:03:46 rillig Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
__RCSID("$NetBSD: xlint.c,v 1.54 2021/01/16 02:40:03 rillig Exp $");
__RCSID("$NetBSD: xlint.c,v 1.55 2021/01/16 16:03:46 rillig Exp $");
#endif
#include <sys/param.h>
@ -392,7 +392,6 @@ main(int argc, char *argv[])
/* FALLTHROUGH */
case 'u':
case 'h':
case 'T':
(void)sprintf(flgbuf, "-%c", c);
appcstrg(&l1flags, flgbuf);
appcstrg(&l2flags, flgbuf);
@ -451,6 +450,13 @@ main(int argc, char *argv[])
Sflag = true;
break;
case 'T':
(void)sprintf(flgbuf, "-%c", c);
appcstrg(&cflags, "-I" PATH_STRICT_BOOL_INCLUDE);
appcstrg(&l1flags, flgbuf);
appcstrg(&l2flags, flgbuf);
break;
#if ! HAVE_NBTOOL_CONFIG_H
case 't':
if (sflag)