#6510 False positive performance warning for std::list::size(). Fix this and other similar false positives. Refactoring of Variable::isStlType(), use fail-safe std::set instead of plain array. Run astyle
This commit is contained in:
parent
20842fb1fc
commit
f0bc300198
|
@ -1868,10 +1868,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, bool&
|
|||
if (end->varId()) {
|
||||
const Variable *var = end->variable();
|
||||
// The container contains the STL types whose operator[] is not a const.
|
||||
// THIS ARRAY MUST BE ORDERED ALPHABETICALLY
|
||||
static const char* const stl_containers [] = {
|
||||
"map", "unordered_map"
|
||||
};
|
||||
static const std::set<std::string> stl_containers = make_container< std::set<std::string> >() << "map" << "unordered_map";
|
||||
if (var && var->isStlType(stl_containers))
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1522,16 +1522,12 @@ CheckIO::ArgumentInfo::~ArgumentInfo()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CheckIO::ArgumentInfo::isStdVectorOrString()
|
||||
{
|
||||
// THIS ARRAY MUST BE ORDERED ALPHABETICALLY
|
||||
static const char* const stl_vector[] = {
|
||||
"array", "vector"
|
||||
};
|
||||
// THIS ARRAY MUST BE ORDERED ALPHABETICALLY
|
||||
static const char* const stl_string[] = {
|
||||
"string", "u16string", "u32string", "wstring"
|
||||
};
|
||||
static const std::set<std::string> stl_vector = make_container< std::set<std::string> >() << "array" << "vector";
|
||||
static const std::set<std::string> stl_string = make_container< std::set<std::string> >() << "string" << "u16string" << "u32string" << "wstring";
|
||||
|
||||
if (variableInfo->isStlType(stl_vector)) {
|
||||
typeToken = variableInfo->typeStartToken()->tokAt(4);
|
||||
|
@ -1586,19 +1582,15 @@ bool CheckIO::ArgumentInfo::isStdVectorOrString()
|
|||
|
||||
bool CheckIO::ArgumentInfo::isStdContainer(const Token *tok)
|
||||
{
|
||||
// THIS ARRAY MUST BE ORDERED ALPHABETICALLY
|
||||
static const char* const stl_container[] = {
|
||||
"array", "bitset", "deque", "forward_list",
|
||||
"hash_map", "hash_multimap", "hash_set",
|
||||
"list", "map", "multimap", "multiset",
|
||||
"priority_queue", "queue", "set", "stack",
|
||||
"unordered_map", "unordered_multimap", "unordered_multiset", "unordered_set",
|
||||
"vector"
|
||||
};
|
||||
// THIS ARRAY MUST BE ORDERED ALPHABETICALLY
|
||||
static const char* const stl_string[]= {
|
||||
"string", "u16string", "u32string", "wstring"
|
||||
};
|
||||
static const std::set<std::string> stl_container = make_container< std::set<std::string> >() <<
|
||||
"array" << "bitset" << "deque" << "forward_list" <<
|
||||
"hash_map" << "hash_multimap" << "hash_set" <<
|
||||
"list" << "map" << "multimap" << "multiset" <<
|
||||
"priority_queue" << "queue" << "set" << "stack" <<
|
||||
"unordered_map" << "unordered_multimap" << "unordered_multiset" << "unordered_set" << "vector"
|
||||
;
|
||||
static const std::set<std::string> stl_string= make_container< std::set<std::string> >() <<
|
||||
"string" << "u16string" << "u32string" << "wstring";
|
||||
|
||||
if (tok && tok->variable()) {
|
||||
const Variable* variable = tok->variable();
|
||||
|
|
|
@ -148,12 +148,10 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
|
|||
*/
|
||||
bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown)
|
||||
{
|
||||
// THIS ARRAY MUST BE ORDERED ALPHABETICALLY
|
||||
static const char* const stl_stream [] = {
|
||||
"fstream", "ifstream", "iostream", "istream",
|
||||
"istringstream", "ofstream", "ostream", "ostringstream",
|
||||
"stringstream", "wistringstream", "wostringstream", "wstringstream"
|
||||
};
|
||||
static const std::set<std::string> stl_stream = make_container< std::set<std::string> >() <<
|
||||
"fstream" << "ifstream" << "iostream" << "istream" <<
|
||||
"istringstream" << "ofstream" << "ostream" << "ostringstream" <<
|
||||
"stringstream" << "wistringstream" << "wostringstream" << "wstringstream";
|
||||
|
||||
unknown = false;
|
||||
|
||||
|
@ -379,12 +377,9 @@ void CheckNullPointer::nullPointer()
|
|||
void CheckNullPointer::nullConstantDereference()
|
||||
{
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
|
||||
// THIS ARRAY MUST BE ORDERED ALPHABETICALLY
|
||||
static const char* const stl_stream[] = {
|
||||
"fstream", "ifstream", "iostream", "istream",
|
||||
"istringstream", "stringstream", "wistringstream", "wstringstream"
|
||||
};
|
||||
static const std::set<std::string> stl_stream = make_container< std::set<std::string> >() <<
|
||||
"fstream" << "ifstream" << "iostream" << "istream" <<
|
||||
"istringstream" << "stringstream" << "wistringstream" << "wstringstream";
|
||||
|
||||
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
|
|
|
@ -843,21 +843,12 @@ void CheckStl::if_findError(const Token *tok, bool str)
|
|||
/**
|
||||
* Is container.size() slow?
|
||||
*/
|
||||
static bool isContainerSizeSlow(const Token *tok)
|
||||
static bool isCpp03ContainerSizeSlow(const Token *tok)
|
||||
{
|
||||
// THIS ARRAY MUST BE ORDERED ALPHABETICALLY
|
||||
static const char* stl_size_slow[] = {
|
||||
"array", "bitset",
|
||||
"forward_list", "hash_map", "hash_multimap", "hash_set",
|
||||
"list", "map", "multimap", "multiset",
|
||||
"priority_queue", "queue", "set", "stack", "unordered_map",
|
||||
"unordered_multimap", "unordered_multiset", "unordered_set"
|
||||
};
|
||||
|
||||
if (!tok)
|
||||
return false;
|
||||
const Variable* var = tok->variable();
|
||||
return var && var->isStlType(stl_size_slow);
|
||||
return var && var->isStlType("list");
|
||||
}
|
||||
|
||||
void CheckStl::size()
|
||||
|
@ -865,6 +856,9 @@ void CheckStl::size()
|
|||
if (!_settings->isEnabled("performance"))
|
||||
return;
|
||||
|
||||
if (_settings->standards.cpp == Standards::CPP11)
|
||||
return;
|
||||
|
||||
const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
|
@ -883,21 +877,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 (isContainerSizeSlow(tok1))
|
||||
if (isCpp03ContainerSizeSlow(tok1))
|
||||
sizeError(tok1);
|
||||
}
|
||||
|
||||
// check for comparison to one
|
||||
if ((tok->previous() && !tok->previous()->isArithmeticalOp() && Token::Match(end, ">=|< 1") && !end->tokAt(2)->isArithmeticalOp()) ||
|
||||
(end->next() && !end->next()->isArithmeticalOp() && Token::Match(tok->tokAt(-2), "1 <=|>") && !tok->tokAt(-3)->isArithmeticalOp())) {
|
||||
if (isContainerSizeSlow(tok1))
|
||||
if (isCpp03ContainerSizeSlow(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 (isContainerSizeSlow(tok1))
|
||||
if (isCpp03ContainerSizeSlow(tok1))
|
||||
sizeError(tok1);
|
||||
}
|
||||
}
|
||||
|
@ -1046,14 +1040,10 @@ void CheckStl::string_c_str()
|
|||
{
|
||||
const bool printInconclusive = _settings->inconclusive;
|
||||
const bool printPerformance = _settings->isEnabled("performance");
|
||||
// THIS ARRAY MUST BE ORDERED ALPHABETICALLY
|
||||
static const char* const stl_string[] = {
|
||||
"string", "u16string", "u32string", "wstring"
|
||||
};
|
||||
// THIS ARRAY MUST BE ORDERED ALPHABETICALLY
|
||||
static const char* const stl_string_stream[] = {
|
||||
"istringstream", "ostringstream", "stringstream", "wstringstream"
|
||||
};
|
||||
static const std::set<std::string> stl_string = make_container< std::set<std::string> >() <<
|
||||
"string" << "u16string" << "u32string" << "wstring" ;
|
||||
static const std::set<std::string> stl_string_stream = make_container< std::set<std::string> >() <<
|
||||
"istringstream" << "ostringstream" << "stringstream" << "wstringstream" ;
|
||||
|
||||
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
|
||||
|
@ -1357,17 +1347,13 @@ void CheckStl::uselessCalls()
|
|||
if (!printPerformance && !printWarning)
|
||||
return;
|
||||
|
||||
// THIS ARRAY MUST BE ORDERED ALPHABETICALLY
|
||||
static const char* const stl_string[] = {
|
||||
"string", "u16string", "u32string", "wstring"
|
||||
};
|
||||
// THIS ARRAY MUST BE ORDERED ALPHABETICALLY
|
||||
static const char* const stl_containers_with_empty_and_clear[] = {
|
||||
"deque", "forward_list", "list",
|
||||
"map", "multimap", "multiset", "set", "string",
|
||||
"unordered_map", "unordered_multimap", "unordered_multiset",
|
||||
"unordered_set", "vector", "wstring"
|
||||
};
|
||||
static const std::set<std::string> stl_string = make_container< std::set<std::string> >() <<
|
||||
"string" << "u16string" << "u32string" << "wstring";
|
||||
static const std::set<std::string> stl_containers_with_empty_and_clear = make_container< std::set<std::string> >() <<
|
||||
"deque" << "forward_list" << "list" <<
|
||||
"map" << "multimap" << "multiset" << "set" << "string" <<
|
||||
"unordered_map" << "unordered_multimap" << "unordered_multiset" <<
|
||||
"unordered_set" << "vector" << "wstring";
|
||||
|
||||
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
|
@ -1556,8 +1542,10 @@ void CheckStl::readingEmptyStlContainer()
|
|||
std::set<unsigned int> empty_map; // empty std::map-like instances of STL containers
|
||||
std::set<unsigned int> empty_nonmap; // empty non-std::map-like instances of STL containers
|
||||
|
||||
static const char *MAP_STL_CONTAINERS[] = { "map", "multimap", "unordered_map", "unordered_multimap" };
|
||||
static const char *NONMAP_STL_CONTAINERS[] = { "deque", "forward_list", "list", "multiset", "queue", "set", "stack", "string", "unordered_multiset", "unordered_set", "vector" };
|
||||
static const std::set<std::string> MAP_STL_CONTAINERS = make_container< std::set<std::string> >() <<
|
||||
"map" << "multimap" << "unordered_map" << "unordered_multimap" ;
|
||||
static const std::set<std::string> NONMAP_STL_CONTAINERS = make_container< std::set<std::string> >() <<
|
||||
"deque" << "forward_list" << "list" << "multiset" << "queue" << "set" << "stack" << "string" << "unordered_multiset" << "unordered_set" << "vector";
|
||||
|
||||
const std::list<Scope>& scopeList = _tokenizer->getSymbolDatabase()->scopeList;
|
||||
|
||||
|
|
|
@ -488,12 +488,25 @@ public:
|
|||
* ...
|
||||
* const char *str[] = {"string", "wstring"};
|
||||
* sVar->isStlType(str) == true
|
||||
* @param stlTypes array of stl types in alphabetical order
|
||||
* @param stlTypes set of stl types
|
||||
* @return true if it is an stl type and its type matches any of the types in 'stlTypes'
|
||||
*/
|
||||
template <std::size_t array_length>
|
||||
bool isStlType(const char* const(&stlTypes)[array_length]) const {
|
||||
return isStlType() && std::binary_search(stlTypes, stlTypes + array_length, _start->strAt(2));
|
||||
bool isStlType(const std::string& stlType) const {
|
||||
return isStlType() && stlType==_start->strAt(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the variable is of any of the STL types passed as arguments ('std::')
|
||||
* E.g.:
|
||||
* std::string s;
|
||||
* ...
|
||||
* const std::set<std::string> str = make_container< std::set<std::string> >() << "string" << "wstring";
|
||||
* sVar->isStlType(str) == true
|
||||
* @param stlTypes set of stl types
|
||||
* @return true if it is an stl type and its type matches any of the types in 'stlTypes'
|
||||
*/
|
||||
bool isStlType(const std::set<std::string>& stlTypes) const {
|
||||
return isStlType() && stlTypes.find(_start->strAt(2))!=stlTypes.end();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1003,5 +1016,23 @@ private:
|
|||
/** list for missing types */
|
||||
std::list<Type> _blankTypes;
|
||||
};
|
||||
|
||||
template < typename Cont >
|
||||
class make_container {
|
||||
public:
|
||||
typedef make_container< Cont > my_type;
|
||||
typedef typename Cont::value_type T;
|
||||
my_type& operator<< (const T& val) {
|
||||
data_.insert(data_.end(), val);
|
||||
return *this;
|
||||
}
|
||||
operator Cont() const {
|
||||
return data_;
|
||||
}
|
||||
private:
|
||||
Cont data_;
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif // symboldatabaseH
|
||||
|
|
|
@ -9318,23 +9318,23 @@ void Tokenizer::simplifyKeyword()
|
|||
// 1) struct name final { }; <- struct is final
|
||||
if (Token::Match(tok, "%type% final [:{]")) {
|
||||
tok->deleteNext();
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// final:
|
||||
// 2) void f() final; <- function is final
|
||||
// override:
|
||||
// void f() override;
|
||||
//if (Token::Match(tok, ") override [{;]"))
|
||||
if (Token::Match(tok, ") const|override|final")) {
|
||||
Token* specifier = tok->tokAt(2);
|
||||
while(specifier && Token::Match(specifier, "const|override|final"))
|
||||
specifier=specifier->next();
|
||||
if (Token::Match(tok, ") const|override|final")) {
|
||||
Token* specifier = tok->tokAt(2);
|
||||
while (specifier && Token::Match(specifier, "const|override|final"))
|
||||
specifier=specifier->next();
|
||||
if (specifier && Token::Match(specifier, "[{;]")) {
|
||||
specifier=tok->next();
|
||||
while (specifier->str()=="override" || specifier->str()=="final")
|
||||
specifier->deleteThis();
|
||||
}
|
||||
}
|
||||
specifier=tok->next();
|
||||
while (specifier->str()=="override" || specifier->str()=="final")
|
||||
specifier->deleteThis();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
289
test/teststl.cpp
289
test/teststl.cpp
|
@ -130,7 +130,7 @@ private:
|
|||
TEST_CASE(readingEmptyStlContainer);
|
||||
}
|
||||
|
||||
void check(const char code[], const bool inconclusive=false) {
|
||||
void check(const char code[], const bool inconclusive=false, const Standards::cppstd_t cppstandard=Standards::CPP11) {
|
||||
// Clear the error buffer..
|
||||
errout.str("");
|
||||
|
||||
|
@ -138,6 +138,7 @@ private:
|
|||
settings.addEnabled("style");
|
||||
settings.addEnabled("performance");
|
||||
settings.inconclusive = inconclusive;
|
||||
settings.standards.cpp = cppstandard;
|
||||
|
||||
// Tokenize..
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
|
@ -1651,106 +1652,148 @@ private:
|
|||
|
||||
|
||||
void size1() {
|
||||
check("struct Fred {\n"
|
||||
" void foo();\n"
|
||||
" std::list<int> x;\n"
|
||||
"};\n"
|
||||
"void Fred::foo()\n"
|
||||
"{\n"
|
||||
" if (x.size() == 0) {}\n"
|
||||
"}");
|
||||
const char* code = "struct Fred {\n"
|
||||
" void foo();\n"
|
||||
" std::list<int> x;\n"
|
||||
"};\n"
|
||||
"void Fred::foo()\n"
|
||||
"{\n"
|
||||
" if (x.size() == 0) {}\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:7]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("std::list<int> x;\n"
|
||||
"void f()\n"
|
||||
"{\n"
|
||||
" if (x.size() == 0) {}\n"
|
||||
"}");
|
||||
code = "std::list<int> x;\n"
|
||||
"void f()\n"
|
||||
"{\n"
|
||||
" if (x.size() == 0) {}\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (x.size() == 0) {}\n"
|
||||
"}");
|
||||
code = "void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (x.size() == 0) {}\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (0 == x.size()) {}\n"
|
||||
"}");
|
||||
code = "void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (0 == x.size()) {}\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (x.size() != 0) {}\n"
|
||||
"}");
|
||||
code = "void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (x.size() != 0) {}\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (0 != x.size()) {}\n"
|
||||
"}");
|
||||
code = "void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (0 != x.size()) {}\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (x.size() > 0) {}\n"
|
||||
"}");
|
||||
code = "void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (x.size() > 0) {}\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (0 < x.size()) {}\n"
|
||||
"}");
|
||||
code = "void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (0 < x.size()) {}\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (x.size() >= 1) {}\n"
|
||||
"}");
|
||||
code = "void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (x.size() >= 1) {}\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (x.size() < 1) {}\n"
|
||||
"}");
|
||||
code = "void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (x.size() < 1) {}\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (1 <= x.size()) {}\n"
|
||||
"}");
|
||||
code = "void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (1 <= x.size()) {}\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (1 > x.size()) {}\n"
|
||||
"}");
|
||||
code = "void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (1 > x.size()) {}\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (x.size()) {}\n"
|
||||
"}");
|
||||
code = "void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (x.size()) {}\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (!x.size()) {}\n"
|
||||
"}");
|
||||
code = "void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" if (!x.size()) {}\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
|
@ -1759,19 +1802,25 @@ private:
|
|||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
code ="void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" fun(!x.size());\n"
|
||||
"}");
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" fun(a && x.size());\n"
|
||||
"}");
|
||||
code = "void f()\n"
|
||||
"{\n"
|
||||
" std::list<int> x;\n"
|
||||
" fun(a && x.size());\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f() {\n" // #4039
|
||||
" std::list<int> x;\n"
|
||||
|
@ -1793,46 +1842,53 @@ private:
|
|||
}
|
||||
|
||||
void size2() {
|
||||
check("struct Fred {\n"
|
||||
" std::list<int> x;\n"
|
||||
"};\n"
|
||||
"struct Wilma {\n"
|
||||
" Fred f;\n"
|
||||
" void foo();\n"
|
||||
"};\n"
|
||||
"void Wilma::foo()\n"
|
||||
"{\n"
|
||||
" if (f.x.size() == 0) {}\n"
|
||||
"}");
|
||||
const char* code = "struct Fred {\n"
|
||||
" std::list<int> x;\n"
|
||||
"};\n"
|
||||
"struct Wilma {\n"
|
||||
" Fred f;\n"
|
||||
" void foo();\n"
|
||||
"};\n"
|
||||
"void Wilma::foo()\n"
|
||||
"{\n"
|
||||
" if (f.x.size() == 0) {}\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:10]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void size3() {
|
||||
check("namespace N {\n"
|
||||
" class Zzz {\n"
|
||||
" public:\n"
|
||||
" std::list<int> x;\n"
|
||||
" };\n"
|
||||
"}\n"
|
||||
"using namespace N;\n"
|
||||
"Zzz * zzz;\n"
|
||||
"int main() {\n"
|
||||
" if (zzz->x.size() > 0) { }\n"
|
||||
"}");
|
||||
const char* code = "namespace N {\n"
|
||||
" class Zzz {\n"
|
||||
" public:\n"
|
||||
" std::list<int> x;\n"
|
||||
" };\n"
|
||||
"}\n"
|
||||
"using namespace N;\n"
|
||||
"Zzz * zzz;\n"
|
||||
"int main() {\n"
|
||||
" if (zzz->x.size() > 0) { }\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:10]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
|
||||
check("namespace N {\n"
|
||||
" class Zzz {\n"
|
||||
" public:\n"
|
||||
" std::list<int> x;\n"
|
||||
" };\n"
|
||||
"}\n"
|
||||
"using namespace N;\n"
|
||||
"int main() {\n"
|
||||
" Zzz * zzz;\n"
|
||||
" if (zzz->x.size() > 0) { }\n"
|
||||
"}");
|
||||
code = "namespace N {\n"
|
||||
" class Zzz {\n"
|
||||
" public:\n"
|
||||
" std::list<int> x;\n"
|
||||
" };\n"
|
||||
"}\n"
|
||||
"using namespace N;\n"
|
||||
"int main() {\n"
|
||||
" Zzz * zzz;\n"
|
||||
" if (zzz->x.size() > 0) { }\n"
|
||||
"}";
|
||||
check(code, false, Standards::CPP03);
|
||||
ASSERT_EQUALS("[test.cpp:10]: (performance) Possible inefficient checking for 'x' emptiness.\n", errout.str());
|
||||
check(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void size4() { // #2652 - don't warn about vector/deque
|
||||
|
@ -1845,6 +1901,11 @@ private:
|
|||
" if (v.size() > 0U) {}\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f(std::array<int,3> &a) {\n"
|
||||
" if (a.size() > 0U) {}\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void redundantCondition1() {
|
||||
|
|
|
@ -659,8 +659,10 @@ private:
|
|||
bool result = si.isVariableDeclaration(list.front(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
Variable v(vartok, list.front(), list.back(), 0, Public, 0, 0, &settings.library);
|
||||
const char* types[] = { "string", "wstring" };
|
||||
const char* no_types[] = { "set" };
|
||||
static const std::set<std::string> types = make_container< std::set<std::string> >() <<
|
||||
"string" << "wstring" ;
|
||||
static const std::set<std::string> no_types = make_container< std::set<std::string> >() <<
|
||||
"set" ;
|
||||
ASSERT_EQUALS(true, v.isStlType());
|
||||
ASSERT_EQUALS(true, v.isStlType(types));
|
||||
ASSERT_EQUALS(false, v.isStlType(no_types));
|
||||
|
@ -675,8 +677,10 @@ private:
|
|||
bool result = si.isVariableDeclaration(list.front(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
Variable v(vartok, list.front(), list.back(), 0, Public, 0, 0, &settings.library);
|
||||
const char* types[] = { "bitset", "set", "vector", "wstring" };
|
||||
const char* no_types[] = { "bitset", "map", "set" };
|
||||
static const std::set<std::string> types = make_container< std::set<std::string> >() <<
|
||||
"bitset" << "set" << "vector" << "wstring" ;
|
||||
static const std::set<std::string> no_types = make_container< std::set<std::string> >() <<
|
||||
"bitset" << "map" << "set" ;
|
||||
ASSERT_EQUALS(true, v.isStlType());
|
||||
ASSERT_EQUALS(true, v.isStlType(types));
|
||||
ASSERT_EQUALS(false, v.isStlType(no_types));
|
||||
|
@ -690,7 +694,8 @@ private:
|
|||
bool result = si.isVariableDeclaration(list.front(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
Variable v(vartok, list.front(), list.back(), 0, Public, 0, 0, &settings.library);
|
||||
const char* types[] = { "bitset", "set", "vector" };
|
||||
static const std::set<std::string> types = make_container< std::set<std::string> >() <<
|
||||
"bitset" << "set" << "vector" ;
|
||||
ASSERT_EQUALS(false, v.isStlType());
|
||||
ASSERT_EQUALS(false, v.isStlType(types));
|
||||
ASSERT_EQUALS(false, v.isStlStringType());
|
||||
|
|
|
@ -4447,10 +4447,10 @@ private:
|
|||
}
|
||||
|
||||
void simplifyKeyword() {
|
||||
{
|
||||
const char code[] = "void f (int a [ static 5] );";
|
||||
ASSERT_EQUALS("void f ( int a [ 5 ] ) ;", tokenizeAndStringify(code));
|
||||
}
|
||||
{
|
||||
const char code[] = "void f (int a [ static 5] );";
|
||||
ASSERT_EQUALS("void f ( int a [ 5 ] ) ;", tokenizeAndStringify(code));
|
||||
}
|
||||
{
|
||||
const char in1[] = "class Base {\n"
|
||||
" virtual int test() = 0;\n"
|
||||
|
@ -4475,17 +4475,17 @@ private:
|
|||
const char out2[] = "class Derived {\n"
|
||||
"virtual int test ( ) ; } ;";
|
||||
ASSERT_EQUALS(out2, tokenizeAndStringify(in2));
|
||||
const char in3[] = "class Derived{\n"
|
||||
const char in3[] = "class Derived{\n"
|
||||
" virtual int test() final override const;"
|
||||
"};";
|
||||
const char out3[] = "class Derived {\n"
|
||||
"virtual int test ( ) const ; } ;";
|
||||
ASSERT_EQUALS(out3, tokenizeAndStringify(in3));
|
||||
|
||||
const char in4 [] = "struct B final : A { void foo(); };";
|
||||
const char out4 [] = "struct B : A { void foo ( ) ; } ;";
|
||||
ASSERT_EQUALS(out4, tokenizeAndStringify(in4));
|
||||
}
|
||||
const char in4 [] = "struct B final : A { void foo(); };";
|
||||
const char out4 [] = "struct B : A { void foo ( ) ; } ;";
|
||||
ASSERT_EQUALS(out4, tokenizeAndStringify(in4));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue