Bug 19672 – Function uses the stack to read a static array parameter but it is passed in the registers

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2019-02-12T21:11:12Z
Last change time
2019-02-15T19:08:37Z
Keywords
wrong-code
Assigned to
No Owner
Creator
Basile-z
See also
https://issues.dlang.org/show_bug.cgi?id=15075

Comments

Comment #0 by b2.temp — 2019-02-12T21:11:12Z
``` struct S { ulong c; bool b; // removing this prevents bug } // increase the struct size at least to 17 bytes also prevents the bug. void main() { S[1] a = [S(42)]; assert(a[0].c == 42); /* Passes. */ f(a); } void f(S[1] a) { assert(a[0].c == 42); /* Fails. */ } ``` After inspection of the produced asm it appeared that the parameter `a` is passed in the registers RDI (a[0].c) and RSI (a[0].b) but when reading the value for the assertion the stack is used instead (proof : https://forum.dlang.org/post/[email protected]).
Comment #1 by bugzilla — 2019-02-13T07:56:53Z
Note that if S is used as the parameter type, rather than S[1], the test passes. The parameters should be passed in registers RDI and RSI for both cases, i.e. S and S[1] should behave the same.
Comment #2 by bugzilla — 2019-02-13T08:29:56Z
Comment #3 by simen.kjaras — 2019-02-13T11:18:42Z
Additional information: Happens when S.sizeof is between 9 and 16, and only for long and ulong fields. Order doesn't matter. Tested with other 8-byte types like double, int[2], short[4], ubyte[8], and it works fine. The type of the padding field also doesn't seem to matter.
Comment #4 by dlang-bot — 2019-02-15T19:08:37Z
dlang/dmd pull request #9364 "Merge remote-tracking branch 'upstream/stable' into merge_stable" was merged: https://github.com/dlang/dmd/pull/9364