If a local variable has larger alignment requirements, closures that capture function arguments can fail: struct SpinLock { align(64) int x; } void collectReferences(int x) //ref HashTab references) { SpinLock lock; // dmd BUG: alignment causes bad capture! void mark() scope nothrow { assert (x == 7); } mark(); } void main() { collectReferences(7); } For Win64, RSP is aligned according to alignof(SpinLock) for alignments 32-128. This makes the closure offset for the function argument x non-constant. Side note: no alignment happens for align(256) or higher. For Win32, alignment is silently omitted.
The alignment code is emitted for Win64, but not for Win32. But you listed the bug applying to x86_64. So please clarify: Is this working for 64 bit platforms?
Currently, stack alignment is enforced only for 64 bit compilations and 32 bit OSX compilations. See the setting of `enforcealign` in codgen() in cgcod.d.
A somewhat more illustrative test: struct SpinLock { align(64) int x; } void collectReferences(int x) //ref HashTab references) { SpinLock lock = SpinLock(8); // dmd BUG: alignment causes bad capture! void mark() scope nothrow { assert(lock.x == 8); assert(x == 7); } mark(); } void main() { collectReferences(7); }
(In reply to Walter Bright from comment #1) > The alignment code is emitted for Win64, but not for Win32. But you listed > the bug applying to x86_64. Win32 passes the assert, but ignores alignments. > > So please clarify: > > Is this working for 64 bit platforms? No.
Thanks, I think I understand it now. But the solution isn't obvious :-/
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17920 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB