Bug 24370 – static array values in static AA initialise to dynamic arrays
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2024-02-04T10:34:55Z
Last change time
2024-02-16T22:35:11Z
Keywords
pull
Assigned to
No Owner
Creator
zxinsworld
Comments
Comment #0 by zxinsworld — 2024-02-04T10:34:55Z
Creating a module-level `immutable` associative array with a static array as its value seemingly causes it to create a dyanmic array, which it then interprets as a static array, causing memory corruption if the static array's length is longer than a dynamic array object.
Affects dmd 2.106.X 0–2.107.0.
Steps to reproduce...
Here's a minimal test example:
```d
immutable uint[3][string] test = [
"oneTwoThree": [1,2,3],
"fourFiveSix": [4,5,6],
"sevenEightNine": [7,8,9],
];
void main(){
import std.stdio: writeln;
writeln(test);
}
```
When I ran it on run.dlang.io with `dmd-beta` (2.106.X), I got:
```
["sevenEightNine":[3, 0, 3620282384], "fourFiveSix":[3, 0, 3620282448], "oneTwoThree":[3, 0, 3620282512]]
```
Uh oh! I expected:
```
["sevenEightNine":[7, 8, 9], "fourFiveSix":[4, 5, 6], "oneTwoThree":[1, 2, 3]]
```
Let's add a few more items to our static array:
```d
immutable uint[18][string] test = [
"aaa": [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],
];
void main() @safe{
import std.stdio: writeln;
writeln(test);
}
```
Now I got:
```
["aaa":[18, 0, 1472507920, 21935, 0, 0, 0, 0, 3844923289, 3235698430, 1472508016, 21935, 0, 0, 0, 0, 0, 0]]
```
The very long numbers are obviously pointers, so their value is non-deterministic.
Comment #1 by zxinsworld — 2024-02-04T10:38:35Z
Correction: this also applies to the initial value of mutable module-level associative arrays.
Comment #2 by schveiguy — 2024-02-06T19:57:00Z
If I put a pragma(msg, V) inside the `core.internal.newaa.makeAA` template, it's printing out:
immutable(uint)[]
which explains why it's not working. Something in the way the lowering is done doesn't work correctly.
Comment #3 by schveiguy — 2024-02-06T20:28:24Z
At runtime, the compiler changes this:
uint[3][string] x = ["hello": [1, 2, 3];
into:
uint[3][string] x = ["hello": [1u, 2u, 3u]]
Note the `u` suffixes, which the compiler adds when seeing the type is `uint`.
This is fine, because the expression has no specific type, just the values have types that are inferred. And the semantic knows how to process this.
However, what we are doing is effectively:
uint[3][string] x = cast(void*)__aaAsStruct(["hello": [1u, 2u, 3u]])
This *leaves out* the type inference based on the type assignment, and uses IFTI to infer the K and V parameters passed to __aaAsStruct without the context of x.
What we need to do is __aaAsStruct(cast(typeof(x))["hello": [1u, 2u, 3u]]) so it will infer the types needed. I'm not 100% sure this will work, because casting is weird at compile-time.
Alternatively, it could explicitly intstantiate e.g. __aaAsStruct!(string, uint[3])(...)
This is slightly less desirable, since it assumes the compile-time parameters of the hook. It also might have issues which are solved quite easily using IFTI.
Comment #4 by dlang-bot — 2024-02-06T21:32:25Z
@dkorpel created dlang/dmd pull request #16164 "Fix Bugzilla Issue 24370 - static array values in static AA initialis…" fixing this issue:
- Fix Bugzilla Issue 24370 - static array values in static AA initialise to dynamic arrays
https://github.com/dlang/dmd/pull/16164
Comment #5 by dlang-bot — 2024-02-06T23:09:59Z
dlang/dmd pull request #16164 "Fix Bugzilla Issue 24370 - static array values in static AA initialis…" was merged into stable:
- 8056c9a8aa9c1303486e9f91d4b8c1b38b2ba3e4 by Dennis Korpel:
Fix Bugzilla Issue 24370 - static array values in static AA initialise to dynamic arrays
https://github.com/dlang/dmd/pull/16164
Comment #6 by dlang-bot — 2024-02-16T22:35:11Z
dlang/dmd pull request #16195 "merge stable" was merged into master:
- aa122ae00018a2240b39efe53221b731a6db6634 by Dennis Korpel:
Fix Bugzilla Issue 24370 - static array values in static AA initialise to dynamic arrays
https://github.com/dlang/dmd/pull/16195