diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 5a7353da7..640404bbe 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -8352,16 +8352,26 @@ void Tokenizer::findGarbageCode() const if (Token::simpleMatch(tok, "switch (")) { if (Token::simpleMatch(tok->linkAt(1), ") {")) { tok = tok->linkAt(1)->linkAt(1); - } else { - const Token *switchToken = tok; - tok = tok->linkAt(1); - while (tok && !Token::Match(tok, "[;{}]")) - tok = tok->next(); - if (!tok) - syntaxError(switchToken); - if (tok->str() != ";") - syntaxError(tok); + continue; } + const Token *switchToken = tok; + tok = tok->linkAt(1); + if (!tok) + syntaxError(switchToken); + // Look for the end of the switch statement, i.e. the first semi-colon or '}' + for ( ; tok ; tok = tok->next()) { + if (tok->str() == "{") { + tok = tok->link(); + } + if (Token::Match(tok, ";|}")) { + // We're at the end of the switch block + if (tok->str() == "}" && tok->strAt(-1) == ":") // Invalid case + syntaxError(switchToken); + break; + } + } + if (!tok) + break; } else if (tok->str() == "(") { tok = tok->link(); } else if (tok->str() == "case") { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index ddb456a29..cb404b802 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -4776,6 +4776,24 @@ private: //ticket #8477 ASSERT_EQUALS("void foo ( ) { enum Anonymous0 : int { Six = 6 } ; return Six ; }", tokenizeAndStringify("void foo () { enum : int { Six = 6 } ; return Six ; }")); + // ticket #8281 + tokenizeAndStringify("void lzma_decode(int i) { " + " bool state; " + " switch (i) " + " while (true) { " + " state=false; " + " case 1: " + " ; " + " }" + "}"); + // ticket #8417 + tokenizeAndStringify("void printOwnedAttributes(int mode) { " + " switch(mode) case 0: { break; } " + "}"); + ASSERT_THROW(tokenizeAndStringify("void printOwnedAttributes(int mode) { " + " switch(mode) case 0: { break; } case 1: ; " + "}"), + InternalError); } void simplifyPointerToStandardType() {