diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 437654947..b4b40f916 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1736,7 +1736,8 @@ bool Tokenizer::tokenize(std::istream &code, arraySize(); // simplify labels and 'case|default'-like syntaxes - simplifyLabelsCaseDefault(); + if (!simplifyLabelsCaseDefault()) + return false; // simplify '[;{}] * & ( %any% ) =' to '%any% =' simplifyMulAndParens(); @@ -2354,7 +2355,7 @@ void Tokenizer::arraySize() /** simplify labels and case|default in the code: add a ";" if not already in.*/ -void Tokenizer::simplifyLabelsCaseDefault() +bool Tokenizer::simplifyLabelsCaseDefault() { bool executablescope = false; unsigned int indentlevel = 0; @@ -2389,15 +2390,19 @@ void Tokenizer::simplifyLabelsCaseDefault() if (Token::Match(tok->next(),"[:{};]")) break; } - if (tok->next()->str() == ":" && tok->strAt(2) != ";") { + if (tok->str() != "case" && tok->next()->str() == ":" && tok->strAt(2) != ";") { tok = tok->next(); tok->insertToken(";"); + } else { + syntaxError(tok); + return false; } } else if (Token::Match(tok, "[;{}] %var% : !!;")) { tok = tok->tokAt(2); tok->insertToken(";"); } } + return true; } diff --git a/lib/tokenize.h b/lib/tokenize.h index 5cd825d90..186eb95b9 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -163,8 +163,11 @@ public: /** Insert array size where it isn't given */ void arraySize(); - /** Simplify labels and 'case|default' syntaxes */ - void simplifyLabelsCaseDefault(); + /** Simplify labels and 'case|default' syntaxes. + * @return true if found nothing or the syntax is correct. + * false if syntax is found to be wrong. + */ + bool simplifyLabelsCaseDefault(); /** Remove macros in global scope */ void removeMacrosInGlobalScope(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index c7a18de52..a4b8450e6 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -66,6 +66,7 @@ private: TEST_CASE(wrong_syntax3); // #3544 TEST_CASE(wrong_syntax4); // #3618 TEST_CASE(wrong_syntax_if_macro); // #2518 - if MACRO() + TEST_CASE(wrong_syntax_case_default); TEST_CASE(garbageCode); TEST_CASE(foreach); // #3690 @@ -722,6 +723,20 @@ private: ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); } + void wrong_syntax_case_default() { + { + //ticket #4234 + tokenizeAndStringify("( ) { switch break ; { switch ( x ) { case } y break ; : } }"); + ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); + } + + { + //ticket #4267 + tokenizeAndStringify("f ( ) { switch break; { switch ( x ) { case } case break; -6: ( ) ; } }"); + ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); + } + } + void garbageCode() { tokenizeAndStringify("struct x foo_t; foo_t typedef y;"); }