Bug 14587 – [REG2.064] generated 64 bit code for switch jump tables is wrong

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
All
Creation time
2015-05-15T13:08:00Z
Last change time
2017-07-01T11:33:12Z
Keywords
wrong-code
Assigned to
nobody
Creator
robpieke
See also
https://issues.dlang.org/show_bug.cgi?id=15538

Comments

Comment #0 by robpieke — 2015-05-15T13:08:02Z
(reporting as an issue - suggested by John Colvin) I'm consistently getting "Segmentation fault: 11" (dmd 2.067.1, OSX) on the code below. I can't figure out where things are going wrong, because any attempt I make to debug via extra print statements causes the program to run successfully. Same if I try to compile with "-gc" ... it suddenly starts working, so I can't debug with gdb. And the code similarly seems to work fine with ldc2. Many thanks in advance! * * * import std.stdio; enum Suit { HEARTS, DIAMONDS, CLUBS, SPADES } enum Value { ACE = 1, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING } struct Card { Value value; Suit suit; } void printCard(in Card card) { final switch(card.value) { case Value.ACE: write("A"); break; case Value.TWO, Value.THREE, Value.FOUR, Value.FIVE, Value.SIX, Value.SEVEN, Value.EIGHT, Value.NINE, Value.TEN: writef("%d", card.value); break; case Value.JACK: write("J"); break; case Value.QUEEN: write("Q"); break; case Value.KING: write("K"); break; } final switch(card.suit) { case Suit.HEARTS: write("♡"); break; case Suit.DIAMONDS: write("♢"); break; case Suit.CLUBS: write("♣"); break; case Suit.SPADES: write("♠"); break; } write("\n"); } int main() { auto card = Card(Value.JACK, Suit.CLUBS); printCard(card); return 0; }
Comment #1 by schveiguy — 2015-05-15T13:49:31Z
A reduced version: struct Card { int value; int suit; } void foo(Card card) { switch(card.value) { case 4: case 5: case 6: case 11: break; default: } } void main() { auto card = Card(11, 1); foo(card); } Changing anything at this point seems to make it run properly.
Comment #2 by robpieke — 2015-05-15T16:14:32Z
Thanks for reducing it Steven! I also did a bit more leg-work. It could be coincidence, but the code seems to work in DMD 2.063.2 and below and fails in 2.064 and above. Not only OSX. Linux (64-bit) at a minimum as well.
Comment #3 by schuetzm — 2015-05-15T16:25:53Z
FWIW, I can reproduce it with DMD master on Linux x86_64. Interestingly, compiling with debug info makes the SEGV go away.
Comment #4 by schuetzm — 2015-05-15T16:36:06Z
It crashes upon entering the jump table: (gdb) disas Dump of assembler code for function _D2xx3fooFS2xx4CardZv: 0x000000000041c7b0 <+0>: push %rbp 0x000000000041c7b1 <+1>: mov %rsp,%rbp 0x000000000041c7b4 <+4>: sub $0x10,%rsp 0x000000000041c7b8 <+8>: mov %rdi,-0x8(%rbp) 0x000000000041c7bc <+12>: cmp $0xb,%edi 0x000000000041c7bf <+15>: ja 0x41c7c8 <_D2xx3fooFS2xx4CardZv+24> => 0x000000000041c7c1 <+17>: jmpq *0x4374f8(,%rdi,8) 0x000000000041c7c8 <+24>: leaveq 0x000000000041c7c9 <+25>: retq (gdb) print $edi $1 = 11 (gdb) print $rdi $2 = 4294967307 As you can see, %edi contains the correct offset, but it uses %rdi as an index. Most likely a bug in the code generator.
Comment #5 by dlang-bugzilla — 2015-05-17T05:42:26Z
Comment #6 by bugzilla — 2015-05-17T16:37:01Z
Great job, everyone, in tracking this one down. You guys have nailed it. It's critical. I'll work on a fix.
Comment #7 by bugzilla — 2015-05-17T16:51:34Z
Comment #8 by github-bugzilla — 2015-05-17T20:28:07Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/4f779561f89e12ff45e30996ad3c8217eb7522e2 fix Issue 14587 - DMD 2.067.1 generating crashing binary on OSX https://github.com/D-Programming-Language/dmd/commit/a7d1edb3c17282994c53fdc797dc3d15f3919d68 Merge pull request #4666 from WalterBright/fix14587 fix Issue 14587 - generated 64 bit code for switch jump tables is wrong
Comment #9 by github-bugzilla — 2015-05-17T20:39:51Z
Commit pushed to dmd-1.x at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/51185a88a63762c5347b729e26ab9540c34201da Merge pull request #4666 from WalterBright/fix14587 fix Issue 14587 - generated 64 bit code for switch jump tables is wrong
Comment #10 by schveiguy — 2015-05-18T12:38:48Z
Awesome! Nice work everyone.
Comment #11 by robpieke — 2015-05-18T13:32:17Z
Wow ... that was a productive weekend! Looking forward to this working its way into a future homebrew update! :D
Comment #12 by github-bugzilla — 2015-06-17T21:05:15Z