Bug 10645 – Wrong codegen for shared struct with constructor and pass to atomicLoad

Status
RESOLVED
Resolution
WORKSFORME
Severity
critical
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2013-07-15T03:02:10Z
Last change time
2019-08-18T23:25:27Z
Assigned to
No Owner
Creator
jfanatiker

Attachments

IDFilenameSummaryContent-TypeSize
1233wrongcodegen.sFull assembly dumptext/plain4715

Comments

Comment #0 by jfanatiker — 2013-07-15T03:02:10Z
The following simple code: --- cat > app2.d << EOF import core.atomic; import std.stdio; struct Test { this(long v) { val = v; } long val; } void main() { shared(Test) test = Test(7); auto buf = atomicLoad(test); writefln("buf: %s, orig: %s", buf, cast(Test)test); } EOF --- produces the following output: buf: Test(0), orig: Test(7) instead of the expected: buf: Test(7), orig: Test(7) Assembly with objdump -d -g -C -S -l app2.o (full output appended): void main() { 0: 55 push %rbp 1: 48 8b ec mov %rsp,%rbp 4: 48 83 ec 10 sub $0x10,%rsp /home/robert/projects/phobosx/source/app2.d:11 shared(Test) test = Test(7); 8: 48 8d 45 f0 lea -0x10(%rbp),%rax <<<<< -0x10 is right c: 48 31 c9 xor %rcx,%rcx f: 48 89 08 mov %rcx,(%rax) 12: 48 be 07 00 00 00 00 movabs $0x7,%rsi 19: 00 00 00 1c: 48 89 c7 mov %rax,%rdi <<<< used here correctly 1f: e8 00 00 00 00 callq 24 <_Dmain+0x24> 24: 48 8d 75 f0 lea -0x10(%rbp),%rsi /home/robert/projects/phobosx/source/app2.d:12 auto buf = atomicLoad(test); 28: 48 8d 7d f8 lea -0x8(%rbp),%rdi <<<< now -0x8, why? 2c: e8 00 00 00 00 callq 31 <_Dmain+0x31> It seems that the wrong address gets passed to atomicLoad. If you remove the constructor of Test the right address (-0x10) is used. Various transformation of this program all have the same wrong output: You can make test global, put it in a union together with a plain long, create a non shared temporary before assigning to the shared variable, use casts, ... The only thing that helps is removing the constructor.
Comment #1 by jfanatiker — 2013-07-15T03:10:02Z
Created attachment 1233 Full assembly dump
Comment #2 by mxfomin — 2014-08-14T06:50:31Z
I remember Walter was speaking that atomicLoad is restricted only to POD structs and structs with constructors are not POD. So, it is clear why it is not working (it also explains observation that removing constructor fixes the problem).
Comment #3 by edwards.ac — 2017-05-10T01:08:47Z
Tested on 2017-05-10 with DMD v2.074.0 on both Ubuntu 16.04 and macOS Sierra. Produces the expected output on both systems: buf: Test(7), orig: Test(7)
Comment #4 by ag0aep6g — 2019-08-18T23:25:27Z
(In reply to Andrew Edwards from comment #3) > Tested on 2017-05-10 with DMD v2.074.0 on both Ubuntu 16.04 and macOS > Sierra. Produces the expected output on both systems: > > buf: Test(7), orig: Test(7) Apparently works since DMD 2.065. Closing as worksforme.