Module Name: src Committed By: rillig Date: Sun Mar 10 16:06:13 UTC 2024
Modified Files: src/tests/usr.bin/xlint/lint1: platform_ilp32_int.c platform_ilp32_long.c platform_lp64.c src/usr.bin/xlint/lint1: tree.c Log Message: lint: saturate signed integer overflow In array address calculations, this prevents a 'array subscript cannot be negative' for large array subscripts. To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/tests/usr.bin/xlint/lint1/platform_ilp32_int.c cvs rdiff -u -r1.6 -r1.7 src/tests/usr.bin/xlint/lint1/platform_ilp32_long.c cvs rdiff -u -r1.10 -r1.11 src/tests/usr.bin/xlint/lint1/platform_lp64.c cvs rdiff -u -r1.621 -r1.622 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/platform_ilp32_int.c diff -u src/tests/usr.bin/xlint/lint1/platform_ilp32_int.c:1.4 src/tests/usr.bin/xlint/lint1/platform_ilp32_int.c:1.5 --- src/tests/usr.bin/xlint/lint1/platform_ilp32_int.c:1.4 Sat Mar 9 17:34:01 2024 +++ src/tests/usr.bin/xlint/lint1/platform_ilp32_int.c Sun Mar 10 16:06:13 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: platform_ilp32_int.c,v 1.4 2024/03/09 17:34:01 rillig Exp $ */ +/* $NetBSD: platform_ilp32_int.c,v 1.5 2024/03/10 16:06:13 rillig Exp $ */ # 3 "platform_ilp32_int.c" /* @@ -65,19 +65,22 @@ array_index(void) /* expect+1: warning: array subscript cannot be > 19: 16777215 [168] */ u64 += u64_buf[0x00ffffff]; /* expect+2: warning: operator '*' produces integer overflow [141] */ - /* expect+1: warning: array subscript cannot be negative: -1 [167] */ + /* expect+1: warning: array subscript cannot be > 19: 268435455 [168] */ u64 += u64_buf[0x7fffffff]; - /* expect+2: warning: conversion of 'long long' to 'int' is out of range [119] */ - /* expect+1: warning: operator '*' produces integer overflow [141] */ + /* expect+3: warning: conversion of 'long long' to 'int' is out of range [119] */ + /* expect+2: warning: operator '*' produces integer overflow [141] */ + /* expect+1: warning: array subscript cannot be negative: -268435456 [167] */ u64 += u64_buf[2147483648]; - /* expect+2: warning: conversion of 'unsigned int' to 'int' is out of range [119] */ - /* expect+1: warning: operator '*' produces integer overflow [141] */ + /* expect+3: warning: conversion of 'unsigned int' to 'int' is out of range [119] */ + /* expect+2: warning: operator '*' produces integer overflow [141] */ + /* expect+1: warning: array subscript cannot be negative: -268435456 [167] */ u64 += u64_buf[0x80000000]; /* expect+2: warning: conversion of 'unsigned int' to 'int' is out of range [119] */ /* expect+1: warning: array subscript cannot be negative: -1 [167] */ u64 += u64_buf[0xffffffff]; - /* expect+2: warning: conversion of 'unsigned int' to 'int' is out of range [119] */ - /* expect+1: warning: operator '*' produces integer overflow [141] */ + /* expect+3: warning: conversion of 'unsigned int' to 'int' is out of range [119] */ + /* expect+2: warning: operator '*' produces integer overflow [141] */ + /* expect+1: warning: array subscript cannot be negative: -268435456 [167] */ u64 += u64_buf[0x80000000]; /* expect+2: warning: conversion of 'unsigned int' to 'int' is out of range [119] */ /* expect+1: warning: array subscript cannot be negative: -1 [167] */ Index: src/tests/usr.bin/xlint/lint1/platform_ilp32_long.c diff -u src/tests/usr.bin/xlint/lint1/platform_ilp32_long.c:1.6 src/tests/usr.bin/xlint/lint1/platform_ilp32_long.c:1.7 --- src/tests/usr.bin/xlint/lint1/platform_ilp32_long.c:1.6 Sat Mar 9 17:34:01 2024 +++ src/tests/usr.bin/xlint/lint1/platform_ilp32_long.c Sun Mar 10 16:06:13 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: platform_ilp32_long.c,v 1.6 2024/03/09 17:34:01 rillig Exp $ */ +/* $NetBSD: platform_ilp32_long.c,v 1.7 2024/03/10 16:06:13 rillig Exp $ */ # 3 "platform_ilp32_long.c" /* @@ -74,19 +74,22 @@ array_index(void) /* expect+1: warning: array subscript cannot be > 19: 16777215 [168] */ u64 += u64_buf[0x00ffffff]; /* expect+2: warning: operator '*' produces integer overflow [141] */ - /* expect+1: warning: array subscript cannot be negative: -1 [167] */ + /* expect+1: warning: array subscript cannot be > 19: 268435455 [168] */ u64 += u64_buf[0x7fffffff]; - /* expect+2: warning: conversion of 'long long' to 'long' is out of range [119] */ - /* expect+1: warning: operator '*' produces integer overflow [141] */ + /* expect+3: warning: conversion of 'long long' to 'long' is out of range [119] */ + /* expect+2: warning: operator '*' produces integer overflow [141] */ + /* expect+1: warning: array subscript cannot be negative: -268435456 [167] */ u64 += u64_buf[2147483648]; - /* expect+2: warning: conversion of 'unsigned int' to 'long' is out of range [119] */ - /* expect+1: warning: operator '*' produces integer overflow [141] */ + /* expect+3: warning: conversion of 'unsigned int' to 'long' is out of range [119] */ + /* expect+2: warning: operator '*' produces integer overflow [141] */ + /* expect+1: warning: array subscript cannot be negative: -268435456 [167] */ u64 += u64_buf[0x80000000]; /* expect+2: warning: conversion of 'unsigned int' to 'long' is out of range [119] */ /* expect+1: warning: array subscript cannot be negative: -1 [167] */ u64 += u64_buf[0xffffffff]; - /* expect+2: warning: conversion of 'unsigned int' to 'long' is out of range [119] */ - /* expect+1: warning: operator '*' produces integer overflow [141] */ + /* expect+3: warning: conversion of 'unsigned int' to 'long' is out of range [119] */ + /* expect+2: warning: operator '*' produces integer overflow [141] */ + /* expect+1: warning: array subscript cannot be negative: -268435456 [167] */ u64 += u64_buf[0x80000000]; /* expect+2: warning: conversion of 'unsigned int' to 'long' is out of range [119] */ /* expect+1: warning: array subscript cannot be negative: -1 [167] */ Index: src/tests/usr.bin/xlint/lint1/platform_lp64.c diff -u src/tests/usr.bin/xlint/lint1/platform_lp64.c:1.10 src/tests/usr.bin/xlint/lint1/platform_lp64.c:1.11 --- src/tests/usr.bin/xlint/lint1/platform_lp64.c:1.10 Sun Mar 10 10:39:19 2024 +++ src/tests/usr.bin/xlint/lint1/platform_lp64.c Sun Mar 10 16:06:13 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: platform_lp64.c,v 1.10 2024/03/10 10:39:19 rillig Exp $ */ +/* $NetBSD: platform_lp64.c,v 1.11 2024/03/10 16:06:13 rillig Exp $ */ # 3 "platform_lp64.c" /* @@ -92,13 +92,13 @@ array_index(void) /* expect+1: warning: array subscript cannot be > 19: 1152921504606846975 [168] */ u64 += u64_buf[0x0fffffffffffffff]; /* expect+2: warning: operator '*' produces integer overflow [141] */ - /* expect+1: warning: array subscript cannot be negative: -1 [167] */ + /* expect+1: warning: array subscript cannot be > 19: 1152921504606846975 [168] */ u64 += u64_buf[0x1fffffffffffffff]; /* expect+2: warning: operator '*' produces integer overflow [141] */ - /* expect+1: warning: array subscript cannot be negative: -1 [167] */ + /* expect+1: warning: array subscript cannot be > 19: 1152921504606846975 [168] */ u64 += u64_buf[0x3fffffffffffffff]; /* expect+2: warning: operator '*' produces integer overflow [141] */ - /* expect+1: warning: array subscript cannot be negative: -1 [167] */ + /* expect+1: warning: array subscript cannot be > 19: 1152921504606846975 [168] */ u64 += u64_buf[0x7fffffffffffffff]; /* expect+1: warning: array subscript cannot be negative: -1 [167] */ u64 += u64_buf[0xffffffffffffffff]; Index: src/usr.bin/xlint/lint1/tree.c diff -u src/usr.bin/xlint/lint1/tree.c:1.621 src/usr.bin/xlint/lint1/tree.c:1.622 --- src/usr.bin/xlint/lint1/tree.c:1.621 Sun Mar 10 15:49:12 2024 +++ src/usr.bin/xlint/lint1/tree.c Sun Mar 10 16:06:13 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: tree.c,v 1.621 2024/03/10 15:49:12 rillig Exp $ */ +/* $NetBSD: tree.c,v 1.622 2024/03/10 16:06:13 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.621 2024/03/10 15:49:12 rillig Exp $"); +__RCSID("$NetBSD: tree.c,v 1.622 2024/03/10 16:06:13 rillig Exp $"); #endif #include <float.h> @@ -871,7 +871,7 @@ fold_signed_integer(op_t op, int64_t l, uint64_t max_prod = (uint64_t)max_value + (neg ? 1 : 0); if (al > 0 && ar > max_prod / al) { *overflow = true; - return (int64_t)(al * ar); + return neg ? min_value : max_value; } return l * r; case DIV: