diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 9d766c2e0..aeb66c945 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -140,34 +140,6 @@ void CheckLeakAutoVar::check() } } -static bool isVariableComparison(const Token *tok, const std::string &comp, const char rhs[], const Token **vartok) -{ - *vartok = nullptr; - if (tok->isComparisonOp()) { - if (Token::Match(tok->astOperand1(), rhs)) { - // Invert comparator - std::string s = tok->str(); - if (s[0] == '>') - s[0] = '<'; - else if (s[0] == '<') - s[0] = '>'; - if (s == comp) { - *vartok = tok->astOperand2(); - } - } else if (Token::Match(tok->astOperand2(), rhs) && tok->str() == comp) { - *vartok = tok->astOperand1(); - } - } else if (comp == "!=" && rhs == std::string("0")) { - *vartok = tok; - } else if (comp == "==" && rhs == std::string("0")) { - if (tok->str() == "!") - *vartok = tok->astOperand1(); - } - if ((*vartok) && (*vartok)->varId() == 0U) - *vartok = nullptr; - return (*vartok != nullptr); -} - void CheckLeakAutoVar::checkScope(const Token * const startToken, VarInfo *varInfo, std::set notzero) @@ -316,42 +288,19 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken, VarInfo varInfo1(*varInfo); // VarInfo for if code VarInfo varInfo2(*varInfo); // VarInfo for else code - // parse condition - std::stack tokens; - tokens.push(tok->next()->astOperand2()); - while (!tokens.empty()) { - const Token *tok3 = tokens.top(); - tokens.pop(); - if (!tok3) - continue; - if (tok3->str() == "&&") { - tokens.push(tok3->astOperand1()); - tokens.push(tok3->astOperand2()); - continue; - } - if (tok3->str() == "(" && - tok3->astOperand2() && - tok3->astOperand2()->isConstOp()) { - tokens.push(tok3->astOperand2()); - continue; - } - - const Token *vartok = nullptr; - if (isVariableComparison(tok3, "!=", "0", &vartok)) { - varInfo2.erase(vartok->varId()); - if (notzero.find(vartok->varId()) != notzero.end()) - varInfo2.clear(); - } else if (isVariableComparison(tok3, "==", "0", &vartok)) { - varInfo1.erase(vartok->varId()); - } else if (Token::Match(tok->next(), "( %name% ( ! %var% ) )|&&")) { - varInfo1.erase(tok->tokAt(5)->varId()); - } else if (isVariableComparison(tok3, "<", "0", &vartok)) { - varInfo1.erase(vartok->varId()); - } else if (isVariableComparison(tok3, ">", "0", &vartok)) { - varInfo2.erase(vartok->varId()); - } else if (isVariableComparison(tok3, "==", "-1", &vartok)) { - varInfo1.erase(vartok->varId()); - } + const Token *vartok = nullptr; + if (Token::findVariableComparison(tok->next()->astOperand2(), "!=", "0", &vartok)) { + varInfo2.erase(vartok->varId()); + if (notzero.find(vartok->varId()) != notzero.end()) + varInfo2.clear(); + } else if (Token::findVariableComparison(tok->next()->astOperand2(), "==", "0", &vartok)) { + varInfo1.erase(vartok->varId()); + } else if (Token::findVariableComparison(tok->next()->astOperand2(), "<", "0", &vartok)) { + varInfo1.erase(vartok->varId()); + } else if (Token::findVariableComparison(tok->next()->astOperand2(), ">", "0", &vartok)) { + varInfo2.erase(vartok->varId()); + } else if (Token::findVariableComparison(tok->next()->astOperand2(), "==", "-1", &vartok)) { + varInfo1.erase(vartok->varId()); } checkScope(tok2->next(), &varInfo1, notzero); diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index f46fd78d8..7924cda80 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -519,28 +519,12 @@ const char *CheckMemoryLeak::functionArgAlloc(const Function *func, unsigned int static bool notvar(const Token *tok, unsigned int varid) { - if (!tok) - return false; if (Token::Match(tok, "&&|;")) return notvar(tok->astOperand1(),varid) || notvar(tok->astOperand2(),varid); - if (tok->str() == "!") - tok = tok->astOperand1(); - else if (tok->str() == "==") { - if (Token::simpleMatch(tok->astOperand1(), "0")) - tok = tok->astOperand2(); - else if (Token::simpleMatch(tok->astOperand2(), "0")) - tok = tok->astOperand1(); - else - return false; - } else { - return false; - } + const Token *vartok = Token::findVariableComparison(tok, "==", "0"); - while (tok && tok->str() == ".") - tok = tok->astOperand2(); - - return tok && tok->varId() == varid; + return vartok && (vartok->varId() == varid); } @@ -2176,10 +2160,10 @@ void CheckMemoryLeakInFunction::checkReallocUsage() const Token* tokEndRealloc = tok->linkAt(3); // Check that the allocation isn't followed immediately by an 'if (!var) { error(); }' that might handle failure - if (Token::Match(tokEndRealloc->next(), "; if ( ! %varid% ) {", tok->varId())) { - const Token* tokEndBrace = tokEndRealloc->linkAt(7); - if (tokEndBrace && Token::simpleMatch(tokEndBrace->tokAt(-2), ") ;") && - Token::Match(tokEndBrace->linkAt(-2)->tokAt(-2), "{|}|; %name% (")) + if (Token::simpleMatch(tokEndRealloc->next(), "; if (") && + notvar(tokEndRealloc->tokAt(3)->astOperand2(), tok->varId())) { + const Token* tokEndBrace = tokEndRealloc->linkAt(3)->linkAt(1); + if (tokEndBrace && _tokenizer->IsScopeNoReturn(tokEndBrace)) continue; } diff --git a/lib/token.cpp b/lib/token.cpp index 11dcdc0be..4411cadc1 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -1459,6 +1459,52 @@ const Token *Token::getValueTokenDeadPointer() const return nullptr; } + +const Token * Token::findVariableComparison(const Token *tok, const std::string &comp, const std::string &rhs, const Token **vartok) +{ + if (!tok) + return nullptr; + + if (tok->str() == "&&") { + const Token *ret = findVariableComparison(tok->astOperand1(), comp, rhs, vartok); + if (!ret) + ret = findVariableComparison(tok->astOperand2(), comp, rhs, vartok); + return ret; + } + + if (tok->str() == "(" && tok->astOperand2() && Token::Match(tok->astOperand1(), "UNLIKELY|LIKELY")) + return findVariableComparison(tok->astOperand2(), comp, rhs, vartok); + + const Token *ret = nullptr; + if (tok->isComparisonOp()) { + if (tok->astOperand1() && tok->astOperand1()->str() == rhs) { + // Invert comparator + std::string s = tok->str(); + if (s[0] == '>') + s[0] = '<'; + else if (s[0] == '<') + s[0] = '>'; + if (s == comp) { + ret = tok->astOperand2(); + } + } else if (tok->str() == comp && tok->astOperand2() && tok->astOperand2()->str() == rhs) { + ret = tok->astOperand1(); + } + } else if (comp == "!=" && rhs == std::string("0")) { + ret = tok; + } else if (comp == "==" && rhs == std::string("0")) { + if (tok->str() == "!") + ret = tok->astOperand1(); + } + while (ret && ret->str() == ".") + ret = ret->astOperand2(); + if (ret && ret->varId() == 0U) + ret = nullptr; + if (vartok) + *vartok = ret; + return ret; +} + void Token::assignProgressValues(Token *tok) { unsigned int total_count = 0; diff --git a/lib/token.h b/lib/token.h index b0321a420..e15ac9c79 100644 --- a/lib/token.h +++ b/lib/token.h @@ -711,6 +711,9 @@ public: const Token *getValueTokenDeadPointer() const; + /** Recursively search for variable comparison against value */ + static const Token * findVariableComparison(const Token *tok, const std::string &comp, const std::string &rhs, const Token **vartok=nullptr); + private: void next(Token *nextToken) { diff --git a/tools/run_more_tests.sh b/tools/run_more_tests.sh index 46baac8eb..6cf3ad813 100755 --- a/tools/run_more_tests.sh +++ b/tools/run_more_tests.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -e + ~/cppcheck/cppcheck -q . 2> 1.txt