[Issue 15538] wrong code with switch

2017-07-01 Thread via Digitalmars-d-bugs
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

2017-04-25 Thread via Digitalmars-d-bugs
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

2017-04-25 Thread via Digitalmars-d-bugs
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

2017-04-24 Thread via Digitalmars-d-bugs
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

2016-10-16 Thread via Digitalmars-d-bugs
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

2016-08-09 Thread via Digitalmars-d-bugs
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.

--