From 00bdc89f98fd11ce0d0fca12d3e42436caac4370 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Fri, 20 Nov 2015 11:20:23 +0100 Subject: [PATCH] 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 --- lib/checkcondition.cpp | 1 - lib/checkstl.cpp | 18 ++++++++---------- lib/tokenize.cpp | 11 ++++------- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index 76b2d1288..717f2369f 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -275,7 +275,6 @@ void CheckCondition::comparison() if (!_settings->isEnabled("style")) return; - // Experimental code based on AST for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { if (Token::Match(tok, "==|!=")) { const Token *expr1 = tok->astOperand1(); diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index d3ab89a18..3dcd46b30 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -930,8 +930,6 @@ static bool isLocal(const Token *tok) } namespace { - static const std::set stl_string = make_container< std::set >() << - "string" << "u16string" << "u32string" << "wstring" ; static const std::set stl_string_stream = make_container< std::set >() << "istringstream" << "ostringstream" << "stringstream" << "wstringstream" ; } @@ -955,9 +953,9 @@ void CheckStl::string_c_str() 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 - for (const Token* tok = func->argDef->next(); tok != 0; tok = tok->nextArgument()) { + for (std::list::const_iterator var = func->argumentList.cbegin(); var != func->argumentList.cend(); ++var) { 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)); } } @@ -980,7 +978,7 @@ void CheckStl::string_c_str() for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) { // Invalid usage.. 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); } else if (Token::Match(tok, "[;{}] %name% = %var% . str ( ) . c_str|data ( ) ;")) { const Variable* var = tok->next()->variable(); @@ -1014,7 +1012,7 @@ void CheckStl::string_c_str() tok2 = tok2->previous(); if (tok2 && Token::Match(tok2->tokAt(-4), ". c_str|data ( )")) { const Variable* var = tok2->tokAt(-5)->variable(); - if (var && var->isStlType(stl_string)) { + if (var && var->isStlStringType()) { string_c_strParam(tok, i->second); } else if (Token::Match(tok2->tokAt(-9), "%name% . str ( )")) { // Check ss.str().c_str() as parameter 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* if (returnType == charPtr) { 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); } else if (Token::Match(tok, "return %var% . str ( ) . c_str|data ( ) ;") && isLocal(tok->next()) && 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(); 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()) && - 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; break; } 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(), ";"); if (Token::Match(tok2->tokAt(-4), ". c_str|data ( )")) { 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); } } @@ -1265,7 +1263,7 @@ void CheckStl::uselessCalls() tok->varId() == tok->tokAt(4)->varId()) { uselessCallsSwapError(tok, tok->str()); } 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| )")) uselessCallsSubstrError(tok, false); else if (tok->strAt(4) == "0" && tok->linkAt(3)->strAt(-1) == "npos") { diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index c895ec507..3e39d68fb 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3714,7 +3714,7 @@ bool Tokenizer::simplifyTokenList2() // clear the _functionList so it can't contain dead pointers 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()) tok->clearAst(); @@ -3886,11 +3886,8 @@ void Tokenizer::printDebugOutput(unsigned int simplification) const printUnknownTypes(); // #5054 - the typeStartToken() should come before typeEndToken() - for (const Token *tok = tokens(); tok; tok = tok->next()) { - if (tok->varId() == 0U) - continue; - - const Variable *var = tok->variable(); + for (unsigned int varid = 1; varid < _symbolDatabase->getVariableListSize(); varid++) { + const Variable *var = _symbolDatabase->getVariableFromVarId(varid); if (!var) continue; @@ -3899,7 +3896,7 @@ void Tokenizer::printDebugOutput(unsigned int simplification) const typetok = typetok->next(); if (typetok != var->typeEndToken()) { - reportError(tok, + reportError(var->typeStartToken(), Severity::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()));