diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index 3b345d025..c46f9686c 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -427,10 +427,10 @@ void CheckFunctions::checkLibraryMatchFunctions() else if (New) continue; - if (!Token::Match(tok, "%name% (") || Token::Match(tok, "for|if|while|switch|sizeof|catch|asm|return")) + if (!Token::Match(tok, "%name% (") || Token::Match(tok, "asm|sizeof|catch")) continue; - if (tok->varId() != 0 || tok->type() || tok->isStandardType()) + if (tok->varId() != 0 || tok->type() || tok->isStandardType() || tok->isControlFlowKeyword()) continue; if (tok->linkAt(1)->strAt(1) == "(") diff --git a/lib/token.cpp b/lib/token.cpp index e6a73925a..de5b3b47e 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -65,8 +65,23 @@ Token::~Token() delete _values; } +static const std::set controlFlowKeywords = make_container< std::set > () << + "goto" << + "do" << + "if" << + "else" << + "for" << + "while" << + "switch" << + "case" << + "break" << + "continue" << + "return"; + void Token::update_property_info() { + setFlag(fIsControlFlowKeyword, controlFlowKeywords.find(_str) != controlFlowKeywords.end()); + if (!_str.empty()) { if (_str == "true" || _str == "false") tokType(eBoolean); diff --git a/lib/token.h b/lib/token.h index d6c7c68a9..b5ff26e62 100644 --- a/lib/token.h +++ b/lib/token.h @@ -401,6 +401,9 @@ public: void isAttributePacked(bool value) { setFlag(fIsAttributePacked, value); } + bool isControlFlowKeyword() const { + return getFlag(fIsControlFlowKeyword); + } bool isOperatorKeyword() const { return getFlag(fIsOperatorKeyword); } @@ -889,12 +892,12 @@ private: fIsAttributeNothrow = (1 << 13), // __attribute__((nothrow)), __declspec(nothrow) fIsAttributeUsed = (1 << 14), // __attribute__((used)) fIsAttributePacked = (1 << 15), // __attribute__((packed)) - fIsOperatorKeyword = (1 << 16), // operator=, etc - fIsComplex = (1 << 17), // complex/_Complex type - fIsEnumType = (1 << 18), // enumeration type - - fIsName = (1 << 19), - fIsLiteral = (1 << 20), + fIsControlFlowKeyword = (1 << 16), // if/switch/while/... + fIsOperatorKeyword = (1 << 17), // operator=, etc + fIsComplex = (1 << 18), // complex/_Complex type + fIsEnumType = (1 << 19), // enumeration type + fIsName = (1 << 20), + fIsLiteral = (1 << 21), }; unsigned int _flags; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 76e586964..66a948bed 100755 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -8258,19 +8258,6 @@ void Tokenizer::validate() const cppcheckError(lastTok); } -static const std::set controlFlowKeywords = make_container< std::set > () << - "goto" << - "do" << - "if" << - "else" << - "for" << - "while" << - "switch" << - "case" << - "break" << - "continue" << - "return"; - const Token * Tokenizer::findGarbageCode() const { for (const Token *tok = tokens(); tok; tok = tok->next()) { @@ -8336,7 +8323,7 @@ const Token * Tokenizer::findGarbageCode() const return list.back(); if (Token::Match(list.back(), "void|char|short|int|long|float|double|const|volatile|static|inline|struct|class|enum|union|template|sizeof|case|break|continue|typedef")) return list.back(); - if ((list.back()->str()==")"||list.back()->str()=="}") && list.back()->previous() && controlFlowKeywords.find(list.back()->previous()->str()) != controlFlowKeywords.end()) + if ((list.back()->str()==")" || list.back()->str()=="}") && list.back()->previous() && list.back()->previous()->isControlFlowKeyword()) return list.back()->previous(); return nullptr; @@ -8346,7 +8333,7 @@ const Token * Tokenizer::findGarbageCode() const bool Tokenizer::isGarbageExpr(const Token *start, const Token *end) { for (const Token *tok = start; tok != end; tok = tok->next()) { - if (controlFlowKeywords.find(tok->str()) != controlFlowKeywords.end()) + if (tok->isControlFlowKeyword()) return true; if (tok->str() == ";") return true;