Jump to page: 1 2
Thread overview
[Issue 5713] New: Broken final switch on ints
Mar 07, 2011
Stewart Gordon
Jan 24, 2012
Walter Bright
Jan 24, 2012
Denis
Jan 24, 2012
Denis
Feb 05, 2012
yebblies
Aug 31, 2012
Rene
March 07, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5713

           Summary: Broken final switch on ints
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: accepts-invalid
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: bearophile_hugs@eml.cc


--- Comment #0 from bearophile_hugs@eml.cc 2011-03-07 04:27:15 PST ---
The purpose of "final switch" is to increase code safety compared to normal switches on enums. This D2 program compiles and runs with no errors (dmd 2.052):


void main() {
    int x = 100;
    final switch (x % 3) {
        case 0: break;
        case 1: break;
    }
}


Two possible ways for the D compiler to manage this code:
- Disallow it, not allowing final switches on int values;
- Manage it correctly and require the case "case 2:" too.
- (A third possibility: ignore the limited range of the switching value and
requiring coverage of the whole integer range, but this is not a good
solution).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 07, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5713


Stewart Gordon <smjg@iname.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |spec, wrong-code
                 CC|                            |smjg@iname.com


--- Comment #1 from Stewart Gordon <smjg@iname.com> 2011-03-07 05:39:56 PST ---
At first I thought maybe it was ignoring the error out of knowledge that x % 3 == 1 in this instance.  But no - it still accepts (and runs without even a SwitchError) if I change x to 101.

But you'd need to cover -1 and -2 as well for this to make sense.

The spec doesn't actually disallow it: http://www.digitalmars.com/d/2.0/statement.html#FinalSwitchStatement

"A final switch statement is just like a switch statement, except that:

    * No DefaultStatement is allowed.
    * No CaseRangeStatements are allowed.
    * If the switch Expression is of enum type, all the enum members must
appear in the CaseStatements.
    * The case expressions cannot evaluate to a run time initialized value."

But this seems to be a mistake, and that no SwitchError is thrown strikes me as a bug.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 08, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5713



--- Comment #2 from bearophile_hugs@eml.cc 2011-03-07 16:17:51 PST ---
See also bug 5714

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 26, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5713



--- Comment #3 from bearophile_hugs@eml.cc 2011-05-26 15:57:36 PDT ---
See also bug 6060

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 20, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5713



--- Comment #4 from bearophile_hugs@eml.cc 2011-08-20 14:05:58 PDT ---
This code is a reduction of real code, with small changes. It shows why this final switch brokeness makes final switch not as safe as advertised:


void main() {
    enum Foo { A, B }
    enum Bar { C = 5, D = 6 }
    int fe; // first mistake, fe is not Foo
    bool someCondition = true;
    if (someCondition)
        fe = Bar.C; // second mistake, fe is not assigned to a Foo
    final switch (fe) {
        case Foo.A: break;
        case Foo.B: break;
    }
}


The code contains two mistakes, the first is giving fe int type instead of Foo. The second mistake is assigning  to fe an invalid enum value. The final switch doesn't catch the wrong enum value of fe, and it asks for no default case because it's supposed to be complete. The final switch spec need to be improved.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 07, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5713



--- Comment #5 from bearophile_hugs@eml.cc 2011-09-07 10:15:54 PDT ---
An example from Timon Gehr, this gives no compilation errors, and prints nothing:


import std.stdio;
enum Mode { nothing, read, write }
void main() {
    final switch (Mode.read | Mode.write) {
        case Mode.nothing: writeln(0); break;
        case Mode.read:    writeln(1); break;
        case Mode.write:   writeln(2); break;
    }
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 24, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=5713



--- Comment #6 from github-bugzilla@puremagic.com 2012-01-24 01:04:53 PST ---
Commit pushed to https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/11738ba260ced4d522d2334c5e99059a2517035d fix Issue 5713 - Broken final switch on ints

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 24, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=5713


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |bugzilla@digitalmars.com
         Resolution|                            |FIXED


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 24, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=5713


Denis <verylonglogin.reg@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |verylonglogin.reg@gmail.com


--- Comment #7 from Denis <verylonglogin.reg@gmail.com> 2012-01-24 15:01:58 MSK ---
(In reply to comment #5)
> An example from Timon Gehr, this gives no compilation errors, and prints nothing:
> 
> 
> import std.stdio;
> enum Mode { nothing, read, write }
> void main() {
>     final switch (Mode.read | Mode.write) {
>         case Mode.nothing: writeln(0); break;
>         case Mode.read:    writeln(1); break;
>         case Mode.write:   writeln(2); break;
>     }
> }

Created issue 7358 inspired by this (inspired but different because this code can be statically rejected).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 24, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=5713


Denis <verylonglogin.reg@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|FIXED                       |


--- Comment #8 from Denis <verylonglogin.reg@gmail.com> 2012-01-24 15:09:27 MSK ---
As bearophile wrote in issue 6060 description:
>in 5713 I don't like an error message (and I'd like the compiler to enforce the presence of the cases for 0,1, and 2)

So this issue requires the following function be compilable _iff_ every `case` is present:
---
void f(int x) {
    final switch (x % 3) {
        case -2:
        case -1:
        case 0:
        case 1:
        case 2:
    }
}
---

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
« First   ‹ Prev
1 2