digitalmars.D.bugs - [Issue 16521] New: Wrong code generation with switch + static foreach
- via Digitalmars-d-bugs (87/87) Sep 21 2016 https://issues.dlang.org/show_bug.cgi?id=16521
https://issues.dlang.org/show_bug.cgi?id=16521 Issue ID: 16521 Summary: Wrong code generation with switch + static foreach Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: major Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: mathias.lang sociomantic.com The following code: ``` void main () { sformat(0, uint.max); } void sformat (Args...) (int index, Args args) { JT: switch (index) { foreach (idx, unused; args) { case idx: assert(unused == args[idx], "Borken compiler"); break JT; } default: assert(0); } } ``` Triggers the assert. Obviously `unused` and `args[idx]` should always be the same. Here's the generated ASM: ``` 000000000042237c <D main>: 42237c: 55 push %rbp 42237d: 48 8b ec mov %rsp,%rbp 422380: 31 f6 xor %esi,%esi 422382: bf ff ff ff ff mov $0xffffffff,%edi 422387: e8 08 00 00 00 callq 422394 <test.sformat!(uint).sformat(int, uint)> 42238c: 31 c0 xor %eax,%eax 42238e: 5d pop %rbp 42238f: c3 retq 422390: 0f 1f 40 00 nopl 0x0(%rax) 0000000000422394 <test.sformat!(uint).sformat(int, uint)>: 422394: 55 push %rbp 422395: 48 8b ec mov %rsp,%rbp 422398: 48 83 ec 20 sub $0x20,%rsp 42239c: 89 7d f8 mov %edi,-0x8(%rbp) 42239f: 85 f6 test %esi,%esi 4223a1: 74 02 je 4223a5 <test.sformat!(uint).sformat(int, uint)+0x11> 4223a3: eb 37 jmp 4223dc <test.sformat!(uint).sformat(int, uint)+0x48> 4223a5: 8b 45 f0 mov -0x10(%rbp),%eax ; <== Access to unitialized variable `unused` 4223a8: 3b 45 f8 cmp -0x8(%rbp),%eax 4223ab: 74 2d je 4223da <test.sformat!(uint).sformat(int, uint)+0x46> 4223ad: 41 b8 0d 00 00 00 mov $0xd,%r8d 4223b3: b9 00 54 44 00 mov $0x445400,%ecx 4223b8: b8 06 00 00 00 mov $0x6,%eax 4223bd: 48 89 c2 mov %rax,%rdx 4223c0: 48 89 55 e8 mov %rdx,-0x18(%rbp) 4223c4: ba 07 54 44 00 mov $0x445407,%edx 4223c9: bf 0f 00 00 00 mov $0xf,%edi 4223ce: 48 89 d6 mov %rdx,%rsi 4223d1: 48 8b 55 e8 mov -0x18(%rbp),%rdx 4223d5: e8 ce 00 00 00 callq 4224a8 <_d_assert_msg> 4223da: eb 0a jmp 4223e6 <test.sformat!(uint).sformat(int, uint)+0x52> 4223dc: bf 12 00 00 00 mov $0x12,%edi 4223e1: e8 2e 00 00 00 callq 422414 <test.__assert(int)> 4223e6: c9 leaveq 4223e7: c3 retq 4223e8: 0f 1f 40 00 nopl 0x0(%rax) ``` Tested with v2.070.0 and v2.071.1 The latest master (cce7909) hints at the bug: test.d(8): Deprecation: 'switch' skips declaration of variable test.sformat!uint.sformat.unused at test.d(10) --
Sep 21 2016