Fix bugzilla 24855 - VRP fails to prevent overflow after division

This commit is contained in:
Dennis Korpel 2024-11-12 23:39:30 +01:00 committed by The Dlang Bot
parent 9ffda54fe1
commit f6115f0335
3 changed files with 12 additions and 2 deletions

View file

@ -667,7 +667,7 @@ struct IntRange
return widest(); return widest();
// Don't treat the whole range as divide by 0 if only one end of a range is 0. // Don't treat the whole range as divide by 0 if only one end of a range is 0.
// Issue 15289 // https://issues.dlang.org/show_bug.cgi?id=15289
if (rhs.imax.value == 0) if (rhs.imax.value == 0)
{ {
rhs.imax.value--; rhs.imax.value--;
@ -681,6 +681,11 @@ struct IntRange
{ {
return IntRange(imin / rhs.imax, imax / rhs.imin); return IntRange(imin / rhs.imax, imax / rhs.imin);
} }
else if (rhs.imin.negative && !rhs.imax.negative) // divisor spans [-1, 0, 1]
{
SignExtendedNumber[4] bdy = [-imin, imin, -imax, imax];
return IntRange.fromNumbers4(bdy.ptr);
}
else else
{ {
// [a,b] / [c,d] = [min (a/c, a/d, b/c, b/d), max (a/c, a/d, b/c, b/d)] // [a,b] / [c,d] = [min (a/c, a/d, b/c, b/d), max (a/c, a/d, b/c, b/d)]

View file

@ -4,6 +4,7 @@
// https://issues.dlang.org/show_bug.cgi?id=3147 // https://issues.dlang.org/show_bug.cgi?id=3147
// https://issues.dlang.org/show_bug.cgi?id=6000 // https://issues.dlang.org/show_bug.cgi?id=6000
// https://issues.dlang.org/show_bug.cgi?id=5225 // https://issues.dlang.org/show_bug.cgi?id=5225
// https://issues.dlang.org/show_bug.cgi?id=24855
void add() void add()
{ {
@ -100,6 +101,10 @@ void divideFail()
short w; short w;
byte y; byte y;
static assert(!__traits(compiles, y = w / -1)); static assert(!__traits(compiles, y = w / -1));
static assert(!__traits(compiles, y = y / w));
short z;
static assert(!__traits(compiles, z = w / z + 1));
} }
void plus1Fail() void plus1Fail()

View file

@ -1426,7 +1426,7 @@ short[PAGESIZE / 16][Bins.B_NUMSMALL + 1] calcBinBase()
foreach (i, size; binsize) foreach (i, size; binsize)
{ {
short end = (PAGESIZE / size) * size; short end = cast(short) ((PAGESIZE / size) * size);
short bsz = size / 16; short bsz = size / 16;
foreach (off; 0..PAGESIZE/16) foreach (off; 0..PAGESIZE/16)
{ {