diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index e05f73e5e..6231fd88d 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1579,6 +1579,32 @@ bool Tokenizer::tokenize(std::istream &code, syntaxError(tok); return false; } + } else if (Token::simpleMatch(tok, "if (")) { + bool macro = false; + unsigned int parlevel = 0; + for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) { + if (tok2->str() == "(") + ++parlevel; + else if (parlevel > 0 && tok2->str() == ")") { + --parlevel; + if (parlevel == 0) { + if (Token::Match(tok2, ") %var% [({]") && tok2->next()->isUpperCaseName()) + macro = true; + else if (!macro) + break; + } + } + if (tok2->str() == ";") + break; + if (tok2->str() == "{") { + if (macro) { + syntaxError(tok2); + return false; + } else { + break; + } + } + } } } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 6e3c5031e..d4135a612 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -770,6 +770,12 @@ private: const std::string code("void f() { if MACRO(); }"); tokenizeAndStringify(code.c_str(), false); ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); + + // #4668 + errout.str(""); + const char code2[] = "void f() { if (x) MACRO() {} }"; + tokenizeAndStringify(code2, false); + ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); } void wrong_syntax_class_x_y() {