Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/xlint/lint1 lint: fix two wrong error messages in st...
details: https://anonhg.NetBSD.org/src/rev/891f6c04b30e
branches: trunk
changeset: 958868:891f6c04b30e
user: rillig <rillig%NetBSD.org@localhost>
date: Sat Jan 23 22:20:17 2021 +0000
description:
lint: fix two wrong error messages in strict bool mode
The strict bool mode gets complicated because for system headers the
rules need to be relaxed since they cannot be changed easily, often not at all.
Still, if lint validates a program in strict bool mode, that program
must run with equal behavior regarding boolean expressions even on a
pre-C99 platform.
diffstat:
tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c | 6 +-
tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp | 2 -
usr.bin/xlint/lint1/externs1.h | 4 +-
usr.bin/xlint/lint1/func.c | 6 +-
usr.bin/xlint/lint1/lint1.h | 3 +-
usr.bin/xlint/lint1/mem1.c | 11 +-
usr.bin/xlint/lint1/tree.c | 92 ++++++++++++-----
7 files changed, 81 insertions(+), 43 deletions(-)
diffs (truncated from 309 to 300 lines):
diff -r f7820a3f46cd -r 891f6c04b30e tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c
--- a/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c Sat Jan 23 20:00:19 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c Sat Jan 23 22:20:17 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: d_c99_bool_strict_syshdr.c,v 1.3 2021/01/23 19:03:55 rillig Exp $ */
+/* $NetBSD: d_c99_bool_strict_syshdr.c,v 1.4 2021/01/23 22:20:18 rillig Exp $ */
# 3 "d_c99_bool_strict_syshdr.c"
/*
@@ -79,13 +79,13 @@
# 80 "d_c99_bool_strict_syshdr.c" 3 4
(int)((ctype_table + 1)[c] & 0x0040) != 0 /* BOOL */
# 82 "d_c99_bool_strict_syshdr.c"
- ; /* expect: 107 */
+ ;
if (
# 86 "d_c99_bool_strict_syshdr.c" 3 4
(int)((ctype_table + 1)[c] & 0x0040) /* INT */
# 88 "d_c99_bool_strict_syshdr.c"
- ) /*FIXME*//* expect: 333 */
+ )
println("system macro returning INT");
if (
diff -r f7820a3f46cd -r 891f6c04b30e tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp
--- a/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp Sat Jan 23 20:00:19 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp Sat Jan 23 22:20:17 2021 +0000
@@ -1,8 +1,6 @@
d_c99_bool_strict_syshdr.c(32): controlling expression must be bool, not 'int' [333]
d_c99_bool_strict_syshdr.c(42): controlling expression must be bool, not 'int' [333]
d_c99_bool_strict_syshdr.c(76): operands of '=' have incompatible types (_Bool != int) [107]
-d_c99_bool_strict_syshdr.c(82): operands of '=' have incompatible types (int != _Bool) [107]
-d_c99_bool_strict_syshdr.c(88): controlling expression must be bool, not 'int' [333]
d_c99_bool_strict_syshdr.c(121): operands of '!=' have incompatible types (_Bool != int) [107]
d_c99_bool_strict_syshdr.c(121): warning: function ch_isspace_sys_bool expects to return value [214]
d_c99_bool_strict_syshdr.c(115): warning: argument c unused in function ch_isspace_sys_bool [231]
diff -r f7820a3f46cd -r 891f6c04b30e usr.bin/xlint/lint1/externs1.h
--- a/usr.bin/xlint/lint1/externs1.h Sat Jan 23 20:00:19 2021 +0000
+++ b/usr.bin/xlint/lint1/externs1.h Sat Jan 23 22:20:17 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: externs1.h,v 1.60 2021/01/23 17:58:03 rillig Exp $ */
+/* $NetBSD: externs1.h,v 1.61 2021/01/23 22:20:17 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -205,7 +205,7 @@
extern sym_t *struct_or_union_member(tnode_t *, op_t, sym_t *);
extern tnode_t *build(op_t, tnode_t *, tnode_t *);
extern tnode_t *cconv(tnode_t *);
-extern bool is_strict_bool(const tnode_t *);
+extern bool is_typeok_bool_operand(const tnode_t *);
extern bool typeok(op_t, int, const tnode_t *, const tnode_t *);
extern tnode_t *promote(op_t, bool, tnode_t *);
extern tnode_t *convert(op_t, int, type_t *, tnode_t *);
diff -r f7820a3f46cd -r 891f6c04b30e usr.bin/xlint/lint1/func.c
--- a/usr.bin/xlint/lint1/func.c Sat Jan 23 20:00:19 2021 +0000
+++ b/usr.bin/xlint/lint1/func.c Sat Jan 23 22:20:17 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: func.c,v 1.64 2021/01/18 20:02:34 rillig Exp $ */
+/* $NetBSD: func.c,v 1.65 2021/01/23 22:20:17 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: func.c,v 1.64 2021/01/18 20:02:34 rillig Exp $");
+__RCSID("$NetBSD: func.c,v 1.65 2021/01/23 22:20:17 rillig Exp $");
#endif
#include <stdlib.h>
@@ -550,7 +550,7 @@
return NULL;
}
- if (tn != NULL && Tflag && !is_strict_bool(tn)) {
+ if (tn != NULL && Tflag && !is_typeok_bool_operand(tn)) {
/* controlling expression must be bool, not '%s' */
error(333, tspec_name(tn->tn_type->t_tspec));
return NULL;
diff -r f7820a3f46cd -r 891f6c04b30e usr.bin/xlint/lint1/lint1.h
--- a/usr.bin/xlint/lint1/lint1.h Sat Jan 23 20:00:19 2021 +0000
+++ b/usr.bin/xlint/lint1/lint1.h Sat Jan 23 22:20:17 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lint1.h,v 1.59 2021/01/18 19:24:09 rillig Exp $ */
+/* $NetBSD: lint1.h,v 1.60 2021/01/23 22:20:17 rillig Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@@ -288,6 +288,7 @@
bool tn_lvalue : 1; /* node is lvalue */
bool tn_cast : 1; /* if tn_op == CVT, it's an explicit cast */
bool tn_parenthesized : 1;
+ bool tn_from_system_header : 1;
union {
struct {
struct tnode *_tn_left; /* (left) operand */
diff -r f7820a3f46cd -r 891f6c04b30e usr.bin/xlint/lint1/mem1.c
--- a/usr.bin/xlint/lint1/mem1.c Sat Jan 23 20:00:19 2021 +0000
+++ b/usr.bin/xlint/lint1/mem1.c Sat Jan 23 22:20:17 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mem1.c,v 1.24 2021/01/18 20:02:34 rillig Exp $ */
+/* $NetBSD: mem1.c,v 1.25 2021/01/23 22:20:17 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: mem1.c,v 1.24 2021/01/18 20:02:34 rillig Exp $");
+__RCSID("$NetBSD: mem1.c,v 1.25 2021/01/23 22:20:17 rillig Exp $");
#endif
#include <sys/types.h>
@@ -348,13 +348,14 @@
}
/*
- * Get memory for a new tree node.
+ * Return a freshly allocated tree node.
*/
tnode_t *
getnode(void)
{
-
- return tgetblk(sizeof (tnode_t));
+ tnode_t *tn = tgetblk(sizeof *tn);
+ tn->tn_from_system_header = in_system_header;
+ return tn;
}
/*
diff -r f7820a3f46cd -r 891f6c04b30e usr.bin/xlint/lint1/tree.c
--- a/usr.bin/xlint/lint1/tree.c Sat Jan 23 20:00:19 2021 +0000
+++ b/usr.bin/xlint/lint1/tree.c Sat Jan 23 22:20:17 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tree.c,v 1.182 2021/01/18 20:02:34 rillig Exp $ */
+/* $NetBSD: tree.c,v 1.183 2021/01/23 22:20:17 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.182 2021/01/18 20:02:34 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.183 2021/01/23 22:20:17 rillig Exp $");
#endif
#include <float.h>
@@ -722,25 +722,24 @@
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. */
+/*
+ * See if the node is valid as operand of an operator that compares its
+ * argument with 0.
+ */
bool
-is_strict_bool(const tnode_t *tn)
+is_typeok_bool_operand(const tnode_t *tn)
{
tspec_t t;
+ lint_assert(Tflag);
+
tn = before_conversion(tn);
t = tn->tn_type->t_tspec;
- if (is_bool_compatible(t, tn))
+ if (t == BOOL)
+ return true;
+
+ if (tn->tn_from_system_header && is_scalar(t))
return true;
/* For enums that are used as bit sets, allow "flags & FLAG". */
@@ -1101,18 +1100,54 @@
}
/*
- * Whether the operator can handle (bool, bool) as well as (scalar, scalar),
- * but not mixtures between the two type classes.
+ * See if in strict bool mode, the operator takes either two bool operands
+ * or two arbitrary other operands.
*/
static bool
-needs_compatible_types(op_t op)
+is_assignment_bool_or_other(op_t op)
+{
+ return op == ASSIGN ||
+ op == ANDASS || op == XORASS || op == ORASS ||
+ op == RETURN || op == FARG;
+}
+
+static bool
+is_symmetric_bool_or_other(op_t op)
{
return op == EQ || op == NE ||
op == BITAND || op == BITXOR || op == BITOR ||
- op == COLON ||
- op == ASSIGN || op == ANDASS || op == XORASS || op == ORASS ||
- op == RETURN ||
- op == FARG;
+ op == COLON;
+}
+
+static bool
+is_bool_int_constant(const tnode_t *tn, tspec_t t)
+{
+ return t == INT &&
+ tn->tn_from_system_header &&
+ tn->tn_op == CON &&
+ (tn->tn_val->v_quad == 0 || tn->tn_val->v_quad == 1);
+}
+
+static bool
+is_typeok_strict_bool(op_t op,
+ const tnode_t *ln, tspec_t lt,
+ const tnode_t *rn, tspec_t rt)
+{
+ if (rn == NULL)
+ return true; /* TODO: check unary operators as well. */
+
+ if ((lt == BOOL) == (rt == BOOL))
+ return true;
+
+ if (is_bool_int_constant(ln, lt) || is_bool_int_constant(rn, rt))
+ return true;
+
+ if (is_assignment_bool_or_other(op)) {
+ return lt != BOOL &&
+ (ln->tn_from_system_header || rn->tn_from_system_header);
+ }
+
+ return !is_symmetric_bool_or_other(op);
}
/*
@@ -1129,9 +1164,7 @@
const tnode_t *rn, tspec_t rt)
{
- if (!needs_compatible_types(op))
- return true;
- if (is_bool_compatible(lt, ln) == is_bool_compatible(rt, rn))
+ if (is_typeok_strict_bool(op, ln, lt, rn, rt))
return true;
if (op == FARG) {
@@ -1175,7 +1208,7 @@
if (mp->m_requires_bool || op == QUEST) {
bool binary = mp->m_binary;
- bool lbool = is_strict_bool(ln);
+ bool lbool = is_typeok_bool_operand(ln);
bool ok = true;
if (!binary && !lbool) {
@@ -1188,7 +1221,7 @@
error(331, getopname(op), tspec_name(lt));
ok = false;
}
- if (binary && op != QUEST && !is_strict_bool(rn)) {
+ if (binary && op != QUEST && !is_typeok_bool_operand(rn)) {
/* right operand of '%s' must be bool, not '%s' */
error(332, getopname(op), tspec_name(rt));
ok = false;
@@ -1521,7 +1554,7 @@
if (lt == BOOL && is_scalar(rt)) /* C99 6.3.1.2 */
return true;
- if (is_arithmetic(lt) && is_arithmetic(rt))
+ if (is_arithmetic(lt) && (is_arithmetic(rt) || rt == BOOL))
return true;
if ((lt == STRUCT || lt == UNION) && (rt == STRUCT || rt == UNION))
@@ -1773,6 +1806,10 @@
ntn->tn_op = op;
ntn->tn_type = type;
+ if (ln->tn_from_system_header)
+ ntn->tn_from_system_header = true;
+ if (rn != NULL && rn->tn_from_system_header)
+ ntn->tn_from_system_header = true;
ntn->tn_left = ln;
ntn->tn_right = rn;
Home |
Main Index |
Thread Index |
Old Index