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