Module Name: src
Committed By: rillig
Date: Sun Jun 9 10:27:39 UTC 2024
Modified Files:
src/distrib/sets/lists/tests: mi
src/tests/usr.bin/xlint/lint1: init_c99.c msg_259.c msg_298.c
t_usage.sh
src/usr.bin/xlint/lint1: err.c tree.c
Added Files:
src/tests/usr.bin/xlint/lint1: msg_380.c msg_381.c
Log Message:
lint: warn about lossy floating point constant to integer conversions
To generate a diff of this commit:
cvs rdiff -u -r1.1318 -r1.1319 src/distrib/sets/lists/tests/mi
cvs rdiff -u -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/init_c99.c
cvs rdiff -u -r1.24 -r1.25 src/tests/usr.bin/xlint/lint1/msg_259.c
cvs rdiff -u -r1.6 -r1.7 src/tests/usr.bin/xlint/lint1/msg_298.c
cvs rdiff -u -r0 -r1.1 src/tests/usr.bin/xlint/lint1/msg_380.c \
src/tests/usr.bin/xlint/lint1/msg_381.c
cvs rdiff -u -r1.21 -r1.22 src/tests/usr.bin/xlint/lint1/t_usage.sh
cvs rdiff -u -r1.245 -r1.246 src/usr.bin/xlint/lint1/err.c
cvs rdiff -u -r1.645 -r1.646 src/usr.bin/xlint/lint1/tree.c
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.1318 src/distrib/sets/lists/tests/mi:1.1319
--- src/distrib/sets/lists/tests/mi:1.1318 Sat Jun 8 13:50:47 2024
+++ src/distrib/sets/lists/tests/mi Sun Jun 9 10:27:39 2024
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1318 2024/06/08 13:50:47 rillig Exp $
+# $NetBSD: mi,v 1.1319 2024/06/09 10:27:39 rillig Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@@ -7515,6 +7515,8 @@
./usr/tests/usr.bin/xlint/lint1/msg_377.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/xlint/lint1/msg_378.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/xlint/lint1/msg_379.c tests-usr.bin-tests compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_380.c tests-usr.bin-tests compattestfile,atf
+./usr/tests/usr.bin/xlint/lint1/msg_381.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/xlint/lint1/op_colon.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/xlint/lint1/op_colon.exp tests-obsolete obsolete,atf
./usr/tests/usr.bin/xlint/lint1/op_shl_lp64.c tests-usr.bin-tests compattestfile,atf
Index: src/tests/usr.bin/xlint/lint1/init_c99.c
diff -u src/tests/usr.bin/xlint/lint1/init_c99.c:1.1 src/tests/usr.bin/xlint/lint1/init_c99.c:1.2
--- src/tests/usr.bin/xlint/lint1/init_c99.c:1.1 Sat Jun 8 13:50:47 2024
+++ src/tests/usr.bin/xlint/lint1/init_c99.c Sun Jun 9 10:27:39 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: init_c99.c,v 1.1 2024/06/08 13:50:47 rillig Exp $ */
+/* $NetBSD: init_c99.c,v 1.2 2024/06/09 10:27:39 rillig Exp $ */
# 3 "init_c99.c"
// Tests for initialization in C99 or later, mainly for designators.
@@ -290,6 +290,7 @@ struct ten ten = {
* covering all tricky edge cases.
*/
+/* expect+1: warning: lossy conversion of 3.5 to 'int' [381] */
int c99_6_7_8_p24_example1_i = 3.5;
double _Complex c99_6_7_8_p24_example1_c = 5 + 3 * 1.0fi;
Index: src/tests/usr.bin/xlint/lint1/msg_259.c
diff -u src/tests/usr.bin/xlint/lint1/msg_259.c:1.24 src/tests/usr.bin/xlint/lint1/msg_259.c:1.25
--- src/tests/usr.bin/xlint/lint1/msg_259.c:1.24 Sat Jun 8 13:50:47 2024
+++ src/tests/usr.bin/xlint/lint1/msg_259.c Sun Jun 9 10:27:39 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: msg_259.c,v 1.24 2024/06/08 13:50:47 rillig Exp $ */
+/* $NetBSD: msg_259.c,v 1.25 2024/06/09 10:27:39 rillig Exp $ */
# 3 "msg_259.c"
// Test for message: argument %d is converted from '%s' to '%s' due to prototype [259]
@@ -236,7 +236,8 @@ constants(void)
/* expect+2: warning: argument 1 is converted from 'long long' to 'unsigned int' due to prototype [259] */
/* expect+1: warning: conversion of 'long long' to 'unsigned int' is out of range, arg #1 [295] */
unsigned_int(0x7fffffffffffffffLL);
- /* expect+1: warning: argument 1 is converted from 'double' to 'unsigned int' due to prototype [259] */
+ /* expect+2: warning: argument 1 is converted from 'double' to 'unsigned int' due to prototype [259] */
+ /* expect+1: warning: lossy conversion of 2.1 to 'unsigned int', arg #1 [380] */
unsigned_int(2.1);
}
Index: src/tests/usr.bin/xlint/lint1/msg_298.c
diff -u src/tests/usr.bin/xlint/lint1/msg_298.c:1.6 src/tests/usr.bin/xlint/lint1/msg_298.c:1.7
--- src/tests/usr.bin/xlint/lint1/msg_298.c:1.6 Sat Jun 8 13:50:47 2024
+++ src/tests/usr.bin/xlint/lint1/msg_298.c Sun Jun 9 10:27:39 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: msg_298.c,v 1.6 2024/06/08 13:50:47 rillig Exp $ */
+/* $NetBSD: msg_298.c,v 1.7 2024/06/09 10:27:39 rillig Exp $ */
# 3 "msg_298.c"
// Test for message: conversion from '%s' to '%s' may lose accuracy, arg #%d [298]
@@ -22,9 +22,4 @@ convert_bit_and(long l)
take_schar(l & 0x7F);
}
-void
-convert_floating_to_integer(void)
-{
- // TODO: warn about lossy conversion.
- take_uint(2.1);
-}
+// For lossy floating-to-integer conversions, see messages 380 and 381.
Index: src/tests/usr.bin/xlint/lint1/t_usage.sh
diff -u src/tests/usr.bin/xlint/lint1/t_usage.sh:1.21 src/tests/usr.bin/xlint/lint1/t_usage.sh:1.22
--- src/tests/usr.bin/xlint/lint1/t_usage.sh:1.21 Sat May 11 15:53:38 2024
+++ src/tests/usr.bin/xlint/lint1/t_usage.sh Sun Jun 9 10:27:39 2024
@@ -1,4 +1,4 @@
-# $NetBSD: t_usage.sh,v 1.21 2024/05/11 15:53:38 rillig Exp $
+# $NetBSD: t_usage.sh,v 1.22 2024/06/09 10:27:39 rillig Exp $
#
# Copyright (c) 2023 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -39,13 +39,13 @@ suppress_messages_body()
# The largest known message.
atf_check \
- "$lint1" -X 379 code.c /dev/null
+ "$lint1" -X 381 code.c /dev/null
# Larger than the largest known message.
atf_check \
-s 'exit:1' \
- -e "inline:lint1: invalid message ID '380'\n" \
- "$lint1" -X 380 code.c /dev/null
+ -e "inline:lint1: invalid message ID '382'\n" \
+ "$lint1" -X 382 code.c /dev/null
# Whitespace is not allowed before a message ID.
atf_check \
Index: src/usr.bin/xlint/lint1/err.c
diff -u src/usr.bin/xlint/lint1/err.c:1.245 src/usr.bin/xlint/lint1/err.c:1.246
--- src/usr.bin/xlint/lint1/err.c:1.245 Sat Jun 8 06:37:06 2024
+++ src/usr.bin/xlint/lint1/err.c Sun Jun 9 10:27:39 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: err.c,v 1.245 2024/06/08 06:37:06 rillig Exp $ */
+/* $NetBSD: err.c,v 1.246 2024/06/09 10:27:39 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: err.c,v 1.245 2024/06/08 06:37:06 rillig Exp $");
+__RCSID("$NetBSD: err.c,v 1.246 2024/06/09 10:27:39 rillig Exp $");
#endif
#include <limits.h>
@@ -435,6 +435,8 @@ static const char *const msgs[] = {
"redundant '\\0' at the end of the format", // 377
"conversion '%.*s' is unreachable by input value", // 378
"comparing integer '%s' to floating point constant %Lg", // 379
+ "lossy conversion of %Lg to '%s', arg #%d", // 380
+ "lossy conversion of %Lg to '%s'", // 381
};
static bool is_suppressed[sizeof(msgs) / sizeof(msgs[0])];
Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.645 src/usr.bin/xlint/lint1/tree.c:1.646
--- src/usr.bin/xlint/lint1/tree.c:1.645 Sat Jun 8 11:55:40 2024
+++ src/usr.bin/xlint/lint1/tree.c Sun Jun 9 10:27:39 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: tree.c,v 1.645 2024/06/08 11:55:40 rillig Exp $ */
+/* $NetBSD: tree.c,v 1.646 2024/06/09 10:27:39 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: tree.c,v 1.645 2024/06/08 11:55:40 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.646 2024/06/09 10:27:39 rillig Exp $");
#endif
#include <float.h>
@@ -3289,7 +3289,26 @@ promote(op_t op, bool farg, tnode_t *tn)
}
static void
-convert_integer_from_floating(op_t op, const type_t *tp, const tnode_t *tn)
+check_lossy_floating_to_integer_conversion(
+ op_t op, int arg, const type_t *tp, const tnode_t *tn)
+{
+ long double x = tn->u.value.u.floating;
+ integer_constraints ic = ic_any(tp);
+ if (is_uinteger(tp->t_tspec)
+ ? x >= ic.umin && x <= ic.umax && x == (uint64_t)x
+ : x >= ic.smin && x <= ic.smax && x == (int64_t)x)
+ return;
+ if (op == FARG)
+ /* lossy conversion of %Lg to '%s', arg #%d */
+ warning(380, x, type_name(tp), arg);
+ else
+ /* lossy conversion of %Lg to '%s' */
+ warning(381, x, type_name(tp));
+}
+
+static void
+convert_integer_from_floating(
+ op_t op, int arg, const type_t *tp, const tnode_t *tn)
{
if (op == CVT)
@@ -3298,6 +3317,8 @@ convert_integer_from_floating(op_t op, c
else
/* implicit conversion from floating point '%s' to ... */
query_message(1, type_name(tn->tn_type), type_name(tp));
+ if (tn->tn_op == CON)
+ check_lossy_floating_to_integer_conversion(op, arg, tp, tn);
}
static bool
@@ -3649,7 +3670,7 @@ convert(op_t op, int arg, type_t *tp, tn
} else if (is_integer(ot))
convert_integer_from_integer(op, arg, nt, ot, tp, tn);
else if (is_floating(ot))
- convert_integer_from_floating(op, tp, tn);
+ convert_integer_from_floating(op, arg, tp, tn);
else if (ot == PTR)
convert_integer_from_pointer(op, nt, tp, tn);
@@ -3731,12 +3752,15 @@ convert_constant_from_floating(op_t op,
lint_assert(nt != LDOUBLE);
const char *ot_name = type_name(gettyp(ov->v_tspec));
const char *nt_name = type_name(ntp);
+ if (is_integer(nt))
+ goto after_warning;
if (op == FARG)
/* conversion of '%s' to '%s' is out of range, ... */
warning(295, ot_name, nt_name, arg);
else
/* conversion of '%s' to '%s' is out of range */
warning(119, ot_name, nt_name);
+ after_warning:
ov->u.floating = ov->u.floating > 0 ? max : min;
}
Added files:
Index: src/tests/usr.bin/xlint/lint1/msg_380.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_380.c:1.1
--- /dev/null Sun Jun 9 10:27:39 2024
+++ src/tests/usr.bin/xlint/lint1/msg_380.c Sun Jun 9 10:27:39 2024
@@ -0,0 +1,60 @@
+/* $NetBSD: msg_380.c,v 1.1 2024/06/09 10:27:39 rillig Exp $ */
+# 3 "msg_380.c"
+
+// Test for message: lossy conversion of %Lg to '%s', arg #%d [380]
+
+/* lint1-extra-flags: -X 351 */
+
+void take_s32(int);
+void take_u32(unsigned int);
+void take_s64(long long);
+void take_u64(unsigned long long);
+
+void
+conversions(void)
+{
+ /* expect+1: warning: lossy conversion of -2.14748e+09 to 'int', arg #1 [380] */
+ take_s32(-2147483649.0);
+ take_s32(-2147483648.0);
+ /* expect+1: warning: lossy conversion of 3.141 to 'int', arg #1 [380] */
+ take_s32(3.141);
+ take_s32(2147483647.0);
+ /* expect+1: warning: lossy conversion of 2.14748e+09 to 'int', arg #1 [380] */
+ take_s32(2147483648.0);
+
+ /* expect+1: warning: lossy conversion of -1 to 'unsigned int', arg #1 [380] */
+ take_u32(-1.0);
+ take_u32(-0.0);
+ take_u32(0.0);
+ /* expect+1: warning: lossy conversion of 3.141 to 'unsigned int', arg #1 [380] */
+ take_u32(3.141);
+ take_u32(4294967295.0);
+ /* expect+1: warning: lossy conversion of 4.29497e+09 to 'unsigned int', arg #1 [380] */
+ take_u32(4294967296.0);
+
+ /* expect+1: warning: lossy conversion of -9.22337e+18 to 'long long', arg #1 [380] */
+ take_s64(-9223372036854776833.0);
+ /* The constant ...809 is rounded down to ...808, thus no warning. */
+ take_s64(-9223372036854775809.0);
+ take_s64(-9223372036854775808.0);
+ /* expect+1: warning: lossy conversion of 3.141 to 'long long', arg #1 [380] */
+ take_s64(3.141);
+ /* expect+1: warning: lossy conversion of 9.22337e+18 to 'long long', arg #1 [380] */
+ take_s64(9223372036854775807.0);
+ /* expect+1: warning: lossy conversion of 9.22337e+18 to 'long long', arg #1 [380] */
+ take_s64(9223372036854775808.0);
+
+ /* expect+1: warning: lossy conversion of -1 to 'unsigned long long', arg #1 [380] */
+ take_u64(-1.0);
+ take_u64(-0.0);
+ take_u64(0.0);
+ /* expect+1: warning: lossy conversion of 3.141 to 'unsigned long long', arg #1 [380] */
+ take_u64(3.141);
+ take_u64(18446744073709550591.0);
+ /* expect+1: warning: lossy conversion of 1.84467e+19 to 'unsigned long long', arg #1 [380] */
+ take_u64(18446744073709550592.0);
+ /* expect+1: warning: lossy conversion of 1.84467e+19 to 'unsigned long long', arg #1 [380] */
+ take_u64(18446744073709551615.0);
+ /* expect+1: warning: lossy conversion of 1.84467e+19 to 'unsigned long long', arg #1 [380] */
+ take_u64(18446744073709551616.0);
+}
Index: src/tests/usr.bin/xlint/lint1/msg_381.c
diff -u /dev/null src/tests/usr.bin/xlint/lint1/msg_381.c:1.1
--- /dev/null Sun Jun 9 10:27:39 2024
+++ src/tests/usr.bin/xlint/lint1/msg_381.c Sun Jun 9 10:27:39 2024
@@ -0,0 +1,60 @@
+/* $NetBSD: msg_381.c,v 1.1 2024/06/09 10:27:39 rillig Exp $ */
+# 3 "msg_381.c"
+
+// Test for message: lossy conversion of %Lg to '%s' [381]
+
+/* lint1-extra-flags: -X 351 */
+
+int s32;
+unsigned int u32;
+long long s64;
+unsigned long long u64;
+
+void
+conversions(void)
+{
+ /* expect+1: warning: lossy conversion of -2.14748e+09 to 'int' [381] */
+ s32 = -2147483649.0;
+ s32 = -2147483648.0;
+ /* expect+1: warning: lossy conversion of 3.141 to 'int' [381] */
+ s32 = 3.141;
+ s32 = 2147483647.0;
+ /* expect+1: warning: lossy conversion of 2.14748e+09 to 'int' [381] */
+ s32 = 2147483648.0;
+
+ /* expect+1: warning: lossy conversion of -1 to 'unsigned int' [381] */
+ u32 = -1.0;
+ u32 = -0.0;
+ u32 = 0.0;
+ /* expect+1: warning: lossy conversion of 3.141 to 'unsigned int' [381] */
+ u32 = 3.141;
+ u32 = 4294967295.0;
+ /* expect+1: warning: lossy conversion of 4.29497e+09 to 'unsigned int' [381] */
+ u32 = 4294967296.0;
+
+ /* expect+1: warning: lossy conversion of -9.22337e+18 to 'long long' [381] */
+ s64 = -9223372036854776833.0;
+ /* The constant ...809 is rounded down to ...808, thus no warning. */
+ s64 = -9223372036854775809.0;
+ s64 = -9223372036854775808.0;
+ /* expect+1: warning: lossy conversion of 3.141 to 'long long' [381] */
+ s64 = 3.141;
+ /* expect+1: warning: lossy conversion of 9.22337e+18 to 'long long' [381] */
+ s64 = 9223372036854775807.0;
+ /* expect+1: warning: lossy conversion of 9.22337e+18 to 'long long' [381] */
+ s64 = 9223372036854775808.0;
+
+ /* expect+1: warning: lossy conversion of -1 to 'unsigned long long' [381] */
+ u64 = -1.0;
+ u64 = -0.0;
+ u64 = 0.0;
+ /* expect+1: warning: lossy conversion of 3.141 to 'unsigned long long' [381] */
+ u64 = 3.141;
+ u64 = 18446744073709550591.0;
+ /* expect+1: warning: lossy conversion of 1.84467e+19 to 'unsigned long long' [381] */
+ u64 = 18446744073709550592.0;
+ /* expect+1: warning: lossy conversion of 1.84467e+19 to 'unsigned long long' [381] */
+ u64 = 18446744073709551615.0;
+ /* expect+1: warning: lossy conversion of 1.84467e+19 to 'unsigned long long' [381] */
+ u64 = 18446744073709551616.0;
+}