diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 11e199fd8..3da00b0d8 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1249,13 +1249,6 @@ void CheckOther::selfAssignmentError(const Token *tok, const std::string &varnam // Inform that second comparison is always true when first comparison is true. //--------------------------------------------------------------------------- -enum Position { First, Second, NA }; -enum Relation { Equal, NotEqual, Less, LessEqual, More, MoreEqual }; -struct Condition { - Position position; - const char *opTokStr; -}; - static std::string invertOperatorForOperandSwap(std::string s) { for (std::string::size_type i = 0; i < s.length(); i++) { @@ -2863,111 +2856,6 @@ void CheckOther::doubleCloseDirError(const Token *tok, const std::string &varnam } namespace { - struct ExpressionTokens { - const Token *start; - const Token *end; - int count; - bool inconclusiveFunction; - ExpressionTokens(const Token *s, const Token *e): start(s), end(e), count(1), inconclusiveFunction(false) {} - }; - - struct FuncFilter { - FuncFilter(const Scope *scope, const Token *tok): _scope(scope), _tok(tok) {} - - bool operator()(const Function* func) const { - bool matchingFunc = func->type == Function::eFunction && - _tok->str() == func->token->str(); - // either a class function, or a global function with the same name - return (_scope && _scope == func->nestedIn && matchingFunc) || - (!_scope && matchingFunc); - } - const Scope *_scope; - const Token *_tok; - }; - - bool inconclusiveFunctionCall(const std::list &constFunctions, - const ExpressionTokens &tokens) - { - const Token *start = tokens.start; - const Token *end = tokens.end; - // look for function calls between start and end... - for (const Token *tok = start; tok && tok != end; tok = tok->next()) { - if (tok != start && tok->str() == "(") { - // go back to find the function call. - const Token *prev = tok->previous(); - if (!prev) - continue; - if (prev->str() == ">") { - // ignore template functions like boo() - return true; - } - if (prev->isName()) { - const Variable *v = 0; - if (Token::Match(prev->tokAt(-2), "%var% .")) { - const Token *scope = prev->tokAt(-2); - v = scope->variable(); - } - // hard coded list of safe, no-side-effect functions - if (v == 0 && Token::Match(prev, "strcmp|strncmp|strlen|wcscmp|wcsncmp|wcslen|memcmp|strcasecmp|strncasecmp")) - return false; - std::list::const_iterator it = std::find_if(constFunctions.begin(), - constFunctions.end(), - FuncFilter(v ? v->typeScope(): 0, prev)); - if (it == constFunctions.end()) - return true; - } - } - } - return false; - } - - class Expressions { - public: - Expressions(const std::list &constFunctions) - : _start(0), - _lastTokens(0), - _constFunctions(constFunctions) { } - - void endExpr(const Token *end) { - const std::string &e = _expression.str(); - if (!e.empty()) { - std::map::iterator it = _expressions.find(e); - bool lastInconclusive = _lastTokens && _lastTokens->inconclusiveFunction; - if (it == _expressions.end()) { - ExpressionTokens exprTokens(_start, end); - exprTokens.inconclusiveFunction = lastInconclusive || inconclusiveFunctionCall( - _constFunctions, exprTokens); - _expressions.insert(std::make_pair(e, exprTokens)); - _lastTokens = &_expressions.find(e)->second; - } else { - ExpressionTokens &expr = it->second; - expr.count += 1; - expr.inconclusiveFunction = expr.inconclusiveFunction || lastInconclusive; - _lastTokens = &expr; - } - } - _expression.str(""); - _start = 0; - } - - void append(const Token *tok) { - if (!_start) - _start = tok; - _expression << tok->str(); - } - - std::map &getMap() { - return _expressions; - } - - private: - std::map _expressions; - std::ostringstream _expression; - const Token *_start; - ExpressionTokens *_lastTokens; - const std::list &_constFunctions; - }; - bool notconst(const Function* func) { return !func->isConst; @@ -2995,132 +2883,6 @@ namespace { } } } - -} - -void CheckOther::checkExpressionRange(const std::list &constFunctions, - const Token *start, - const Token *end, - const std::string &toCheck) -{ - if (!start || !end) - return; - Expressions expressions(constFunctions); - std::string opName; - int level = 0; - for (const Token *tok = start->next(); tok && tok != end; tok = tok->next()) { - if (tok->str() == ")") - level--; - else if (tok->str() == "(") - level++; - - if (level == 0 && Token::Match(tok, toCheck.c_str())) { - opName = tok->str(); - expressions.endExpr(tok); - } else { - expressions.append(tok); - } - } - expressions.endExpr(end); - std::map::const_iterator it = expressions.getMap().begin(); - for (; it != expressions.getMap().end(); ++it) { - // check expression.. - bool valid = true; - unsigned int parentheses = 0; // () - unsigned int brackets = 0; // [] - - // taking address? - if (Token::Match(it->second.end->previous(), "%op% &")) { - continue; - } - - for (const Token *tok = it->second.start; tok && tok != it->second.end; tok = tok->next()) { - if (tok->str() == "(") { - ++parentheses; - } else if (tok->str() == ")") { - if (parentheses == 0) { - valid = false; - break; - } - --parentheses; - } else if (tok->str() == "[") { - ++brackets; - } else if (tok->str() == "]") { - if (brackets == 0) { - valid = false; - break; - } - --brackets; - } else if (tok->type() == Token::eIncDecOp) { - valid = false; - break; - } - } - - if (!valid || parentheses!=0 || brackets!=0) - continue; - - const ExpressionTokens &expr = it->second; - if (expr.count > 1 && !expr.inconclusiveFunction) { - duplicateExpressionError(expr.start, expr.start, opName); - } - } -} - -void CheckOther::complexDuplicateExpressionCheck(const std::list &constFunctions, - const Token *classStart, - const std::string &toCheck, - const std::string &alt) -{ - std::string statementStart(",|=|?|:|return"); - if (!alt.empty()) - statementStart += "|" + alt; - std::string statementEnd(";|,|?|:"); - if (!alt.empty()) - statementEnd += "|" + alt; - - for (const Token *tok = classStart; tok && tok != classStart->link(); tok = tok->next()) { - if (!Token::Match(tok, toCheck.c_str())) - continue; - - // look backward for the start of the statement - const Token *start = 0; - int level = 0; - for (const Token *tok1 = tok->previous(); tok1 && tok1 != classStart; tok1 = tok1->previous()) { - if (tok1->str() == ")") - level++; - else if (tok1->str() == "(") - level--; - - if (level < 0 || (level == 0 && Token::Match(tok1, statementStart.c_str()))) { - start = tok1; - break; - } - - if (tok1->isExpandedMacro()) - break; - } - const Token *end = 0; - level = 0; - // look for the end of the statement - for (const Token *tok1 = tok->next(); tok1 && tok1 != classStart->link(); tok1 = tok1->next()) { - if (tok1->str() == ")") - level--; - else if (tok1->str() == "(") - level++; - - if (level < 0 || (level == 0 && Token::Match(tok1, statementEnd.c_str()))) { - end = tok1; - break; - } - - if (tok1->isExpandedMacro()) - break; - } - - if (start && end) - checkExpressionRange(constFunctions, start, end, toCheck); - } } static bool astIsFloat(const Token *tok) diff --git a/lib/checkother.h b/lib/checkother.h index dcf4f3f9b..c4cab33c2 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -470,16 +470,6 @@ private: "* NaN (not a number) value used in arithmetic expression.\n" "* comma in return statement (the comma can easily be misread as a semicolon).\n"; } - - void checkExpressionRange(const std::list &constFunctions, - const Token *start, - const Token *end, - const std::string &toCheck); - - void complexDuplicateExpressionCheck(const std::list &constFunctions, - const Token *classStart, - const std::string &toCheck, - const std::string &alt); }; /// @} //---------------------------------------------------------------------------