Module Name:    src
Committed By:   rillig
Date:           Thu Jan 11 20:25:04 UTC 2024

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

Log Message:
lint: warn about integer overflow when folding constant INT_MIN / -1


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/tests/usr.bin/xlint/lint1/msg_141.c
cvs rdiff -u -r1.592 -r1.593 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.9 src/tests/usr.bin/xlint/lint1/msg_141.c:1.10
--- src/tests/usr.bin/xlint/lint1/msg_141.c:1.9	Mon Jan  8 17:11:32 2024
+++ src/tests/usr.bin/xlint/lint1/msg_141.c	Thu Jan 11 20:25:04 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg_141.c,v 1.9 2024/01/08 17:11:32 rillig Exp $	*/
+/*	$NetBSD: msg_141.c,v 1.10 2024/01/11 20:25:04 rillig Exp $	*/
 # 3 "msg_141.c"
 
 // Test for message: operator '%s' produces integer overflow [141]
@@ -149,8 +149,11 @@ long long overflow_signed[] = {
 
 	// '/'
 
-	-1 / INT_MIN,	// TODO: integer overflow
+	-1 / INT_MIN,
 	-1 / INT_MAX,
+	/* expect+1: warning: operator '/' produces integer overflow [141] */
+	INT_MIN / -1,
+	INT_MAX / -1,
 
 	// '%'
 

Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.592 src/usr.bin/xlint/lint1/tree.c:1.593
--- src/usr.bin/xlint/lint1/tree.c:1.592	Tue Jan  9 23:46:54 2024
+++ src/usr.bin/xlint/lint1/tree.c	Thu Jan 11 20:25:04 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.592 2024/01/09 23:46:54 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.593 2024/01/11 20:25:04 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.592 2024/01/09 23:46:54 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.593 2024/01/11 20:25:04 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -802,7 +802,7 @@ fold_constant_integer(tnode_t *tn)
 	if (is_binary(tn))
 		ur = sr = tn->tn_right->tn_val.u.integer;
 
-	int64_t mask = (int64_t)value_bits(size_in_bits(t));
+	uint64_t mask = value_bits(size_in_bits(t));
 	bool ovfl = false;
 
 	int64_t si;
@@ -821,7 +821,7 @@ fold_constant_integer(tnode_t *tn)
 	case MULT:
 		if (utyp) {
 			si = (int64_t)(ul * ur);
-			if (si != (si & mask))
+			if (si != (si & (int64_t)mask))
 				ovfl = true;
 			else if (ul != 0 && si / ul != ur)
 				ovfl = true;
@@ -836,6 +836,11 @@ fold_constant_integer(tnode_t *tn)
 			/* division by 0 */
 			error(139);
 			si = utyp ? -1 : INT64_MAX;
+		} else if (!utyp
+		    && (sl & mask) == (mask ^ (mask >> 1)) && sr == -1) {
+			/* operator '%s' produces integer overflow */
+			warning(141, op_name(DIV));
+			si = sl;
 		} else {
 			si = utyp ? (int64_t)(ul / ur) : sl / sr;
 		}
@@ -910,7 +915,7 @@ fold_constant_integer(tnode_t *tn)
 
 	/* XXX: The overflow check does not work for 64-bit integers. */
 	if (ovfl ||
-	    ((uint64_t)(si | mask) != ~(uint64_t)0 && (si & ~mask) != 0)) {
+	    ((si | mask) != ~(uint64_t)0 && (si & ~mask) != 0)) {
 		if (hflag)
 			/* operator '%s' produces integer overflow */
 			warning(141, op_name(tn->tn_op));

Reply via email to