Jump to page: 1 2
Thread overview
[Issue 15538] [REG 2.064] wrong code with switch
[Issue 15538] final switch statement raises an exception even though all cases are covered und certain conditions
Jan 10, 2016
Johannes
[Issue 15538] final switch statement raises an exception even though all cases are covered under certain conditions
Feb 12, 2016
Johannes Loher
Jun 13, 2016
Johannes Loher
Aug 08, 2016
Johannes Loher
Aug 09, 2016
Sobirari Muhomori
[Issue 15538] wrong code with switch
Aug 09, 2016
ag0aep6g@gmail.com
Oct 15, 2016
Johannes Loher
Apr 24, 2017
ag0aep6g@gmail.com
Apr 25, 2017
aneas
Apr 25, 2017
Ketmar Dark
Jul 01, 2017
Johannes Loher
Jul 01, 2017
ag0aep6g@gmail.com
Jul 01, 2017
Vladimir Panteleev
Jul 01, 2017
Vladimir Panteleev
Oct 07, 2017
Walter Bright
Oct 07, 2017
Walter Bright
January 10, 2016
https://issues.dlang.org/show_bug.cgi?id=15538

Johannes <johannes.loher@fg4f.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|enhancement                 |major

--
February 12, 2016
https://issues.dlang.org/show_bug.cgi?id=15538

Johannes Loher <johannes.loher@fg4f.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|final switch statement      |final switch statement
                   |raises an exception even    |raises an exception even
                   |though all cases are        |though all cases are
                   |covered und certain         |covered under certain
                   |conditions                  |conditions

--
June 13, 2016
https://issues.dlang.org/show_bug.cgi?id=15538

Johannes Loher <johannes.loher@fg4f.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Attachment #1573|0                           |1
        is obsolete|                            |

--- Comment #1 from Johannes Loher <johannes.loher@fg4f.de> ---
Created attachment 1600
  --> https://issues.dlang.org/attachment.cgi?id=1600&action=edit
new code example

--
August 08, 2016
https://issues.dlang.org/show_bug.cgi?id=15538

--- Comment #2 from Johannes Loher <johannes.loher@fg4f.de> ---
Everything seems to work fine when running the program from within gdb. It also does not seem to be a problem of final switch, but switch in general. I tried it with a usual switch clause, in that case It always goes to default:

--
August 09, 2016
https://issues.dlang.org/show_bug.cgi?id=15538

Sobirari Muhomori <dfj1esp02@sneakemail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code

--- Comment #3 from Sobirari Muhomori <dfj1esp02@sneakemail.com> ---
Does optimization flag -O affect the behavior?

--
August 09, 2016
https://issues.dlang.org/show_bug.cgi?id=15538

ag0aep6g@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ag0aep6g@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 ag0aep6g@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.

--
October 15, 2016
https://issues.dlang.org/show_bug.cgi?id=15538

--- Comment #5 from Johannes Loher <johannes.loher@fg4f.de> ---
In the reduced example, the bug also appears when running in gdb.

--
April 24, 2017
https://issues.dlang.org/show_bug.cgi?id=15538

ag0aep6g@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |alexander.breckel@gmail.com

--- Comment #6 from ag0aep6g@gmail.com ---
*** Issue 17347 has been marked as a duplicate of this issue. ***

--
April 25, 2017
https://issues.dlang.org/show_bug.cgi?id=15538

--- Comment #7 from aneas <alexander.breckel@gmail.com> ---
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:
----

00000000004271a8 <_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 2d                    ja     4271e7 <_D3app2f1FS3app1SZi+0x3f>
  4271ba:    48 8d 05 a7 3f 02 00     lea    0x23fa7(%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 e0                    jmpq   *%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.

--
April 25, 2017
https://issues.dlang.org/show_bug.cgi?id=15538

Ketmar Dark <ketmar@ketmar.no-ip.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ketmar@ketmar.no-ip.org

--
« First   ‹ Prev
1 2