diff --git a/tests/usr.bin/xlint/lint1/msg_141.c b/tests/usr.bin/xlint/lint1/msg_141.c index b7150b2dacc0..9a18143e8b39 100644 --- a/tests/usr.bin/xlint/lint1/msg_141.c +++ b/tests/usr.bin/xlint/lint1/msg_141.c @@ -1,4 +1,4 @@ -/* $NetBSD: msg_141.c,v 1.11 2024/03/10 09:58:30 rillig Exp $ */ +/* $NetBSD: msg_141.c,v 1.12 2024/03/10 10:15:52 rillig Exp $ */ # 3 "msg_141.c" // Test for message: operator '%s' produces integer overflow [141] @@ -162,26 +162,26 @@ mult_u32(void) void mult_s64(void) { - /* TODO: expect+1: warning: operator '*' produces integer overflow [141] */ - //s64 = -0x100000000LL * 0x100000000LL; // -0x010000000000000000 - /* TODO: expect+1: warning: operator '*' produces integer overflow [141] */ - //s64 = -3LL * 0x2aaaaaaaaaaaaaabLL; // -0x8000000000000001 - /* TODO: expect+1: warning: operator '*' produces integer overflow [141] */ - //s64 = 0x2aaaaaaaaaaaaaabLL * -3LL; // -0x8000000000000001 + /* expect+1: warning: operator '*' produces integer overflow [141] */ + s64 = -0x100000000LL * 0x100000000LL; // -0x010000000000000000 + /* expect+1: warning: operator '*' produces integer overflow [141] */ + s64 = -3LL * 0x2aaaaaaaaaaaaaabLL; // -0x8000000000000001 + /* expect+1: warning: operator '*' produces integer overflow [141] */ + s64 = 0x2aaaaaaaaaaaaaabLL * -3LL; // -0x8000000000000001 s64 = -8LL * +0x1000000000000000LL; // -0x8000000000000000 s64 = +0x1000000000000000LL * -8LL; // -0x8000000000000000 s64 = +2LL * +0x3fffffffffffffffLL; // +0x7ffffffffffffffe s64 = +0x3fffffffffffffffLL * +2LL; // +0x7ffffffffffffffe s64 = +0x7fffffffffffffffLL * +1LL; // +0x7fffffffffffffff s64 = +1LL * +0x7fffffffffffffffLL; // +0x7fffffffffffffff - /* TODO: expect+1: warning: operator '*' produces integer overflow [141] */ - //s64 = +2LL * +0x4000000000000000LL; // +0x8000000000000000 - /* TODO: expect+1: warning: operator '*' produces integer overflow [141] */ - //s64 = +0x4000000000000000LL * +2LL; // +0x8000000000000000 - /* TODO: expect+1: warning: operator '*' produces integer overflow [141] */ - //s64 = +0xffffffffLL * +0x100000001LL; // +0xffffffffffffffff - /* TODO: expect+1: warning: operator '*' produces integer overflow [141] */ - //s64 = +0x100000000LL * +0x100000000LL; // +0x010000000000000000 + /* expect+1: warning: operator '*' produces integer overflow [141] */ + s64 = +2LL * +0x4000000000000000LL; // +0x8000000000000000 + /* expect+1: warning: operator '*' produces integer overflow [141] */ + s64 = +0x4000000000000000LL * +2LL; // +0x8000000000000000 + /* expect+1: warning: operator '*' produces integer overflow [141] */ + s64 = +0xffffffffLL * +0x100000001LL; // +0xffffffffffffffff + /* expect+1: warning: operator '*' produces integer overflow [141] */ + s64 = +0x100000000LL * +0x100000000LL; // +0x010000000000000000 } void @@ -249,6 +249,7 @@ mod_s32(void) { s32 = -1 % (-0x7fffffff - 1); s32 = -1 % 0x7fffffff; + /* expect+1: warning: operator '%' produces integer overflow [141] */ s32 = (-0x7fffffff - 1) % -1; s32 = 0x7fffffff % -1; } @@ -269,9 +270,8 @@ mod_s64(void) { s64 = -1LL % (-0x7fffffffffffffffLL - 1LL); s64 = -1LL % 0x7fffffffffffffffLL; - // FIXME: endless loop on x86_64 in idivq instruction, - // probably due to SIGFPE handling. - //s64 = (-0x7fffffffffffffffLL - 1LL) % -1LL; + /* expect+1: warning: operator '%' produces integer overflow [141] */ + s64 = (-0x7fffffffffffffffLL - 1LL) % -1LL; s64 = 0x7fffffffffffffffLL % -1LL; } @@ -334,12 +334,12 @@ plus_u32(void) void plus_s64(void) { - /* TODO: expect+1: warning: operator '+' produces integer overflow [141] */ - // FIXME: s64 = -0x7fffffffffffffffLL + -2LL; + /* expect+1: warning: operator '+' produces integer overflow [141] */ + s64 = -0x7fffffffffffffffLL + -2LL; s64 = -0x7fffffffffffffffLL + -1LL; s64 = 0x7ffffffffffffffeLL + 1LL; - /* TODO: expect+1: warning: operator '+' produces integer overflow [141] */ - // FIXME: s64 = 0x7fffffffffffffffLL + 1LL; + /* expect+1: warning: operator '+' produces integer overflow [141] */ + s64 = 0x7fffffffffffffffLL + 1LL; } void @@ -390,19 +390,19 @@ minus_u32(void) void minus_s64(void) { - /* TODO: expect+1: warning: operator '-' produces integer overflow [141] */ - // FIXME: s64 = -0x7fffffffffffffffLL - 0x7fffffffffffffffLL; - /* TODO: expect+1: warning: operator '-' produces integer overflow [141] */ - // FIXME: s64 = -0x7fffffffffffffffLL - 2LL; + /* expect+1: warning: operator '-' produces integer overflow [141] */ + s64 = -0x7fffffffffffffffLL - 0x7fffffffffffffffLL; + /* expect+1: warning: operator '-' produces integer overflow [141] */ + s64 = -0x7fffffffffffffffLL - 2LL; s64 = -0x7fffffffffffffffLL - 1LL; s64 = -0x7fffffffffffffffLL - 0LL; s64 = -0x7fffffffffffffffLL - -1LL; s64 = 0x7fffffffffffffffLL - 1LL; s64 = 0x7fffffffffffffffLL - 0LL; - /* TODO: expect+1: warning: operator '-' produces integer overflow [141] */ - // FIXME: s64 = 0x7fffffffffffffffLL - -1LL; - /* TODO: expect+1: warning: operator '-' produces integer overflow [141] */ - // FIXME: s64 = 0x7fffffffffffffffLL - -0x7fffffffffffffffLL; + /* expect+1: warning: operator '-' produces integer overflow [141] */ + s64 = 0x7fffffffffffffffLL - -1LL; + /* expect+1: warning: operator '-' produces integer overflow [141] */ + s64 = 0x7fffffffffffffffLL - -0x7fffffffffffffffLL; } void diff --git a/usr.bin/xlint/lint1/tree.c b/usr.bin/xlint/lint1/tree.c index af8355288fa8..a7d1b88935a8 100644 --- a/usr.bin/xlint/lint1/tree.c +++ b/usr.bin/xlint/lint1/tree.c @@ -1,4 +1,4 @@ -/* $NetBSD: tree.c,v 1.615 2024/03/10 09:24:54 rillig Exp $ */ +/* $NetBSD: tree.c,v 1.616 2024/03/10 10:15:51 rillig Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -37,7 +37,7 @@ #include #if defined(__RCSID) -__RCSID("$NetBSD: tree.c,v 1.615 2024/03/10 09:24:54 rillig Exp $"); +__RCSID("$NetBSD: tree.c,v 1.616 2024/03/10 10:15:51 rillig Exp $"); #endif #include @@ -834,7 +834,16 @@ fold_constant_integer(tnode_t *tn) else if (ul != 0 && si / ul != ur) ovfl = true; } else { - si = sl * sr; + uint64_t al = sl >= 0 ? ul : -ul; + uint64_t ar = sr >= 0 ? ur : -ur; + bool neg = (sl >= 0) != (sr >= 0); + uint64_t max_prod = (uint64_t)max_value + + (neg ? 1 : 0); + if (al > 0 && ar > max_prod / al) { + si = (int64_t)(al * ar); + ovfl = true; + } else + si = sl * sr; if (msb(si, t) != (msb(sl, t) ^ msb(sr, t))) ovfl = true; } @@ -855,18 +864,21 @@ fold_constant_integer(tnode_t *tn) /* modulus by 0 */ error(140); si = 0; + } else if (!utyp && sl == min_value && sr == -1) { + ovfl = true; + si = 0; } else si = utyp ? (int64_t)(ul % ur) : sl % sr; break; case PLUS: - si = utyp ? (int64_t)(ul + ur) : sl + sr; + si = (int64_t)(ul + ur); if (msb(sl, t) && msb(sr, t) && !msb(si, t)) ovfl = true; if (!utyp && !msb(sl, t) && !msb(sr, t) && msb(si, t)) ovfl = true; break; case MINUS: - si = utyp ? (int64_t)(ul - ur) : sl - sr; + si = (int64_t)(ul - ur); if (!utyp && msb(sl, t) && !msb(sr, t) && !msb(si, t)) ovfl = true; if (!msb(sl, t) && msb(sr, t) && msb(si, t))