Module Name:    src
Committed By:   rillig
Date:           Sun Mar 10 10:15:52 UTC 2024

Modified Files:
        src/tests/usr.bin/xlint/lint1: msg_141.c
        src/usr.bin/xlint/lint1: tree.c

Log Message:
lint: fix integer overflow in integer overflow check


To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/tests/usr.bin/xlint/lint1/msg_141.c
cvs rdiff -u -r1.615 -r1.616 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_141.c
diff -u src/tests/usr.bin/xlint/lint1/msg_141.c:1.11 src/tests/usr.bin/xlint/lint1/msg_141.c:1.12
--- src/tests/usr.bin/xlint/lint1/msg_141.c:1.11	Sun Mar 10 09:58:30 2024
+++ src/tests/usr.bin/xlint/lint1/msg_141.c	Sun Mar 10 10:15:52 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg_141.c,v 1.11 2024/03/10 09:58:30 rillig Exp $	*/
+/*	$NetBSD: msg_141.c,v 1.12 2024/03/10 10:15:52 rillig Exp $	*/
 # 3 "msg_141.c"
 
 // Test for message: operator '%s' produces integer overflow [141]
@@ -162,26 +162,26 @@ mult_u32(void)
 void
 mult_s64(void)
 {
-	/* TODO: expect+1: warning: operator '*' produces integer overflow [141] */
-	//s64 = -0x100000000LL * 0x100000000LL;	// -0x010000000000000000
-	/* TODO: expect+1: warning: operator '*' produces integer overflow [141] */
-	//s64 = -3LL * 0x2aaaaaaaaaaaaaabLL;	// -0x8000000000000001
-	/* TODO: expect+1: warning: operator '*' produces integer overflow [141] */
-	//s64 = 0x2aaaaaaaaaaaaaabLL * -3LL;	// -0x8000000000000001
+	/* expect+1: warning: operator '*' produces integer overflow [141] */
+	s64 = -0x100000000LL * 0x100000000LL;	// -0x010000000000000000
+	/* expect+1: warning: operator '*' produces integer overflow [141] */
+	s64 = -3LL * 0x2aaaaaaaaaaaaaabLL;	// -0x8000000000000001
+	/* expect+1: warning: operator '*' produces integer overflow [141] */
+	s64 = 0x2aaaaaaaaaaaaaabLL * -3LL;	// -0x8000000000000001
 	s64 = -8LL * +0x1000000000000000LL;	// -0x8000000000000000
 	s64 = +0x1000000000000000LL * -8LL;	// -0x8000000000000000
 	s64 = +2LL * +0x3fffffffffffffffLL;	// +0x7ffffffffffffffe
 	s64 = +0x3fffffffffffffffLL * +2LL;	// +0x7ffffffffffffffe
 	s64 = +0x7fffffffffffffffLL * +1LL;	// +0x7fffffffffffffff
 	s64 = +1LL * +0x7fffffffffffffffLL;	// +0x7fffffffffffffff
-	/* TODO: expect+1: warning: operator '*' produces integer overflow [141] */
-	//s64 = +2LL * +0x4000000000000000LL;	// +0x8000000000000000
-	/* TODO: expect+1: warning: operator '*' produces integer overflow [141] */
-	//s64 = +0x4000000000000000LL * +2LL;	// +0x8000000000000000
-	/* TODO: expect+1: warning: operator '*' produces integer overflow [141] */
-	//s64 = +0xffffffffLL * +0x100000001LL;	// +0xffffffffffffffff
-	/* TODO: expect+1: warning: operator '*' produces integer overflow [141] */
-	//s64 = +0x100000000LL * +0x100000000LL;	// +0x010000000000000000
+	/* expect+1: warning: operator '*' produces integer overflow [141] */
+	s64 = +2LL * +0x4000000000000000LL;	// +0x8000000000000000
+	/* expect+1: warning: operator '*' produces integer overflow [141] */
+	s64 = +0x4000000000000000LL * +2LL;	// +0x8000000000000000
+	/* expect+1: warning: operator '*' produces integer overflow [141] */
+	s64 = +0xffffffffLL * +0x100000001LL;	// +0xffffffffffffffff
+	/* expect+1: warning: operator '*' produces integer overflow [141] */
+	s64 = +0x100000000LL * +0x100000000LL;	// +0x010000000000000000
 }
 
 void
@@ -249,6 +249,7 @@ mod_s32(void)
 {
 	s32 = -1 % (-0x7fffffff - 1);
 	s32 = -1 % 0x7fffffff;
+	/* expect+1: warning: operator '%' produces integer overflow [141] */
 	s32 = (-0x7fffffff - 1) % -1;
 	s32 = 0x7fffffff % -1;
 }
@@ -269,9 +270,8 @@ mod_s64(void)
 {
 	s64 = -1LL % (-0x7fffffffffffffffLL - 1LL);
 	s64 = -1LL % 0x7fffffffffffffffLL;
-	// FIXME: endless loop on x86_64 in idivq instruction,
-	//  probably due to SIGFPE handling.
-	//s64 = (-0x7fffffffffffffffLL - 1LL) % -1LL;
+	/* expect+1: warning: operator '%' produces integer overflow [141] */
+	s64 = (-0x7fffffffffffffffLL - 1LL) % -1LL;
 	s64 = 0x7fffffffffffffffLL % -1LL;
 }
 
