Bug 10124 – Array length increases on subtraction of a big number instead of throwing RangeError

Status
RESOLVED
Resolution
WONTFIX
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-05-20T04:52:02Z
Last change time
2020-08-29T07:08:06Z
Keywords
backend, wrong-code
Assigned to
No Owner
Creator
Denis Shelomovskii
Blocks
10123

Comments

Comment #0 by verylonglogin.reg — 2013-05-20T04:52:02Z
This code runs fine but should fail in runtime: --- void main() { int[] arr; arr.length -= size_t.max; // Let's subtract a very big number assert(arr.length == 1); // Passes! } --- Also there is a question what to do with `arr.length -= -1`? I'd like this code to be rejected as incorrect mixed signed/unsigned operation (see also Issue 259). This is a compiler bug as dmd just calls `_d_arraysetlengthT` without any information about operation type. I.e. it works like `arr.length = arr.length - size_t.max`.
Comment #1 by yebblies — 2014-08-31T13:47:15Z
I'm not sure it should fail. This is how unsigned types usually work.
Comment #2 by monarchdodra — 2014-08-31T21:03:55Z
(In reply to yebblies from comment #1) > I'm not sure it should fail. This is how unsigned types usually work. Yeah... but it's not actually an arithmetic operations here. It's a setter operation. AFAIK, array resize detects overflow. I don't see why it wouldn't detect underflow? Just saying.
Comment #3 by Marco.Leise — 2014-09-01T06:44:08Z
I see it like the others, Denis. Detecting overflow/underflow here is no different than on regular integer math in other places. The compiler's rewrite looks fine to me. If anything, we need a generic integer overflow check placed around integer math. Same goes for `arr.length -= -1': Again, this is how the language works. Mixing signed and unsigned is allowed, as is `a - (-1)'. While I am positive on these features in general as a nice-to-have, I think this bug report on array.length is invalid and too narrow. Consider for example some custom struct exposing some .length similar to arr.length, which would not be affected by a fix to this bug. We would get different semantics where we are striving to unify the experience.
Comment #4 by yebblies — 2014-09-01T18:18:40Z
Overflow looks the same: void main() { int[] arr = [1,2,3,4]; arr.length += uint.max; } It's currently being rewritten to 'length = (length op arg)'. I'm not sure how to detect this easily without adding inline code, or an overload for each operation. I mean, for this: arr.length += -3; the compiler sees this: arr.length = arr.length + 4294967293u;
Comment #5 by bugzilla — 2020-08-29T07:08:06Z
This is an artifact of 2's complement arithmetic. Instrumenting the code to detect integer arithmetic overflows will have a large performance penalty, so is not done.