#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:
Alexander Mai 2015-05-17 20:02:41 +02:00
parent 20842fb1fc
commit f0bc300198
9 changed files with 284 additions and 215 deletions

View File

@ -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;
}

View File

@ -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();

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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();
}
}
}
}
}

View File

@ -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() {

View File

@ -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());

View File

@ -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));
}
}
/**