diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 6116d41b6..968800b1c 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -894,8 +894,10 @@ void CheckStl::if_findError(const Token *tok, bool str) } - -bool CheckStl::isStlContainer(const Token *tok) const +/** + * Is container.size() slow? + */ +static bool isContainerSizeSlow(const Token *tok) { // find where this token is defined const Variable *var = tok->variable(); @@ -910,11 +912,8 @@ bool CheckStl::isStlContainer(const Token *tok) const if (Token::simpleMatch(type, "std ::")) type = type->tokAt(2); - // all possible stl containers as a token - static const char STL_CONTAINER_LIST[] = "array|bitset|deque|list|forward_list|map|multimap|multiset|priority_queue|queue|set|stack|vector|hash_map|hash_multimap|hash_set|unordered_map|unordered_multimap|unordered_set|unordered_multiset|basic_string"; - // check if it's an stl template - if (Token::Match(type, STL_CONTAINER_LIST)) + if (Token::Match(type, "array|bitset|list|forward_list|map|multimap|multiset|priority_queue|queue|set|stack|hash_map|hash_multimap|hash_set|unordered_map|unordered_multimap|unordered_set|unordered_multiset|basic_string")) return true; return false; @@ -944,21 +943,21 @@ void CheckStl::size() // check for comparison to zero if ((tok->previous() && !tok->previous()->isArithmeticalOp() && Token::Match(end, "==|<=|!=|> 0")) || (end->next() && !end->next()->isArithmeticalOp() && Token::Match(tok->tokAt(-2), "0 ==|>=|!=|<"))) { - if (isStlContainer(tok1)) + if (isContainerSizeSlow(tok1)) sizeError(tok1); } // check for comparison to one if ((tok->previous() && !tok->previous()->isArithmeticalOp() && Token::Match(end, ">=|< 1")) || (end->next() && !end->next()->isArithmeticalOp() && Token::Match(tok->tokAt(-2), "1 <=|>"))) { - if (isStlContainer(tok1)) + if (isContainerSizeSlow(tok1)) sizeError(tok1); } // check for using as boolean expression else if ((Token::Match(tok->tokAt(-2), "if|while (") && end->str() == ")") || (tok->previous()->type() == Token::eLogicalOp && Token::Match(end, "&&|)|,|;|%oror%"))) { - if (isStlContainer(tok1)) + if (isContainerSizeSlow(tok1)) sizeError(tok1); } } diff --git a/lib/checkstl.h b/lib/checkstl.h index 124058d92..396832afc 100644 --- a/lib/checkstl.h +++ b/lib/checkstl.h @@ -225,8 +225,6 @@ private: "* using auto pointer (auto_ptr)\n" "* useless calls of string and STL functions\n"; } - - bool isStlContainer(const Token *tok) const; }; /// @} //--------------------------------------------------------------------------- diff --git a/test/teststl.cpp b/test/teststl.cpp index 0da7886c3..e496c463f 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -101,6 +101,7 @@ private: TEST_CASE(size1); TEST_CASE(size2); TEST_CASE(size3); + TEST_CASE(size4); // #2652 - don't warn about vector/deque // Redundant conditions.. // if (ints.find(123) != ints.end()) ints.remove(123); @@ -1620,6 +1621,18 @@ private: ASSERT_EQUALS("[test.cpp:10]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str()); } + void size4() { // #2652 - don't warn about vector/deque + check("void f(std::vector &v) {\n" + " if (v.size() > 0U) {}\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("void f(std::deque &v) {\n" + " if (v.size() > 0U) {}\n" + "}"); + ASSERT_EQUALS("", errout.str()); + } + void redundantCondition2() { check("void f(string haystack)\n" "{\n"