@@ -334,12 +334,12 @@ plus_u32(void)
 void
 plus_s64(void)
 {
-	/* TODO: expect+1: warning: operator '+' produces integer overflow [141] */
-	// FIXME: s64 = -0x7fffffffffffffffLL + -2LL;
+	/* expect+1: warning: operator '+' produces integer overflow [141] */
+	s64 = -0x7fffffffffffffffLL + -2LL;
 	s64 = -0x7fffffffffffffffLL + -1LL;
 	s64 = 0x7ffffffffffffffeLL + 1LL;
-	/* TODO: expect+1: warning: operator '+' produces integer overflow [141] */
-	// FIXME: s64 = 0x7fffffffffffffffLL + 1LL;
+	/* expect+1: warning: operator '+' produces integer overflow [141] */
+	s64 = 0x7fffffffffffffffLL + 1LL;
 }
 
 void
@@ -390,19 +390,19 @@ minus_u32(void)
 void
 minus_s64(void)
 {
-	/* TODO: expect+1: warning: operator '-' produces integer overflow [141] */
-	// FIXME: s64 = -0x7fffffffffffffffLL - 0x7fffffffffffffffLL;
-	/* TODO: expect+1: warning: operator '-' produces integer overflow [141] */
-	// FIXME: s64 = -0x7fffffffffffffffLL - 2LL;
+	/* expect+1: warning: operator '-' produces integer overflow [141] */
+	s64 = -0x7fffffffffffffffLL - 0x7fffffffffffffffLL;
+	/* expect+1: warning: operator '-' produces integer overflow [141] */
+	s64 = -0x7fffffffffffffffLL - 2LL;
 	s64 = -0x7fffffffffffffffLL - 1LL;
 	s64 = -0x7fffffffffffffffLL - 0LL;
 	s64 = -0x7fffffffffffffffLL - -1LL;
 	s64 = 0x7fffffffffffffffLL - 1LL;
 	s64 = 0x7fffffffffffffffLL - 0LL;
-	/* TODO: expect+1: warning: operator '-' produces integer overflow [141] */
-	// FIXME: s64 = 0x7fffffffffffffffLL - -1LL;
-	/* TODO: expect+1: warning: operator '-' produces integer overflow [141] */
-	// FIXME: s64 = 0x7fffffffffffffffLL - -0x7fffffffffffffffLL;
+	/* expect+1: warning: operator '-' produces integer overflow [141] */
+	s64 = 0x7fffffffffffffffLL - -1LL;
+	/* expect+1: warning: operator '-' produces integer overflow [141] */
+	s64 = 0x7fffffffffffffffLL - -0x7fffffffffffffffLL;
 }
 
 void

Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.615 src/usr.bin/xlint/lint1/tree.c:1.616
--- src/usr.bin/xlint/lint1/tree.c:1.615	Sun Mar 10 09:24:54 2024
+++ src/usr.bin/xlint/lint1/tree.c	Sun Mar 10 10:15:51 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.615 2024/03/10 09:24:54 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.616 2024/03/10 10:15:51 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.615 2024/03/10 09:24:54 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.616 2024/03/10 10:15:51 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -834,7 +834,16 @@ fold_constant_integer(tnode_t *tn)
 			else if (ul != 0 && si / ul != ur)
 				ovfl = true;
 		} else {
-			si = sl * sr;
+			uint64_t al = sl >= 0 ? ul : -ul;
+			uint64_t ar = sr >= 0 ? ur : -ur;
+			bool neg = (sl >= 0) != (sr >= 0);
+			uint64_t max_prod = (uint64_t)max_value
+			    + (neg ? 1 : 0);
+			if (al > 0 && ar > max_prod / al) {
+				si = (int64_t)(al * ar);
+				ovfl = true;
+			} else
+				si = sl * sr;
 			if (msb(si, t) != (msb(sl, t) ^ msb(sr, t)))
 				ovfl = true;
 		}
@@ -855,18 +864,21 @@ fold_constant_integer(tnode_t *tn)
 			/* modulus by 0 */
 			error(140);
 			si = 0;
+		} else if (!utyp && sl == min_value && sr == -1) {
+			ovfl = true;
+			si = 0;
 		} else
 			si = utyp ? (int64_t)(ul % ur) : sl % sr;
 		break;
 	case PLUS:
-		si = utyp ? (int64_t)(ul + ur) : sl + sr;
+		si = (int64_t)(ul + ur);
 		if (msb(sl, t) && msb(sr, t) && !msb(si, t))
 			ovfl = true;
 		if (!utyp && !msb(sl, t) && !msb(sr, t) && msb(si, t))
 			ovfl = true;
 		break;
 	case MINUS:
-		si = utyp ? (int64_t)(ul - ur) : sl - sr;
+		si = (int64_t)(ul - ur);
 		if (!utyp && msb(sl, t) && !msb(sr, t) && !msb(si, t))
 			ovfl = true;
 		if (!msb(sl, t) && msb(sr, t) && msb(si, t))

Reply via email to