Module Name: src
Committed By: rillig
Date: Tue Oct 8 19:50:50 UTC 2024
Modified Files:
src/tests/usr.bin/xlint/lint1: msg_132.c
src/usr.bin/xlint/lint1: tree.c
Log Message:
lint: compute integer constraints for unsigned multiplication
This fixes the wrong warning about possible loss of accuracy in
libc/c16rtomb.
To generate a diff of this commit:
cvs rdiff -u -r1.43 -r1.44 src/tests/usr.bin/xlint/lint1/msg_132.c
cvs rdiff -u -r1.652 -r1.653 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/tests/usr.bin/xlint/lint1/msg_132.c
diff -u src/tests/usr.bin/xlint/lint1/msg_132.c:1.43 src/tests/usr.bin/xlint/lint1/msg_132.c:1.44
--- src/tests/usr.bin/xlint/lint1/msg_132.c:1.43 Tue Oct 8 19:39:54 2024
+++ src/tests/usr.bin/xlint/lint1/msg_132.c Tue Oct 8 19:50:49 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: msg_132.c,v 1.43 2024/10/08 19:39:54 rillig Exp $ */
+/* $NetBSD: msg_132.c,v 1.44 2024/10/08 19:50:49 rillig Exp $ */
# 3 "msg_132.c"
// Test for message: conversion from '%s' to '%s' may lose accuracy [132]
@@ -236,19 +236,15 @@ be32enc(void *buf, u32_t u)
void
test_ic_mult(void)
{
- /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
- u32 = u16 * 65536ULL;
- /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
u32 = u16 * 65537ULL;
+ /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
+ u32 = u16 * 65538ULL;
- /* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
u16 = 0 * u16;
- /* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
u16 = 1 * u16;
/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
u16 = 2 * u16;
- /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
u32 = (u16 & 1023ULL) / 1ULL * 1024ULL | (u16 & 1023ULL) / 1ULL * 1ULL;
}
Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.652 src/usr.bin/xlint/lint1/tree.c:1.653
--- src/usr.bin/xlint/lint1/tree.c:1.652 Sat Sep 28 19:09:37 2024
+++ src/usr.bin/xlint/lint1/tree.c Tue Oct 8 19:50:49 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: tree.c,v 1.652 2024/09/28 19:09:37 rillig Exp $ */
+/* $NetBSD: tree.c,v 1.653 2024/10/08 19:50:49 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.652 2024/09/28 19:09:37 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.653 2024/10/08 19:50:49 rillig Exp $");
#endif
#include <float.h>
@@ -161,6 +161,23 @@ ic_cvt(const type_t *ntp, const type_t *
}
static integer_constraints
+ic_mult(const type_t *tp, integer_constraints a, integer_constraints b)
+{
+ integer_constraints c;
+
+ if (ic_maybe_signed(tp, &a) || ic_maybe_signed(tp, &b)
+ || (a.umax > 0 && b.umax > ic_any(tp).umax / a.umax))
+ return ic_any(tp);
+
+ c.smin = INT64_MIN;
+ c.smax = INT64_MAX;
+ c.umin = a.umin * b.umin;
+ c.umax = a.umax * b.umax;
+ c.bclr = ~u64_fill_right(c.umax);
+ return c;
+}
+
+static integer_constraints
ic_bitand(integer_constraints a, integer_constraints b)
{
integer_constraints c;
@@ -294,6 +311,10 @@ ic_expr(const tnode_t *tn)
return ic_any(tn->tn_type);
lc = ic_expr(tn->u.ops.left);
return ic_cvt(tn->tn_type, tn->u.ops.left->tn_type, lc);
+ case MULT:
+ lc = ic_expr(before_conversion(tn->u.ops.left));
+ rc = ic_expr(before_conversion(tn->u.ops.right));
+ return ic_mult(tn->tn_type, lc, rc);
case DIV:
lc = ic_expr(before_conversion(tn->u.ops.left));
rc = ic_expr(before_conversion(tn->u.ops.right));