Module Name:    src
Committed By:   rillig
Date:           Sun Mar 10 14:32:30 UTC 2024

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

Log Message:
lint: detect more cases of integer overflow in constant expressions

For unsigned integers, detect when 'a + b' wraps around.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/tests/usr.bin/xlint/lint1/expr_fold.c \
    src/tests/usr.bin/xlint/lint1/msg_141.c
cvs rdiff -u -r1.618 -r1.619 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/expr_fold.c
diff -u src/tests/usr.bin/xlint/lint1/expr_fold.c:1.13 src/tests/usr.bin/xlint/lint1/expr_fold.c:1.14
--- src/tests/usr.bin/xlint/lint1/expr_fold.c:1.13	Sun Mar 10 10:31:29 2024
+++ src/tests/usr.bin/xlint/lint1/expr_fold.c	Sun Mar 10 14:32:30 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: expr_fold.c,v 1.13 2024/03/10 10:31:29 rillig Exp $	*/
+/*	$NetBSD: expr_fold.c,v 1.14 2024/03/10 14:32:30 rillig Exp $	*/
 # 3 "expr_fold.c"
 
 /*
@@ -59,8 +59,7 @@ fold_uminus(void)
 	/* The '-' is an operator, it is not part of the integer constant. */
 	take_int(-2147483648);
 
-	/* expect+2: warning: operator '+' produces integer overflow [141] */
-	/* expect+1: warning: operator '-' produces integer overflow [141] */
+	/* expect+1: warning: operator '+' produces integer overflow [141] */
 	take_int(-(2147483647 + 1));
 	/* expect+1: warning: operator '-' produces integer overflow [141] */
 	take_int(-(-2147483647 - 1));
Index: src/tests/usr.bin/xlint/lint1/msg_141.c
diff -u src/tests/usr.bin/xlint/lint1/msg_141.c:1.13 src/tests/usr.bin/xlint/lint1/msg_141.c:1.14
--- src/tests/usr.bin/xlint/lint1/msg_141.c:1.13	Sun Mar 10 10:31:29 2024
+++ src/tests/usr.bin/xlint/lint1/msg_141.c	Sun Mar 10 14:32:30 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg_141.c,v 1.13 2024/03/10 10:31:29 rillig Exp $	*/
+/*	$NetBSD: msg_141.c,v 1.14 2024/03/10 14:32:30 rillig Exp $	*/
 # 3 "msg_141.c"
 
 // Test for message: operator '%s' produces integer overflow [141]
@@ -347,11 +347,11 @@ plus_u64(void)
 	u64 = 0xffffffffffffffffULL + 0x0000000000000000ULL;
 	u64 = 0x0000000000000000ULL + 0xffffffffffffffffULL;
 	u64 = 0xfffffffffffffffeULL + 0x0000000000000001ULL;
-	/* TODO: expect+1: warning: operator '+' produces integer overflow [141] */
+	/* expect+1: warning: operator '+' produces integer overflow [141] */
 	u64 = 0xffffffffffffffffULL + 0x0000000000000001ULL;
-	/* TODO: expect+1: warning: operator '+' produces integer overflow [141] */
+	/* expect+1: warning: operator '+' produces integer overflow [141] */
 	u64 = 0x0000000000000001ULL + 0xffffffffffffffffULL;
-	/* TODO: expect+1: warning: operator '+' produces integer overflow [141] */
+	/* expect+1: warning: operator '+' produces integer overflow [141] */
 	u64 = 0xffffffffffffffffULL + 0xffffffffffffffffULL;
 }
 
@@ -374,12 +374,12 @@ void
 minus_u32(void)
 {
 	u32 = 0x00000000U - 0x00000000U;
-	/* TODO: expect+1: warning: operator '-' produces integer overflow [141] */
+	/* expect+1: warning: operator '-' produces integer overflow [141] */
 	u32 = 0x00000000U - 0x00000001U;
 	/* expect+1: warning: operator '-' produces integer overflow [141] */
 	u32 = 0x00000000U - 0x80000000U;
 	u32 = 0x80000000U - 0x00000001U;
-	/* TODO: expect+1: warning: operator '-' produces integer overflow [141] */
+	/* expect+1: warning: operator '-' produces integer overflow [141] */
 	u32 = 0x00000000U - 0xffffffffU;
 	u32 = 0xffffffffU - 0x00000000U;
 	u32 = 0xffffffffU - 0xffffffffU;

Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.618 src/usr.bin/xlint/lint1/tree.c:1.619
--- src/usr.bin/xlint/lint1/tree.c:1.618	Sun Mar 10 12:50:45 2024
+++ src/usr.bin/xlint/lint1/tree.c	Sun Mar 10 14:32:30 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.618 2024/03/10 12:50:45 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.619 2024/03/10 14:32: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.618 2024/03/10 12:50:45 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.619 2024/03/10 14:32:30 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -819,18 +819,12 @@ fold_unsigned_integer(op_t op, uint64_t 
 			return 0;
 		} else
 			return l % r;
-	case PLUS:;
-		uint64_t plus_result = l + r;
-		uint64_t hi = max_value ^ (max_value >> 1);
-		if (l & hi && r & hi && !(plus_result & hi))
-			*overflow = true;
-		return plus_result;
-	case MINUS:;
-		uint64_t minus_result = l - r;
-		hi = max_value ^ (max_value >> 1);
-		if (!(l & hi) && r & hi && minus_result & hi)
-			*overflow = true;
-		return minus_result;
+	case PLUS:
+		*overflow = l > max_value - r;
+		return l + r;
+	case MINUS:
+		*overflow = l < r;
+		return l - r;
 	case SHL:
 		/* TODO: warn about out-of-bounds 'sr'. */
 		return l << (r & 63);
@@ -910,23 +904,26 @@ fold_signed_integer(op_t op, int64_t l, 
 			return 0;
 		}
 		return l % r;
-	case PLUS:;
-		uint64_t plus_result = (uint64_t)l + (uint64_t)r;
-		hi = (uint64_t)max_value + 1;
-
-		if (l & hi && r & hi && !(plus_result & hi))
+	case PLUS:
+		if (r > 0 && l > max_value - r) {
 			*overflow = true;
-		if (!(l & hi) && !(r & hi) && plus_result & hi)
+			return max_value;
+		}
+		if (r < 0 && l < min_value - r) {
 			*overflow = true;
-		return (int64_t)plus_result;
-	case MINUS:;
-		uint64_t minus_result = (uint64_t)l - (uint64_t)r;
-		hi = (uint64_t)max_value + 1;
-		if (l & hi && !(r & hi) && !(minus_result & hi))
+			return min_value;
+		}
+		return l + r;
+	case MINUS:
+		if (r > 0 && l < min_value + r) {
 			*overflow = true;
-		if (!(l & hi) && r & hi && minus_result & hi)
+			return min_value;
+		}
+		if (r < 0 && l > max_value + r) {
 			*overflow = true;
-		return (int64_t)minus_result;
+			return max_value;
+		}
+		return l - r;
 	case SHL:
 		/* TODO: warn about out-of-bounds 'sr'. */
 		/* TODO: warn about overflow in signed '<<'. */

Reply via email to