diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 15af853aa..ccde0dd0a 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -7444,9 +7444,18 @@ Token * Tokenizer::initVar(Token * tok) void Tokenizer::elseif() { for (Token *tok = list.front(); tok; tok = tok->next()) { - if (!Token::simpleMatch(tok, "else if")) + if (tok->str() != "else") continue; + if (!Token::Match(tok->previous(), ";|}")) + syntaxError(tok->previous()); + + if (!Token::Match(tok->next(), "%name%")) + continue; + + if (tok->strAt(1) != "if") + unknownMacroError(tok->next()); + for (Token *tok2 = tok; tok2; tok2 = tok2->next()) { if (Token::Match(tok2, "(|{|[")) tok2 = tok2->link(); @@ -10258,8 +10267,15 @@ void Tokenizer::simplifyNamespaceAliases() Token * tokNameStart = tok->tokAt(3); Token * tokNameEnd = tokNameStart; - while (tokNameEnd && tokNameEnd->next() && tokNameEnd->next()->str() != ";") + while (tokNameEnd && tokNameEnd->next() && tokNameEnd->next()->str() != ";") { + if (tokNameEnd->str() == "(") { + if (tokNameEnd->previous()->isName()) + unknownMacroError(tokNameEnd->previous()); + else + syntaxError(tokNameEnd); + } tokNameEnd = tokNameEnd->next(); + } if (!tokNameEnd) return; // syntax error diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 4a1af60f9..83219bacf 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -548,11 +548,12 @@ private: void garbageCode23() { //garbage code : don't crash (#3481) - checkCode("{\n" - " if (1) = x\n" - " else abort s[2]\n" - "}"); - ASSERT_EQUALS("", errout.str()); + ASSERT_THROW_EQUALS(checkCode("{\n" + " if (1) = x\n" + " else abort s[2]\n" + "}"), + InternalError, + "syntax error"); } void garbageCode24() { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index b9f66926c..7d93aa6c5 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -6938,6 +6938,23 @@ private: InternalError, "There is an unknown macro here somewhere. Configuration is required. If MACRO is a macro then please configure it."); + ASSERT_THROW_EQUALS(tokenizeAndStringify("void f(int i) {\n" // #11770 + " if (i == 0) {}\n" + " else if (i == 1) {}\n" + " else\n" + " MACRO(i)\n" + "}\n" + "void g() {}\n"), + InternalError, + "There is an unknown macro here somewhere. Configuration is required. If MACRO is a macro then please configure it."); + ASSERT_NO_THROW(tokenizeAndStringify("void f(int i) {\n" + " if (i == 0) {}\n" + " else if (i == 1) {}\n" + " else\n" + " MACRO(i);\n" + "}\n" + "void g() {}\n")); + ASSERT_THROW_EQUALS(tokenizeAndStringify("class C : public QObject {\n" // #11770 " struct S { static void g() {} };\n" "private Q_SLOTS:\n" @@ -6952,6 +6969,15 @@ private: "};\n"), InternalError, "There is an unknown macro here somewhere. Configuration is required. If slots is a macro then please configure it."); + + ASSERT_THROW_EQUALS(tokenizeAndStringify("namespace U_ICU_ENTRY_POINT_RENAME(icu) { }\n" + "namespace icu = U_ICU_ENTRY_POINT_RENAME(icu);\n" + "namespace U_ICU_ENTRY_POINT_RENAME(icu) {\n" + " class BreakIterator;\n" + "}\n" + "typedef int UStringCaseMapper(icu::BreakIterator* iter);\n"), + InternalError, + "There is an unknown macro here somewhere. Configuration is required. If U_ICU_ENTRY_POINT_RENAME is a macro then please configure it."); }