[Issue 15538] wrong code with switch
https://issues.dlang.org/show_bug.cgi?id=15538 --- Comment #8 from Johannes Loher --- I tracked this down a bit. It worked fine till 2.063.2 (including). From 2.064 onward it sarts to segfault. Finally, from 2.068 onward, the assert error starts hppening. --
[Issue 15538] wrong code with switch
https://issues.dlang.org/show_bug.cgi?id=15538 Ketmar Dark changed: What|Removed |Added CC||ket...@ketmar.no-ip.org --
[Issue 15538] wrong code with switch
https://issues.dlang.org/show_bug.cgi?id=15538 --- Comment #7 from aneas --- Further reduced: struct S { int a = 0; int b = 1; } int f1(S s) { switch (s.a) { case 0: return 10; case 1: return 20; case 2: return 30; case 3: return 40; default: return 99; } } void main() { S s; assert(f1(s) == 10); /* fails */ } The generates assembly for f1 is this: 004271a8 <_D3app2f1FS3app1SZi>: 4271a8:55 push %rbp 4271a9:48 8b ec mov%rsp,%rbp 4271ac:48 83 ec 10 sub$0x10,%rsp 4271b0:48 89 7d f8 mov%rdi,-0x8(%rbp) 4271b4:48 83 ff 03 cmp$0x3,%rdi 4271b8:77 2dja 4271e7 <_D3app2f1FS3app1SZi+0x3f> 4271ba:48 8d 05 a7 3f 02 00 lea0x23fa7(%rip),%rax# 44b168 <_D3app1S6__initZ+0x8> 4271c1:48 63 0c b8 movslq (%rax,%rdi,4),%rcx 4271c5:48 8d 04 01 lea(%rcx,%rax,1),%rax 4271c9:ff e0jmpq *%rax 4271cb:b8 0a 00 00 00 mov$0xa,%eax 4271d0:c9 leaveq 4271d1:c3 retq 4271d2:b8 14 00 00 00 mov$0x14,%eax 4271d7:c9 leaveq 4271d8:c3 retq 4271d9:b8 1e 00 00 00 mov$0x1e,%eax 4271de:c9 leaveq 4271df:c3 retq 4271e0:b8 28 00 00 00 mov$0x28,%eax 4271e5:c9 leaveq 4271e6:c3 retq 4271e7:b8 63 00 00 00 mov$0x63,%eax 4271ec:c9 leaveq 4271ed:c3 retq ... Dmd packs the whole struct into a single register (%rdi). Since the switch statement contains consecutive cases, Dmd rightfully tries to skip as many of them as possible by doing a single comparison (cmp $0x3,%rdi). However, this comparison is performed on the whole register, which also contains the second field of the Struct. --
[Issue 15538] wrong code with switch
https://issues.dlang.org/show_bug.cgi?id=15538 ag0ae...@gmail.com changed: What|Removed |Added CC||alexander.brec...@gmail.com --- Comment #6 from ag0ae...@gmail.com --- *** Issue 17347 has been marked as a duplicate of this issue. *** --
[Issue 15538] wrong code with switch
https://issues.dlang.org/show_bug.cgi?id=15538 --- Comment #5 from Johannes Loher --- In the reduced example, the bug also appears when running in gdb. --
[Issue 15538] wrong code with switch
https://issues.dlang.org/show_bug.cgi?id=15538 ag0ae...@gmail.com changed: What|Removed |Added CC||ag0ae...@gmail.com Summary|final switch statement |wrong code with switch |raises an exception even| |though all cases are| |covered under certain | |conditions | --- Comment #4 from ag0ae...@gmail.com --- Reduced a bit more: struct S { int a = 0; int b = 1; } int f1(int a) { switch (a) { case 0: return 10; case 1: return 20; case 2: return 30; case 3: return 40; default: return 99; } } int f2(S s) { return f1(s.a); } void main() { S s; assert(f1(s.a) == 10); /* passes */ assert(f2(s) == 10); /* fails */ } (In reply to Sobirari Muhomori from comment #3) > Does optimization flag -O affect the behavior? No. -inline has an effect, presumably because f2 is inlined. --