Fixes issue with case inside switch that is not a compound statement (#1031)
* Fixes issue with case inside switch that is not a compound statement was treated as garbage This fixes an issue with the check for case keywords outside of switch detection that would treat a case statement inside a switch that is not a compound statement as garbage, but this is perfectly valid C++. This construct is used in several libraries, i.e. Google Test. * Tweak check and handle missing semicolon Tweaks the check with feedback from danmar. Handle the case where there is no semicolon and document it with a unit test.
This commit is contained in:
parent
5b6ec49a6f
commit
4d18d3948f
|
@ -8346,13 +8346,23 @@ const Token * Tokenizer::findGarbageCode() const
|
||||||
|
|
||||||
// case keyword must be inside switch
|
// case keyword must be inside switch
|
||||||
for (const Token *tok = tokens(); tok; tok = tok->next()) {
|
for (const Token *tok = tokens(); tok; tok = tok->next()) {
|
||||||
if (Token::simpleMatch(tok, "switch (") && Token::simpleMatch(tok->linkAt(1), ") {"))
|
if (Token::simpleMatch(tok, "switch (")) {
|
||||||
|
if (Token::simpleMatch(tok->linkAt(1), ") {")) {
|
||||||
tok = tok->linkAt(1)->linkAt(1);
|
tok = tok->linkAt(1)->linkAt(1);
|
||||||
else if (tok->str() == "(")
|
} else {
|
||||||
tok = tok->link();
|
while (tok->str() != ";" && tok->str() != "{") {
|
||||||
else if (tok->str() == "case")
|
if (tok->next() == nullptr) {
|
||||||
return tok;
|
return tok;
|
||||||
}
|
}
|
||||||
|
tok = tok->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (tok->str() == "(") {
|
||||||
|
tok = tok->link();
|
||||||
|
} else if (tok->str() == "case") {
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const Token *tok = tokens(); tok ; tok = tok->next()) {
|
for (const Token *tok = tokens(); tok ; tok = tok->next()) {
|
||||||
if (!Token::simpleMatch(tok, "for (")) // find for loops
|
if (!Token::simpleMatch(tok, "for (")) // find for loops
|
||||||
|
|
|
@ -379,6 +379,9 @@ private:
|
||||||
|
|
||||||
//ticket #4267
|
//ticket #4267
|
||||||
ASSERT_THROW(checkCode("f ( ) { switch break; { switch ( x ) { case } case break; -6: ( ) ; } }"), InternalError);
|
ASSERT_THROW(checkCode("f ( ) { switch break; { switch ( x ) { case } case break; -6: ( ) ; } }"), InternalError);
|
||||||
|
|
||||||
|
// Missing semicolon
|
||||||
|
ASSERT_THROW(checkCode("void foo () { switch(0) case 0 : default : }"), InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode1() {
|
void garbageCode1() {
|
||||||
|
|
|
@ -4750,6 +4750,9 @@ private:
|
||||||
//ticket #3227
|
//ticket #3227
|
||||||
ASSERT_EQUALS("void foo ( ) { switch ( n ) { label : ; case 1 : ; label1 : ; label2 : ; break ; } }",
|
ASSERT_EQUALS("void foo ( ) { switch ( n ) { label : ; case 1 : ; label1 : ; label2 : ; break ; } }",
|
||||||
tokenizeAndStringify("void foo(){ switch (n){ label: case 1: label1: label2: break; }}"));
|
tokenizeAndStringify("void foo(){ switch (n){ label: case 1: label1: label2: break; }}"));
|
||||||
|
//ticket #8345
|
||||||
|
ASSERT_EQUALS("void foo ( ) { switch ( 0 ) { case 0 : ; default : ; } }",
|
||||||
|
tokenizeAndStringify("void foo () { switch(0) case 0 : default : ; }"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void simplifyPointerToStandardType() {
|
void simplifyPointerToStandardType() {
|
||||||
|
|
Loading…
Reference in New Issue