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));

Reply via email to