Bug 24377 – Error: negative array dimension `3145728u * 1024u`[32bit]

Status
NEW
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2024-02-08T22:09:50Z
Last change time
2024-12-13T19:33:09Z
Keywords
diagnostic, rejects-valid
Assigned to
No Owner
Creator
kdevel
See also
https://issues.dlang.org/show_bug.cgi?id=11612
Moved to GitHub: dmd#20397 →

Comments

Comment #0 by kdevel — 2024-02-08T22:09:50Z
$ cat nad.d import std.stdio; void main() { auto arr = new char [3u * 1024 * 1024 * 1024]; // <--- error writefln ("%X", arr.length); } $ dmd -m32 ./nad.d ./nad.d(5): Error: negative array dimension `3145728u * 1024u` [unexpected] $ gdc -m32 nad.d -o nad $ ./nad C0000000 [expected] $ cat nad2.d import std.stdio; void main() { auto siz = 3u * 1024 * 1024 * 1024; auto arr = new char [siz]; writefln ("%X", arr.length); } $ dmd -m32 ./nad2.d $ ./nad2 C0000000 [expected] used compilers: - DMD64 D Compiler v2.105.3 - gcc (GCC) 12.1.0
Comment #1 by ibuclaw — 2024-02-10T12:00:59Z
Behaviour changed in v2.105
Comment #2 by ibuclaw — 2024-02-10T12:14:40Z
Comment #3 by ibuclaw — 2024-02-10T12:21:47Z
You're allocating an array that takes up more than half the address space, so that is already pretty dubious. Note: this is the case on 64-bit too if you request an array size bigger than `long.max`. auto arr = new char [1u + long.max]; // Error: negative array dimension `1LU + 9223372036854775807LU`
Comment #4 by kdevel — 2024-02-10T12:51:48Z
(In reply to Iain Buclaw from comment #3) > You're allocating an array that takes up more than half the address space, > so that is already pretty dubious. Up to about 3.5 GiB the allocation is legit in 32 bit mode. But even with a 2 GiB allocation the error shows up: $ cat nad2g.d import std.stdio; void main() { auto arr = new char [2u * 1024 * 1024 * 1024]; // <--- error writefln ("%X", arr.length); } $ dmd -m32 nad2g.d nad2g.d(5): Error: negative array dimension `2097152u * 1024u`
Comment #5 by ibuclaw — 2024-02-11T23:31:43Z
(In reply to kdevel from comment #4) > (In reply to Iain Buclaw from comment #3) > > You're allocating an array that takes up more than half the address space, > > so that is already pretty dubious. > Up to about 3.5 GiB the allocation is legit in 32 bit mode. But even with a > 2 GiB allocation the error shows up: > > $ cat nad2g.d > import std.stdio; > > void main() > { > auto arr = new char [2u * 1024 * 1024 * 1024]; // <--- error > writefln ("%X", arr.length); > } > $ dmd -m32 nad2g.d > nad2g.d(5): Error: negative array dimension `2097152u * 1024u` It is based on the error for static arrays. ``` Error: `char[cast(size_t)2147483648]` size 1 * 2147483648 exceeds 0x7fffffff size limit for static array ``` The hard limit is the max supported static data size for the target. GCC will even warn about doing such things (i.e: malloc/calloc). ``` warning: argument 1 value ‘2147483648’ exceeds maximum object size 2147483647 ```
Comment #6 by kdevel — 2024-02-12T01:07:56Z
(In reply to Iain Buclaw from comment #5) > > $ dmd -m32 nad2g.d > > nad2g.d(5): Error: negative array dimension `2097152u * 1024u` > It is based on the error for static arrays. What follows from that observation? > ``` > Error: `char[cast(size_t)2147483648]` size 1 * 2147483648 exceeds 0x7fffffff > size limit for static array > ``` > > The hard limit is the max supported static data size for the target. This issue is not about the static data size but about dynamic allocation. > GCC will even warn about doing such things (i.e: malloc/calloc). > ``` > warning: argument 1 value ‘2147483648’ exceeds maximum object size 2147483647 > ``` The GCC message is a warning not an error. And, what is more, a false positive one [1] [2]. If you check the return value of malloc/calloc you will find that it is not NULL. That the full 2^^32 address space is available to the user process has been discussed in [3]. [1] https://stackoverflow.com/questions/47450718/gcc7-2-argument-range-exceeds-maximum-object-size-9-7-werror-alloc-size-larg [2] [GCC] Bug 85783 – alloc-size-larger-than fires incorrectly with new[] and can't be disabled https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85783 [3] https://stackoverflow.com/questions/5079519/memory-limit-to-a-32-bit-process-running-on-a-64-bit-linux-os
Comment #7 by robert.schadek — 2024-12-13T19:33:09Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20397 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB