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