[Issue 16521] New: Wrong code generation with switch + static foreach
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Wed Sep 21 12:54:33 PDT 2016
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 at puremagic.com
Reporter: mathias.lang at 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)
--
More information about the Digitalmars-d-bugs
mailing list