diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 6d981396d..f238c56ee 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1602,6 +1602,19 @@ bool Tokenizer::tokenize(std::istream &code, return false; } + // if (x) MACRO() .. + for (const Token *tok = list.front(); tok; tok = tok->next()) { + if (Token::simpleMatch(tok, "if (")) { + tok = tok->next()->link(); + if (Token::Match(tok, ") %var% (") && + tok->next()->isUpperCaseName() && + Token::Match(tok->linkAt(2), ") {|else")) { + syntaxError(tok->next()); + return false; + } + } + } + // replace 'NULL' and similar '0'-defined macros with '0' simplifyNull(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index b81f5a25e..1a4f01526 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -799,8 +799,15 @@ private: void wrong_syntax_if_macro() { // #2518 #4171 - const std::string code("void f() { if MACRO(); }"); - tokenizeAndStringify(code.c_str(), false); + tokenizeAndStringify("void f() { if MACRO(); }", false); + ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); + + // #4668 - note there is no semicolon after MACRO() + tokenizeAndStringify("void f() { if (x) MACRO() {} }", false); + ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); + + // #4810 - note there is no semicolon after MACRO() + tokenizeAndStringify("void f() { if (x) MACRO() else ; }", false); ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); }