lint: explain why !finite(x) is not allowed in strict bool mode

This commit is contained in:
rillig 2021-01-24 07:58:48 +00:00
parent 5eadbc3ac1
commit 378eb7af09
3 changed files with 46 additions and 12 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: d_c99_bool_strict_syshdr.c,v 1.6 2021/01/23 23:11:40 rillig Exp $ */
/* $NetBSD: d_c99_bool_strict_syshdr.c,v 1.7 2021/01/24 07:58:48 rillig Exp $ */
# 3 "d_c99_bool_strict_syshdr.c"
/*
@ -122,17 +122,50 @@ ch_isspace_sys_bool(char c)
}
/*
* If a function from a system header has return type int, which has
* traditionally been used for the missing type bool, it may be used
* in controlling expressions.
* There are several functions from system headers that have return type
* int. For this return type there are many API conventions:
*
* * isspace: 0 means no, non-zero means yes
* * open: 0 means success, -1 means failure
* * main: 0 means success, non-zero means failure
* * strcmp: 0 means equal, < 0 means less than, > 0 means greater than
*
* Without a detailed list of individual functions, it's not possible to
* guess what the return value means. Therefore in strict bool mode, the
* return value of these functions cannot be implicitly converted to bool,
* not even in a context where the result is compared to 0. Allowing that
* would allow expressions like !strcmp(s1, s2), which is not correct since
* strcmp returns an "ordered comparison result", not a bool.
*/
# 1 "math.h" 3 4
extern int finite(double);
# 133 "d_c99_bool_strict_syshdr.c"
# 1 "string.h" 3 4
extern int strcmp(const char *, const char *);
# 146 "d_c99_bool_strict_syshdr.c"
/*ARGSUSED*/
_Bool
call_finite_bad(double d)
{
return finite(d); /* expect: 211 */
}
_Bool
call_finite(double d) /*FIXME*//* expect: 231 */
call_finite_good(double d)
{
return finite(d); /*FIXME*//* expect: 211 */
return finite(d) != 0;
}
/*ARGSUSED*/
_Bool
str_equal_bad(const char *s1, const char *s2)
{
return !strcmp(s1, s2); /* expect: 330, 214 */
}
_Bool
str_equal_good(const char *s1, const char *s2)
{
return strcmp(s1, s2) == 0;
}

View File

@ -1,5 +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(137): return value type mismatch (_Bool) and (int) [211]
d_c99_bool_strict_syshdr.c(135): warning: argument d unused in function call_finite [231]
d_c99_bool_strict_syshdr.c(151): return value type mismatch (_Bool) and (int) [211]
d_c99_bool_strict_syshdr.c(164): operand of '!' must be bool, not 'int' [330]
d_c99_bool_strict_syshdr.c(164): warning: function str_equal_bad expects to return value [214]

View File

@ -1,4 +1,4 @@
/* $NetBSD: lex.c,v 1.4 2021/01/24 00:02:38 christos Exp $ */
/* $NetBSD: lex.c,v 1.5 2021/01/24 07:58:48 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: lex.c,v 1.4 2021/01/24 00:02:38 christos Exp $");
__RCSID("$NetBSD: lex.c,v 1.5 2021/01/24 07:58:48 rillig Exp $");
#endif
#include <ctype.h>
@ -770,7 +770,7 @@ lex_fcon(const char *yytext, size_t yyleng)
if (typ == FLOAT) {
f = (float)d;
if (!finite(f)) {
if (finite(f) == 0) {
/* floating-point constant out of range */
warning(248);
f = f > 0 ? FLT_MAX : -FLT_MAX;