Skip to content

Commit

Permalink
This is patch for issue no 192 'no error on missing defaut in non-fin…
Browse files Browse the repository at this point in the history
…al switches'

It check for LabeledStatements with "default" label and sets flag to indicate such statement.
If flag is already set and such statement found it reports error.
No Default statement found then also reports error.
nested cases is also handled.
Changes in file : libd/src/d/semantic/flow.d
New files : tests/test0184.d
            tests/test0185.d
            tests/test0186.d
            tests/test0187.d
  • Loading branch information
vivekvpandya committed Feb 16, 2016
1 parent a0cfe4a commit d3ab7a2
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 2 deletions.
25 changes: 23 additions & 2 deletions libd/src/d/semantic/flow.d
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ private:
bool, "allowFallthrough", 1,
bool, "switchMustTerminate", 1,
bool, "switchFunTerminate", 1,
uint, "", 2,
bool, "switchHaveDefault", 1,
uint, "", 1,
));

public:
Expand Down Expand Up @@ -196,6 +197,7 @@ public:
auto oldSwitchMustTerminate = switchMustTerminate;
auto oldSwitchFunTerminate = switchFunTerminate;
auto oldBlockTerminate = blockTerminate;
auto oldSwitchHaveDefault = switchHaveDefault;

scope(exit) {
mustTerminate = switchMustTerminate && mustTerminate;
Expand All @@ -207,14 +209,23 @@ public:
allowFallthrough = oldAllowFallthrough;
switchMustTerminate = oldSwitchMustTerminate;
switchFunTerminate = oldSwitchFunTerminate;
switchHaveDefault = oldSwitchHaveDefault;
}

switchStmt = s;
switchStack = varStack;
allowFallthrough = true;
switchFunTerminate = true;

switchHaveDefault = false;
visit(s.statement);

if (!switchHaveDefault) {
import d.exception;
throw new CompileException(
s.location,
"switch statement without a default; use 'final switch' or add 'default: assert(0);' or add 'default: break;'",
);
}
}

void visit(BreakStatement s) {
Expand Down Expand Up @@ -318,6 +329,16 @@ public:
void visit(LabeledStatement s) {
auto label = s.label;
if (label == BuiltinName!"default") {
if (switchHaveDefault) {
import d.exception;
throw new CompileException(
s.location,
"switch statements with multiple defaults are not allowed.",
);
}

switchHaveDefault = true;

setCaseEntry(
s.location,
"Default statement can only appear within switch statement.",
Expand Down
19 changes: 19 additions & 0 deletions tests/test0184.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//T compiles:no
//T retval:0
//T has-passed:yes
// Tests multiple default in non-final switches

int main() {
int x = 10;
switch(x) {
case 0:
return 1;
case 2:
return 2;
default:
return 5;
default:
return 7;
}
}

32 changes: 32 additions & 0 deletions tests/test0185.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//T compiles:yes
//T retval:0
//T has-passed:yes
// Tests nested switch
int main() {
int x = 10;
switch (x) {
case 1 :
switch (x) {
default :
break;
}
break;
case 2 :
switch (x) {
default :
break;
case 1 :
switch (x) {
default :
break;
}
break;
}
break;

default :
break;
}

return 0;
}
21 changes: 21 additions & 0 deletions tests/test0186.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//T compiles:no
//T retval:0
//T has-passed:yes
// Tests nested default for no error on missing defaut in non-final switches
int main() {
int x = 10;
switch(x) {
case 1 :
switch (x) {
case 1 :
break;
}
case 2 :
switch (x) {
default :
break;
}
default :
break;
}
}
15 changes: 15 additions & 0 deletions tests/test0187.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//T compiles:no
//T retval:0
//T has-passed:yes
// Tests missing default in non-final switches

int main() {
int x = 10;
switch(x) {
case 0:
return 1;
case 2:
return 2;
}
}

0 comments on commit d3ab7a2

Please sign in to comment.