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 '<<'. */