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: do not warn about 'may lose accura...
details: https://anonhg.NetBSD.org/src/rev/34751433e383
branches: trunk
changeset: 368363:34751433e383
user: rillig <rillig%NetBSD.org@localhost>
date: Wed Jul 06 22:26:30 2022 +0000
description:
lint: do not warn about 'may lose accuracy' in safe cases of '%'
The possible values of the expression 'a % b' for unsigned integers lie
between 0 and (b - 1). For signed integers, it's more complicated, so
ignore them for now.
diffstat:
tests/usr.bin/xlint/lint1/msg_132.c | 27 +++++++++++++++++++++------
usr.bin/xlint/lint1/tree.c | 37 +++++++++++++++++++++++++++++++++++--
2 files changed, 56 insertions(+), 8 deletions(-)
diffs (129 lines):
diff -r b6142508ebb8 -r 34751433e383 tests/usr.bin/xlint/lint1/msg_132.c
--- a/tests/usr.bin/xlint/lint1/msg_132.c Wed Jul 06 21:59:06 2022 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_132.c Wed Jul 06 22:26:30 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: msg_132.c,v 1.22 2022/07/06 21:59:06 rillig Exp $ */
+/* $NetBSD: msg_132.c,v 1.23 2022/07/06 22:26:31 rillig Exp $ */
# 3 "msg_132.c"
// Test for message: conversion from '%s' to '%s' may lose accuracy [132]
@@ -290,18 +290,22 @@
test_ic_mod(void)
{
/* The result is between 0 and 254. */
+ u8 = u64 % u8;
+
+ /* The result is between 0 and 255. */
+ u8 = u64 % 256;
+
+ /* The result is between 0 and 256. */
/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
- u8 = u64 % u8;
+ u8 = u64 % 257;
/* The result is between 0 and 1000. */
/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
u8 = u64 % 1000;
- /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned short' may lose accuracy [132] */
- u16 = u64 % 1000;
/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int:9' may lose accuracy [132] */
bits.u9 = u64 % 1000;
- /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int:10' may lose accuracy [132] */
bits.u10 = u64 % 1000;
+ u16 = u64 % 1000;
/*
* For signed division, if the result of 'a / b' is not representable
@@ -309,8 +313,19 @@
* '(a / b) * a + a % b == a'.
*
* If the result of 'a / b' is not representable exactly, the result
- * of 'a % b' is not defined.
+ * of 'a % b' is not defined. Due to this uncertainty, lint does not
+ * narrow down the range for signed modulo expressions.
*
* C90 6.3.5, C99 6.5.5.
*/
+
+ /* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
+ s8 = s16 % s8;
+
+ /*
+ * The result is always 0, it's a theoretical edge case though, so
+ * lint doesn't care to implement this.
+ */
+ /* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
+ s8 = s64 % 1;
}
diff -r b6142508ebb8 -r 34751433e383 usr.bin/xlint/lint1/tree.c
--- a/usr.bin/xlint/lint1/tree.c Wed Jul 06 21:59:06 2022 +0000
+++ b/usr.bin/xlint/lint1/tree.c Wed Jul 06 22:26:30 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tree.c,v 1.471 2022/07/05 22:50:41 rillig Exp $ */
+/* $NetBSD: tree.c,v 1.472 2022/07/06 22:26:30 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.471 2022/07/05 22:50:41 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.472 2022/07/06 22:26:30 rillig Exp $");
#endif
#include <float.h>
@@ -104,6 +104,18 @@
extern sig_atomic_t fpe;
+static uint64_t
+u64_fill_right(uint64_t x)
+{
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ x |= x >> 32;
+ return x;
+}
+
static bool
ic_maybe_signed(const type_t *tp, const integer_constraints *ic)
{
@@ -200,6 +212,23 @@
}
static integer_constraints
+ic_mod(const type_t *tp, integer_constraints a, integer_constraints b)
+{
+ integer_constraints c;
+
+ if (ic_maybe_signed(tp, &a) || ic_maybe_signed(tp, &b))
+ return ic_any(tp);
+
+ c.smin = INT64_MIN;
+ c.smax = INT64_MAX;
+ c.umin = 0;
+ c.umax = b.umax - 1;
+ c.bset = 0;
+ c.bclr = ~u64_fill_right(c.umax);
+ return c;
+}
+
+static integer_constraints
ic_shl(const type_t *tp, integer_constraints a, integer_constraints b)
{
integer_constraints c;
@@ -264,6 +293,10 @@
return ic_any(tn->tn_type);
lc = ic_expr(tn->tn_left);
return ic_cvt(tn->tn_type, tn->tn_left->tn_type, lc);
+ case MOD:
+ lc = ic_expr(before_conversion(tn->tn_left));
+ rc = ic_expr(before_conversion(tn->tn_right));
+ return ic_mod(tn->tn_type, lc, rc);
case SHL:
lc = ic_expr(tn->tn_left);
rc = ic_expr(tn->tn_right);
Home |
Main Index |
Thread Index |
Old Index