Refactorizations:

- Rely on SymbolDatabase to detect string types
- Loop over variable list instead of token list
- Fixed two comments claiming that the AST is experimental
This commit is contained in:
PKEuS 2015-11-20 11:20:23 +01:00
parent 52b5446d86
commit 00bdc89f98
3 changed files with 12 additions and 18 deletions

View File

@ -275,7 +275,6 @@ void CheckCondition::comparison()
if (!_settings->isEnabled("style")) if (!_settings->isEnabled("style"))
return; return;
// Experimental code based on AST
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
if (Token::Match(tok, "==|!=")) { if (Token::Match(tok, "==|!=")) {
const Token *expr1 = tok->astOperand1(); const Token *expr1 = tok->astOperand1();

View File

@ -930,8 +930,6 @@ static bool isLocal(const Token *tok)
} }
namespace { namespace {
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> >() << static const std::set<std::string> stl_string_stream = make_container< std::set<std::string> >() <<
"istringstream" << "ostringstream" << "stringstream" << "wstringstream" ; "istringstream" << "ostringstream" << "stringstream" << "wstringstream" ;
} }
@ -955,9 +953,9 @@ void CheckStl::string_c_str()
unsigned int numpar = 0; unsigned int numpar = 0;
c_strFuncParam.insert(std::make_pair(func->tokenDef->str(), numpar)); // Insert function as dummy, to indicate that there is at least one function with that name c_strFuncParam.insert(std::make_pair(func->tokenDef->str(), numpar)); // Insert function as dummy, to indicate that there is at least one function with that name
for (const Token* tok = func->argDef->next(); tok != 0; tok = tok->nextArgument()) { for (std::list<Variable>::const_iterator var = func->argumentList.cbegin(); var != func->argumentList.cend(); ++var) {
numpar++; numpar++;
if (Token::Match(tok, "std :: string|wstring !!&") || Token::Match(tok, "const std :: string|wstring")) if (var->isStlStringType() && (!var->isReference() || var->isConst()))
c_strFuncParam.insert(std::make_pair(func->tokenDef->str(), numpar)); c_strFuncParam.insert(std::make_pair(func->tokenDef->str(), numpar));
} }
} }
@ -980,7 +978,7 @@ void CheckStl::string_c_str()
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) { for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
// Invalid usage.. // Invalid usage..
if (Token::Match(tok, "throw %var% . c_str|data ( ) ;") && isLocal(tok->next()) && if (Token::Match(tok, "throw %var% . c_str|data ( ) ;") && isLocal(tok->next()) &&
tok->next()->variable() && tok->next()->variable()->isStlType(stl_string)) { tok->next()->variable() && tok->next()->variable()->isStlStringType()) {
string_c_strThrowError(tok); string_c_strThrowError(tok);
} else if (Token::Match(tok, "[;{}] %name% = %var% . str ( ) . c_str|data ( ) ;")) { } else if (Token::Match(tok, "[;{}] %name% = %var% . str ( ) . c_str|data ( ) ;")) {
const Variable* var = tok->next()->variable(); const Variable* var = tok->next()->variable();
@ -1014,7 +1012,7 @@ void CheckStl::string_c_str()
tok2 = tok2->previous(); tok2 = tok2->previous();
if (tok2 && Token::Match(tok2->tokAt(-4), ". c_str|data ( )")) { if (tok2 && Token::Match(tok2->tokAt(-4), ". c_str|data ( )")) {
const Variable* var = tok2->tokAt(-5)->variable(); const Variable* var = tok2->tokAt(-5)->variable();
if (var && var->isStlType(stl_string)) { if (var && var->isStlStringType()) {
string_c_strParam(tok, i->second); string_c_strParam(tok, i->second);
} else if (Token::Match(tok2->tokAt(-9), "%name% . str ( )")) { // Check ss.str().c_str() as parameter } else if (Token::Match(tok2->tokAt(-9), "%name% . str ( )")) { // Check ss.str().c_str() as parameter
const Variable* ssVar = tok2->tokAt(-9)->variable(); const Variable* ssVar = tok2->tokAt(-9)->variable();
@ -1029,7 +1027,7 @@ void CheckStl::string_c_str()
// Using c_str() to get the return value is only dangerous if the function returns a char* // Using c_str() to get the return value is only dangerous if the function returns a char*
if (returnType == charPtr) { if (returnType == charPtr) {
if (Token::Match(tok, "return %var% . c_str|data ( ) ;") && isLocal(tok->next()) && if (Token::Match(tok, "return %var% . c_str|data ( ) ;") && isLocal(tok->next()) &&
tok->next()->variable() && tok->next()->variable()->isStlType(stl_string)) { tok->next()->variable() && tok->next()->variable()->isStlStringType()) {
string_c_strError(tok); string_c_strError(tok);
} else if (Token::Match(tok, "return %var% . str ( ) . c_str|data ( ) ;") && isLocal(tok->next()) && } else if (Token::Match(tok, "return %var% . str ( ) . c_str|data ( ) ;") && isLocal(tok->next()) &&
tok->next()->variable() && tok->next()->variable()->isStlType(stl_string_stream)) { tok->next()->variable() && tok->next()->variable()->isStlType(stl_string_stream)) {
@ -1048,7 +1046,7 @@ void CheckStl::string_c_str()
const Token *search_end = tok->next()->link(); const Token *search_end = tok->next()->link();
for (const Token *search_tok = tok->tokAt(2); search_tok != search_end; search_tok = search_tok->next()) { for (const Token *search_tok = tok->tokAt(2); search_tok != search_end; search_tok = search_tok->next()) {
if (Token::Match(search_tok, "+ %var%") && isLocal(search_tok->next()) && if (Token::Match(search_tok, "+ %var%") && isLocal(search_tok->next()) &&
search_tok->next()->variable() && search_tok->next()->variable()->isStlType(stl_string)) { search_tok->next()->variable() && search_tok->next()->variable()->isStlStringType()) {
is_implicit_std_string = true; is_implicit_std_string = true;
break; break;
} else if (Token::Match(search_tok, "+ std :: string|wstring (")) { } else if (Token::Match(search_tok, "+ std :: string|wstring (")) {
@ -1067,7 +1065,7 @@ void CheckStl::string_c_str()
const Token* tok2 = Token::findsimplematch(tok->next(), ";"); const Token* tok2 = Token::findsimplematch(tok->next(), ";");
if (Token::Match(tok2->tokAt(-4), ". c_str|data ( )")) { if (Token::Match(tok2->tokAt(-4), ". c_str|data ( )")) {
tok2 = tok2->tokAt(-5); tok2 = tok2->tokAt(-5);
if (tok2->variable() && tok2->variable()->isStlType(stl_string)) { // return var.c_str(); if (tok2->variable() && tok2->variable()->isStlStringType()) { // return var.c_str();
string_c_strReturn(tok); string_c_strReturn(tok);
} }
} }
@ -1265,7 +1263,7 @@ void CheckStl::uselessCalls()
tok->varId() == tok->tokAt(4)->varId()) { tok->varId() == tok->tokAt(4)->varId()) {
uselessCallsSwapError(tok, tok->str()); uselessCallsSwapError(tok, tok->str());
} else if (printPerformance && Token::Match(tok, "%var% . substr (") && } else if (printPerformance && Token::Match(tok, "%var% . substr (") &&
tok->variable() && tok->variable()->isStlType(stl_string)) { tok->variable() && tok->variable()->isStlStringType()) {
if (Token::Match(tok->tokAt(4), "0| )")) if (Token::Match(tok->tokAt(4), "0| )"))
uselessCallsSubstrError(tok, false); uselessCallsSubstrError(tok, false);
else if (tok->strAt(4) == "0" && tok->linkAt(3)->strAt(-1) == "npos") { else if (tok->strAt(4) == "0" && tok->linkAt(3)->strAt(-1) == "npos") {

View File

@ -3714,7 +3714,7 @@ bool Tokenizer::simplifyTokenList2()
// clear the _functionList so it can't contain dead pointers // clear the _functionList so it can't contain dead pointers
deleteSymbolDatabase(); deleteSymbolDatabase();
// Experimental AST handling. // Clear AST. It will be created again at the end of this function.
for (Token *tok = list.front(); tok; tok = tok->next()) for (Token *tok = list.front(); tok; tok = tok->next())
tok->clearAst(); tok->clearAst();
@ -3886,11 +3886,8 @@ void Tokenizer::printDebugOutput(unsigned int simplification) const
printUnknownTypes(); printUnknownTypes();
// #5054 - the typeStartToken() should come before typeEndToken() // #5054 - the typeStartToken() should come before typeEndToken()
for (const Token *tok = tokens(); tok; tok = tok->next()) { for (unsigned int varid = 1; varid < _symbolDatabase->getVariableListSize(); varid++) {
if (tok->varId() == 0U) const Variable *var = _symbolDatabase->getVariableFromVarId(varid);
continue;
const Variable *var = tok->variable();
if (!var) if (!var)
continue; continue;
@ -3899,7 +3896,7 @@ void Tokenizer::printDebugOutput(unsigned int simplification) const
typetok = typetok->next(); typetok = typetok->next();
if (typetok != var->typeEndToken()) { if (typetok != var->typeEndToken()) {
reportError(tok, reportError(var->typeStartToken(),
Severity::debug, Severity::debug,
"debug", "debug",
"Variable::typeStartToken() of variable '" + var->name() + "' is not located before Variable::typeEndToken(). The location of the typeStartToken() is '" + var->typeStartToken()->str() + "' at line " + MathLib::toString(var->typeStartToken()->linenr())); "Variable::typeStartToken() of variable '" + var->name() + "' is not located before Variable::typeEndToken(). The location of the typeStartToken() is '" + var->typeStartToken()->str() + "' at line " + MathLib::toString(var->typeStartToken()->linenr()));