From 63e567eb508ff4e59170b844de94b5893b121c0c Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sat, 25 Jun 2022 08:38:17 +0200 Subject: [PATCH] Remove simplifyKnownVariables() (#4232) * Remove simplifyKnownVariables() * Add some test cases back * Remove unused functions * Format --- lib/mathlib.cpp | 17 - lib/mathlib.h | 1 - lib/tokenize.cpp | 828 ------------------------------------ lib/tokenize.h | 21 - test/testbufferoverrun.cpp | 20 + test/testleakautovar.cpp | 18 + test/testmathlib.cpp | 22 - test/testother.cpp | 12 + test/testsimplifytokens.cpp | 575 ------------------------- 9 files changed, 50 insertions(+), 1464 deletions(-) diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index 9784e03fa..bf6c5fb83 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -1037,23 +1037,6 @@ std::string MathLib::subtract(const std::string &first, const std::string &secon #endif } -std::string MathLib::incdec(const std::string & var, const std::string & op) -{ -#ifdef TEST_MATHLIB_VALUE - if (op == "++") - return value(var).add(1).str(); - else if (op == "--") - return value(var).add(-1).str(); -#else - if (op == "++") - return MathLib::add(var, "1"); - else if (op == "--") - return MathLib::subtract(var, "1"); -#endif - - throw InternalError(nullptr, std::string("Unexpected operation '") + op + "' in MathLib::incdec(). Please report this to Cppcheck developers."); -} - std::string MathLib::divide(const std::string &first, const std::string &second) { #ifdef TEST_MATHLIB_VALUE diff --git a/lib/mathlib.h b/lib/mathlib.h index 394c2ebb2..74c45c5a3 100644 --- a/lib/mathlib.h +++ b/lib/mathlib.h @@ -106,7 +106,6 @@ public: static std::string multiply(const std::string & first, const std::string & second); static std::string divide(const std::string & first, const std::string & second); static std::string mod(const std::string & first, const std::string & second); - static std::string incdec(const std::string & var, const std::string & op); static std::string calculate(const std::string & first, const std::string & second, char action); static std::string sin(const std::string & tok); diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index da6acbc47..fcfdd740e 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -5178,8 +5178,6 @@ bool Tokenizer::simplifyTokenList2() return false; modified = false; - modified |= simplifyKnownVariables(); - modified |= simplifyConstTernaryOp(); modified |= simplifyCalculations(); validate(); @@ -7038,767 +7036,6 @@ Token * Tokenizer::initVar(Token * tok) return tok; } - -bool Tokenizer::simplifyKnownVariables() -{ - // return value for function. Set to true if any simplifications are made - bool ret = false; - - // constants.. - { - std::unordered_map constantValues; - std::map constantVars; - std::unordered_map> constantValueUsages; - for (Token *tok = list.front(); tok; tok = tok->next()) { - // Reference to variable - if (Token::Match(tok, "%type%|* & %name% = %name% ;")) { - Token *start = tok->previous(); - while (Token::Match(start,"%type%|*|&")) - start = start->previous(); - if (!Token::Match(start,"[;{}]")) - continue; - const Token *reftok = tok->tokAt(2); - const Token *vartok = reftok->tokAt(2); - int level = 0; - for (Token *tok2 = tok->tokAt(6); tok2; tok2 = tok2->next()) { - if (tok2->str() == "{") { - ++level; - } else if (tok2->str() == "}") { - if (level <= 0) - break; - --level; - } else if (tok2->varId() == reftok->varId()) { - tok2->str(vartok->str()); - tok2->varId(vartok->varId()); - } - } - Token::eraseTokens(start, tok->tokAt(6)); - tok = start; - } - - if (tok->isName() && (Token::Match(tok, "static| const| static| %type% const| %name% = %any% ;") || - Token::Match(tok, "static| const| static| %type% const| %name% ( %any% ) ;"))) { - bool isconst = false; - for (const Token *tok2 = tok; (tok2->str() != "=") && (tok2->str() != "("); tok2 = tok2->next()) { - if (tok2->str() == "const") { - isconst = true; - break; - } - } - if (!isconst) - continue; - - Token *tok1 = tok; - - // start of statement - if (tok != list.front() && !Token::Match(tok->previous(),";|{|}|private:|protected:|public:")) - continue; - // skip "const" and "static" - while (Token::Match(tok, "const|static")) - tok = tok->next(); - // pod type - if (!tok->isStandardType()) - continue; - - Token * const vartok = (tok->next() && tok->next()->str() == "const") ? tok->tokAt(2) : tok->next(); - const Token * const valuetok = vartok->tokAt(2); - if (Token::Match(valuetok, "%bool%|%char%|%num%|%str% )| ;")) { - // record a constant value for this variable - constantValues[vartok->varId()] = valuetok->str(); - constantVars[vartok->varId()] = tok1; - } - } else if (tok->varId()) { - // find the entry for the known variable, if any. Exclude the location where the variable is assigned with next == "=" - if (constantValues.find(tok->varId()) != constantValues.end() && tok->next()->str() != "=") { - constantValueUsages[tok->varId()].push_back(tok); - } - } - } - - for (auto constantVar = constantVars.rbegin(); constantVar != constantVars.rend(); constantVar++) { - bool referenceFound = false; - std::list usageList = constantValueUsages[constantVar->first]; - for (Token* usage : usageList) { - // check if any usages of each known variable are a reference - if (Token::Match(usage->tokAt(-2), "(|[|,|{|return|%op% & %varid%", constantVar->first)) { - referenceFound = true; - break; - } - } - - if (!referenceFound) { - // replace all usages of non-referenced known variables with their value - for (Token* usage : usageList) { - usage->str(constantValues[constantVar->first]); - } - - Token* startTok = constantVar->second; - // remove variable assignment statement - while (startTok->next()->str() != ";") - startTok->deleteNext(); - startTok->deleteNext(); - - // #8579 if we can we want another token to delete startTok. if we can't it doesn't matter - if (startTok->previous()) { - startTok->previous()->deleteNext(); - } else if (startTok->next()) { - startTok->next()->deletePrevious(); - } else { - startTok->deleteThis(); - } - startTok = nullptr; - - constantVar->second = nullptr; - ret = true; - } - } - } - - // variable id for local, float/double, array variables - std::set localvars; - std::set floatvars; - std::set arrays; - - // auto variables.. - for (Token *tok = list.front(); tok; tok = tok->next()) { - // Search for a block of code - Token * const start = const_cast(startOfExecutableScope(tok)); - if (!start) - continue; - - for (const Token *tok2 = start->previous(); tok2 && !Token::Match(tok2, "[;{}]"); tok2 = tok2->previous()) { - if (tok2->varId() != 0) - localvars.insert(tok2->varId()); - } - - tok = start; - // parse the block of code.. - int indentlevel = 0; - Token *tok2 = tok; - for (; tok2; tok2 = tok2->next()) { - if (Token::Match(tok2, "[;{}] %type% %name%|*")) { - bool isfloat = false; - bool ispointer = false; - const Token *vartok = tok2->next(); - while (Token::Match(vartok, "%name%|* %name%|*")) { - if (Token::Match(vartok, "float|double")) - isfloat = true; - if (vartok->str() == "*") - ispointer = true; - vartok = vartok->next(); - } - if (Token::Match(vartok, "%var% ;|[")) - localvars.insert(vartok->varId()); - if (isfloat && !ispointer && Token::Match(vartok, "%var% ;")) - floatvars.insert(vartok->varId()); - if (Token::Match(vartok, "%var% [")) - arrays.insert(vartok->varId()); - } - - if (tok2->str() == "{") - ++indentlevel; - - else if (tok2->str() == "}") { - --indentlevel; - if (indentlevel <= 0) - break; - } - - else if (Token::simpleMatch(tok2, "for (")) - tok2 = tok2->next()->link(); - - else if (tok2->previous()->str() != "*" && !Token::Match(tok2->tokAt(-2), "* --|++") && - (Token::Match(tok2, "%name% = %bool%|%char%|%num%|%str%|%name% ;") || - Token::Match(tok2, "%name% [ %num%| ] = %str% ;") || - Token::Match(tok2, "%name% = & %name% ;") || - (Token::Match(tok2, "%name% = & %name% [ 0 ] ;") && arrays.find(tok2->tokAt(3)->varId()) != arrays.end()))) { - const int varid = tok2->varId(); - if (varid == 0) - continue; - - if (Token::Match(tok2->previous(), "[;{}]") && localvars.find(varid) == localvars.end()) - continue; - - // initialization of static variable => the value is not *known* - { - bool isstatic = false; - const Token *decl = tok2->previous(); - while (decl && (decl->isName() || decl->str() == "*")) { - if (decl->str() == "static") { - isstatic = true; - break; - } - decl = decl->previous(); - } - if (isstatic) - continue; - } - - // skip loop variable - if (Token::Match(tok2->tokAt(-2), "(|:: %type%")) { - const Token *tok3 = tok2->previous(); - do { - tok3 = tok3->tokAt(-2); - } while (Token::Match(tok3->previous(), ":: %type%")); - if (Token::Match(tok3->tokAt(-2), "for ( %type%")) - continue; - } - - // struct name.. - if (Token::Match(tok2, "%varid% = &| %varid%", tok2->varId())) - continue; - - const std::string structname = Token::Match(tok2->tokAt(-3), "[;{}] %name% .") ? - std::string(tok2->strAt(-2) + " .") : - std::string(); - - const Token * const valueToken = tok2->tokAt(2); - - std::string value; - nonneg int valueVarId = 0; - - Token *tok3 = nullptr; - bool valueIsPointer = false; - - // there could be a hang here if tok2 is moved back by the function calls below for some reason - if (Settings::terminated()) - return false; - - if (!simplifyKnownVariablesGetData(varid, &tok2, &tok3, value, valueVarId, valueIsPointer, floatvars.find(tok2->varId()) != floatvars.end())) - continue; - - if (valueVarId > 0 && arrays.find(valueVarId) != arrays.end()) - continue; - - ret |= simplifyKnownVariablesSimplify(&tok2, tok3, varid, structname, value, valueVarId, valueIsPointer, valueToken, indentlevel); - } - - else if (Token::Match(tok2, "strcpy|sprintf ( %name% , %str% ) ;")) { - const int varid(tok2->tokAt(2)->varId()); - if (varid == 0) - continue; - - const Token * const valueToken = tok2->tokAt(4); - std::string value(valueToken->str()); - if (tok2->str() == "sprintf") { - std::string::size_type n = 0; - while ((n = value.find("%%", n)) != std::string::npos) { - // Replace "%%" with "%" - erase the first '%' and continue past the second '%' - value.erase(n, 1); - ++n; - } - } - const int valueVarId(0); - const bool valueIsPointer(false); - Token *tok3 = tok2->tokAt(6); - ret |= simplifyKnownVariablesSimplify(&tok2, tok3, varid, emptyString, value, valueVarId, valueIsPointer, valueToken, indentlevel); - - // there could be a hang here if tok2 was moved back by the function call above for some reason - if (Settings::terminated()) - return false; - } - } - - if (tok2) - tok = tok2->previous(); - } - - return ret; -} - -bool Tokenizer::simplifyKnownVariablesGetData(nonneg int varid, Token **_tok2, Token **_tok3, std::string &value, nonneg int &valueVarId, bool &valueIsPointer, bool floatvar) -{ - Token *tok2 = *_tok2; - Token *tok3 = nullptr; - - if (Token::simpleMatch(tok2->tokAt(-2), "for (")) { - // only specific for loops is handled - if (!Token::Match(tok2, "%varid% = %num% ; %varid% <|<= %num% ; ++| %varid% ++| ) {", varid)) - return false; - - // is there a "break" in the for loop? - bool hasbreak = false; - const Token* end4 = tok2->linkAt(-1)->linkAt(1); - for (const Token *tok4 = tok2->previous()->link(); tok4 != end4; tok4 = tok4->next()) { - if (tok4->str() == "break") { - hasbreak = true; - break; - } - } - if (hasbreak) - return false; - - // no break => the value of the counter value is known after the for loop.. - const Token* compareTok = tok2->tokAt(5); - if (compareTok->str() == "<") { - value = compareTok->next()->str(); - valueVarId = compareTok->next()->varId(); - } else - value = MathLib::toString(MathLib::toLongNumber(compareTok->next()->str()) + 1); - - // Skip for-body.. - tok3 = tok2->previous()->link()->next()->link()->next(); - } else { - value = tok2->strAt(2); - valueVarId = tok2->tokAt(2)->varId(); - if (tok2->strAt(1) == "[") { - value = tok2->next()->link()->strAt(2); - valueVarId = 0; - } else if (value == "&") { - value = tok2->strAt(3); - valueVarId = tok2->tokAt(3)->varId(); - - // *ptr = &var; *ptr = 5; - // equals - // var = 5; not *var = 5; - if (tok2->strAt(4) == ";") - valueIsPointer = true; - } - - // Add a '.0' to a decimal value and therefore convert it to an floating point number. - else if (MathLib::isDec(tok2->strAt(2)) && floatvar) { - value += ".0"; - } - - // float variable: convert true/false to 1.0 / 0.0 - else if (tok2->tokAt(2)->isBoolean() && floatvar) { - value = (value == "true") ? "1.0" : "0.0"; - } - - if (Token::simpleMatch(tok2->next(), "= &")) - tok2 = tok2->tokAt(3); - - tok3 = tok2->next(); - } - *_tok2 = tok2; - *_tok3 = tok3; - return true; -} - -bool Tokenizer::simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, nonneg int varid, const std::string &structname, std::string &value, nonneg int valueVarId, bool valueIsPointer, const Token * const valueToken, int indentlevel) const -{ - const bool pointeralias(valueToken->isName() || Token::Match(valueToken, "& %name% [")); - const bool varIsGlobal = (indentlevel == 0); - const bool printDebug = mSettings->debugwarnings; - - if (mErrorLogger && !list.getFiles().empty()) - mErrorLogger->reportProgress(list.getFiles()[0], "Tokenize (simplifyKnownVariables)", tok3->progressValue()); - - if (isMaxTime()) - return false; - - bool ret = false; - - Token* bailOutFromLoop = nullptr; - int indentlevel3 = indentlevel; - bool ret3 = false; - for (; tok3; tok3 = tok3->next()) { - if (tok3->str() == "{") { - ++indentlevel3; - } else if (tok3->str() == "}") { - --indentlevel3; - if (indentlevel3 < indentlevel) { - if (Token::Match((*tok2)->tokAt(-7), "%type% * %name% ; %name% = & %name% ;") && - (*tok2)->strAt(-5) == (*tok2)->strAt(-3)) { - (*tok2) = (*tok2)->tokAt(-4); - Token::eraseTokens((*tok2), (*tok2)->tokAt(6)); - } - break; - } - } - - // Stop if there is a pointer alias and a shadow variable is - // declared in an inner scope (#3058) - if (valueIsPointer && tok3->varId() > 0 && - tok3->previous() && (tok3->previous()->isName() || tok3->previous()->str() == "*") && - valueToken->str() == "&" && - valueToken->next() && - valueToken->next()->isName() && - tok3->str() == valueToken->next()->str() && - tok3->varId() > valueToken->next()->varId()) { - // more checking if this is a variable declaration - bool decl = true; - for (const Token *tok4 = tok3->previous(); tok4; tok4 = tok4->previous()) { - if (Token::Match(tok4, "[;{}]")) - break; - - else if (tok4->isName()) { - if (tok4->varId() > 0) { - decl = false; - break; - } - } - - else if (!Token::Match(tok4, "[&*]")) { - decl = false; - break; - } - } - if (decl) - break; - } - - // Stop if label is found - if (Token::Match(tok3, "; %type% : ;")) - break; - - // Stop if break/continue is found .. - if (Token::Match(tok3, "break|continue")) - break; - if ((indentlevel3 > 1 || !Token::simpleMatch(Token::findsimplematch(tok3,";"), "; }")) && tok3->str() == "return") - ret3 = true; - if (ret3 && tok3->str() == ";") - break; - - if (pointeralias && Token::Match(tok3, ("!!= " + value).c_str())) - break; - - // Stop if a loop is found - if (pointeralias && Token::Match(tok3, "do|for|while")) - break; - - // Stop if unknown function call is seen and the variable is global: it might be - // changed by the function call - if (varIsGlobal && tok3->str() == ")" && tok3->link() && - Token::Match(tok3->link()->tokAt(-2), "[;{}] %name% (") && - !Token::Match(tok3->link()->previous(), "if|for|while|switch|BOOST_FOREACH")) - break; - - // Stop if something like 'while (--var)' is found - if (Token::Match(tok3, "for|while|do")) { - const Token *endpar = tok3->next()->link(); - if (Token::simpleMatch(endpar, ") {")) - endpar = endpar->next()->link(); - bool bailout = false; - for (const Token *tok4 = tok3; tok4 && tok4 != endpar; tok4 = tok4->next()) { - if (Token::Match(tok4, "++|-- %varid%", varid) || - Token::Match(tok4, "%varid% ++|--|=", varid)) { - bailout = true; - break; - } - } - if (bailout) - break; - } - - if (bailOutFromLoop) { - // This could be a loop, skip it, but only if it doesn't contain - // the variable we are checking for. If it contains the variable - // we will bail out. - if (tok3->varId() == varid) { - // Continue - //tok2 = bailOutFromLoop; - break; - } else if (tok3 == bailOutFromLoop) { - // We have skipped the loop - bailOutFromLoop = nullptr; - continue; - } - - continue; - } else if (tok3->str() == "{" && tok3->previous()->str() == ")") { - // There is a possible loop after the assignment. Try to skip it. - if (tok3->previous()->link() && - tok3->previous()->link()->strAt(-1) != "if") - bailOutFromLoop = tok3->link(); - continue; - } - - // Variable used in realloc (see Ticket #1649) - if (Token::Match(tok3, "%name% = realloc ( %name% ,") && - tok3->varId() == varid && - tok3->tokAt(4)->varId() == varid) { - tok3->tokAt(4)->str(value); - ret = true; - } - - // condition "(|&&|%OROR% %varid% )|&&|%OROR%|; - if (!Token::Match(tok3->previous(), "( %name% )") && - Token::Match(tok3->previous(), "&&|(|%oror% %varid% &&|%oror%|)|;", varid)) { - tok3->str(value); - tok3->varId(valueVarId); - ret = true; - } - - // parameter in function call.. - if (tok3->varId() == varid && Token::Match(tok3->previous(), "[(,] %name% [,)]")) { - // If the parameter is passed by value then simplify it - if (isFunctionParameterPassedByValue(tok3)) { - tok3->str(value); - tok3->varId(valueVarId); - ret = true; - } - } - - // Variable is used somehow in a non-defined pattern => bail out - if (tok3->varId() == varid) { - // This is a really generic bailout so let's try to avoid this. - // There might be lots of false negatives. - if (printDebug) { - // FIXME: Fix all the debug warnings for values and then - // remove this bailout - if (pointeralias) - break; - - // suppress debug-warning when calling member function - if (Token::Match(tok3->next(), ". %name% (")) - break; - - // suppress debug-warning when assignment - if (tok3->strAt(1) == "=") - break; - - // taking address of variable.. - if (Token::Match(tok3->tokAt(-2), "return|= & %name% ;")) - break; - - // parameter in function call.. - if (Token::Match(tok3->tokAt(-2), "%name% ( %name% ,|)") || - Token::Match(tok3->previous(), ", %name% ,|)")) - break; - - // conditional increment - if (Token::Match(tok3->tokAt(-3), ") { ++|--") || - Token::Match(tok3->tokAt(-2), ") { %name% ++|--")) - break; - - reportError(tok3, Severity::debug, "debug", - "simplifyKnownVariables: bailing out (variable="+tok3->str()+", value="+value+")"); - } - - break; - } - - // Using the variable in condition.. - if (Token::Match(tok3->previous(), ("if ( " + structname + " %varid% %cop%|)").c_str(), varid) || - Token::Match(tok3, ("( " + structname + " %varid% %comp%").c_str(), varid) || - Token::Match(tok3, ("%comp%|!|= " + structname + " %varid% %cop%|)|;").c_str(), varid) || - Token::Match(tok3->previous(), "strlen|free ( %varid% )", varid)) { - if (value[0] == '\"' && tok3->previous()->str() != "strlen") { - // bail out if value is a string unless if it's just given - // as parameter to strlen - break; - } - if (!structname.empty()) { - tok3->deleteNext(2); - } - if (Token::Match(valueToken, "& %name% ;")) { - tok3->insertToken("&"); - tok3 = tok3->next(); - } - tok3 = tok3->next(); - tok3->str(value); - tok3->varId(valueVarId); - ret = true; - } - - // pointer alias used in condition.. - if (Token::Match(valueToken,"& %name% ;") && Token::Match(tok3, ("( * " + structname + " %varid% %cop%").c_str(), varid)) { - tok3->deleteNext(); - if (!structname.empty()) - tok3->deleteNext(2); - tok3 = tok3->next(); - tok3->str(value); - tok3->varId(valueVarId); - ret = true; - } - - // Delete pointer alias - if (isCPP() && pointeralias && (tok3->str() == "delete") && tok3->next() && - (Token::Match(tok3->next(), "%varid% ;", varid) || - Token::Match(tok3->next(), "[ ] %varid%", varid))) { - tok3 = (tok3->next()->str() == "[") ? tok3->tokAt(3) : tok3->next(); - tok3->str(value); - tok3->varId(valueVarId); - ret = true; - } - - // Variable is used in function call.. - if (Token::Match(tok3, ("%name% ( " + structname + " %varid% ,").c_str(), varid)) { - static const char * const functionName[] = { - // always simplify - "strcmp", "strdup", - // don't simplify buffer value - "memcmp","memcpy","memmove","memset","strcpy","strncmp","strncpy" - }; - for (int i = 0; i < (sizeof(functionName) / sizeof(*functionName)); ++i) { - if (valueVarId == 0U && i >= 2) - break; - if (tok3->str() == functionName[i]) { - Token *par1 = tok3->tokAt(2); - if (!structname.empty()) { - par1->deleteNext(); - par1->deleteThis(); - } - par1->str(value); - par1->varId(valueVarId); - break; - } - } - } - - // Variable is used as 2nd parameter in function call.. - if (Token::Match(tok3, ("%name% ( %any% , " + structname + " %varid% ,|)").c_str(), varid)) { - static const char * const functionName[] = { - // always simplify - "strcmp","strcpy","strncmp","strncpy", - // don't simplify buffer value - "memcmp","memcpy","memmove" - }; - for (int i = 0; i < (sizeof(functionName) / sizeof(*functionName)); ++i) { - if (valueVarId == 0U && i >= 4) - break; - if (tok3->str() == functionName[i]) { - Token *par = tok3->tokAt(4); - if (!structname.empty()) { - par->deleteNext(); - par->deleteThis(); - } - par->str(value); - par->varId(valueVarId); - break; - } - } - } - - // array usage - if (value[0] != '\"' && Token::Match(tok3, ("[(,] " + structname + " %varid% [|%cop%").c_str(), varid)) { - if (!structname.empty()) { - tok3->deleteNext(2); - } - tok3 = tok3->next(); - tok3->str(value); - tok3->varId(valueVarId); - ret = true; - } - - // The >> operator is sometimes used to assign a variable in C++ - if (isCPP() && Token::Match(tok3, (">> " + structname + " %varid%").c_str(), varid)) { - // bailout for such code: ; std :: cin >> i ; - const Token *prev = tok3->previous(); - while (prev && prev->str() != "return" && Token::Match(prev, "%name%|::|*")) - prev = prev->previous(); - if (Token::Match(prev, ";|{|}|>>")) - break; - } - - // Variable is used in calculation.. - if (((tok3->previous()->varId() > 0) && Token::Match(tok3, ("& " + structname + " %varid%").c_str(), varid)) || - (Token::Match(tok3, ("[=+-*/%^|[] " + structname + " %varid% [=?+-*/%^|;])]").c_str(), varid) && !Token::Match(tok3, ("= " + structname + " %name% =").c_str())) || - Token::Match(tok3, ("[(=+-*/%^|[] " + structname + " %varid% <<|>>").c_str(), varid) || - Token::Match(tok3, ("<<|>> " + structname + " %varid% %cop%|;|]|)").c_str(), varid) || - Token::Match(tok3->previous(), ("[=+-*/%^|[] ( " + structname + " %varid% !!=").c_str(), varid)) { - if (value[0] == '\"') - break; - if (!structname.empty()) { - tok3->deleteNext(2); - ret = true; - } - tok3 = tok3->next(); - if (tok3->str() != value) - ret = true; - tok3->str(value); - tok3->varId(valueVarId); - if (tok3->previous()->str() == "*" && (valueIsPointer || Token::Match(valueToken, "& %name% ;"))) { - tok3 = tok3->previous(); - tok3->deleteThis(); - ret = true; - } else if (Token::Match(valueToken, "& %name% ;")) - tok3->insertToken("&", emptyString, true); - } - - if (Token::simpleMatch(tok3, "= {")) { - const Token* const end4 = tok3->linkAt(1); - for (const Token *tok4 = tok3; tok4 != end4; tok4 = tok4->next()) { - if (Token::Match(tok4, "{|, %varid% ,|}", varid)) { - tok4->next()->str(value); - tok4->next()->varId(valueVarId); - ret = true; - } - } - } - - // Using the variable in for-condition.. - if (Token::simpleMatch(tok3, "for (")) { - for (Token *tok4 = tok3->tokAt(2); tok4; tok4 = tok4->next()) { - if (Token::Match(tok4, "(|)")) - break; - - // Replace variable used in condition.. - if (Token::Match(tok4, "; %name% <|<=|!= %name% ; ++| %name% ++| )")) { - const Token *inctok = tok4->tokAt(5); - if (inctok->str() == "++") - inctok = inctok->next(); - if (inctok->varId() == varid) - break; - - if (tok4->next()->varId() == varid) { - tok4->next()->str(value); - tok4->next()->varId(valueVarId); - ret = true; - } - if (tok4->tokAt(3)->varId() == varid) { - tok4->tokAt(3)->str(value); - tok4->tokAt(3)->varId(valueVarId); - ret = true; - } - } - } - } - - if (indentlevel == indentlevel3 && Token::Match(tok3->next(), "%varid% ++|--", varid) && MathLib::isInt(value)) { - const std::string op(tok3->strAt(2)); - if (Token::Match(tok3, "[{};] %any% %any% ;")) { - tok3->deleteNext(3); - } else { - tok3 = tok3->next(); - tok3->str(value); - tok3->varId(valueVarId); - tok3->deleteNext(); - } - value = MathLib::incdec(value, op); - if (!Token::simpleMatch((*tok2)->tokAt(-2), "for (")) { - (*tok2)->tokAt(2)->str(value); - (*tok2)->tokAt(2)->varId(valueVarId); - } - ret = true; - } - - if (indentlevel == indentlevel3 && Token::Match(tok3->next(), "++|-- %varid%", varid) && MathLib::isInt(value) && - !Token::Match(tok3->tokAt(3), "[.[]")) { - value = MathLib::incdec(value, tok3->next()->str()); - (*tok2)->tokAt(2)->str(value); - (*tok2)->tokAt(2)->varId(valueVarId); - if (Token::Match(tok3, "[;{}] %any% %any% ;")) { - tok3->deleteNext(3); - } else { - tok3->deleteNext(); - tok3->next()->str(value); - tok3->next()->varId(valueVarId); - } - tok3 = tok3->next(); - ret = true; - } - - // return variable.. - if (Token::Match(tok3, "return %varid% %any%", varid) && - valueToken->str() != "&" && - (tok3->tokAt(2)->isExtendedOp() || tok3->strAt(2) == ";") && - value[0] != '\"') { - tok3->next()->str(value); - tok3->next()->varId(valueVarId); - } - - else if (pointeralias && Token::Match(tok3, "return * %varid% ;", varid) && value[0] != '\"') { - tok3->deleteNext(); - tok3->next()->str(value); - tok3->next()->varId(valueVarId); - } - } - return ret; -} - - void Tokenizer::elseif() { for (Token *tok = list.front(); tok; tok = tok->next()) { @@ -8162,71 +7399,6 @@ bool Tokenizer::isScopeNoReturn(const Token *endScopeToken, bool *unknown) const //--------------------------------------------------------------------------- -bool Tokenizer::isFunctionParameterPassedByValue(const Token *fpar) const -{ - // TODO: If symbol database is available, use it. - const Token *ftok; - - // Look at function call, what parameter number is it? - int parameter = 1; - for (ftok = fpar->previous(); ftok; ftok = ftok->previous()) { - if (ftok->str() == "(") - break; - else if (ftok->str() == ")") - ftok = ftok->link(); - else if (ftok->str() == ",") - ++parameter; - else if (Token::Match(ftok, "[;{}]")) - break; - } - - // Is this a function call? - if (ftok && Token::Match(ftok->tokAt(-2), "[;{}=] %name% (")) { - const std::string& functionName(ftok->previous()->str()); - - if (functionName == "return") - return true; - - // Locate function declaration.. - for (const Token *tok = tokens(); tok; tok = tok->next()) { - if (tok->str() == "{") - tok = tok->link(); - else if (Token::Match(tok, "%type% (") && tok->str() == functionName) { - // Goto parameter - tok = tok->tokAt(2); - int par = 1; - while (tok && par < parameter) { - if (tok->str() == ")") - break; - if (tok->str() == ",") - ++par; - tok = tok->next(); - } - if (!tok) - return false; - - // If parameter was found, determine if it's passed by value - if (par == parameter) { - bool knowntype = false; - while (tok && tok->isName()) { - knowntype |= tok->isStandardType(); - knowntype |= (tok->str() == "struct"); - tok = tok->next(); - } - if (!tok || !knowntype) - return false; - if (tok->str() != "," && tok->str() != ")") - return false; - return true; - } - } - } - } - return false; -} - -//--------------------------------------------------------------------------- - void Tokenizer::eraseDeadCode(Token *begin, const Token *end) { if (!begin) diff --git a/lib/tokenize.h b/lib/tokenize.h index 8bcc07b30..c5c1c3ce6 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -329,27 +329,6 @@ public: */ bool simplifyUsing(); - /** - * A simplify function that replaces a variable with its value in cases - * when the value is known. e.g. "x=10; if(x)" => "x=10;if(10)" - * - * @return true if modifications to token-list are done. - * false if no modifications are done. - */ - bool simplifyKnownVariables(); - - /** - * Utility function for simplifyKnownVariables. Get data about an - * assigned variable. - */ - static bool simplifyKnownVariablesGetData(nonneg int varid, Token **_tok2, Token **_tok3, std::string &value, nonneg int &valueVarId, bool &valueIsPointer, bool floatvar); - - /** - * utility function for simplifyKnownVariables. Perform simplification - * of a given variable - */ - bool simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, nonneg int varid, const std::string &structname, std::string &value, nonneg int valueVarId, bool valueIsPointer, const Token * const valueToken, int indentlevel) const; - /** Simplify useless C++ empty namespaces, like: 'namespace %name% { }'*/ void simplifyEmptyNamespaces(); diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 109944fe3..6d34d4a12 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -191,6 +191,7 @@ private: TEST_CASE(array_index_64); // #10878 TEST_CASE(array_index_65); // #11066 TEST_CASE(array_index_66); // #10740 + TEST_CASE(array_index_67); // #1596 TEST_CASE(array_index_multidim); TEST_CASE(array_index_switch_in_for); TEST_CASE(array_index_for_in_for); // FP: #2634 @@ -1852,6 +1853,25 @@ private: errout.str()); } + void array_index_67() { + check("void func(int i) {\n" // #1596 + " int types[3];\n" + " int type_cnt = 0;\n" + " if (i == 0) {\n" + " types[type_cnt] = 0;\n" + " type_cnt++;\n" + " types[type_cnt] = 0;\n" + " type_cnt++;\n" + " types[type_cnt] = 0;\n" + " type_cnt++;\n" + " } else {\n" + " types[type_cnt] = 1;\n" + " type_cnt++;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + void array_index_multidim() { check("void f()\n" "{\n" diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 4262b59d3..cd46b070b 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -93,6 +93,7 @@ private: TEST_CASE(assign21); // #10186 TEST_CASE(assign22); // #9139 TEST_CASE(assign23); + TEST_CASE(assign24); // #7440 TEST_CASE(isAutoDealloc); @@ -504,6 +505,23 @@ private: settings = s; } + void assign24() { // #7440 + check("void f() {\n" + " char* data = new char[100];\n" + " char** dataPtr = &data;\n" + " delete[] *dataPtr;\n" + "}\n", true); + ASSERT_EQUALS("", errout.str()); + + check("void f() {\n" + " char* data = new char[100];\n" + " char** dataPtr = &data;\n" + " printf(\"test\");\n" + " delete[] *dataPtr;\n" + "}\n", true); + ASSERT_EQUALS("", errout.str()); + } + void isAutoDealloc() { check("void f() {\n" " char *p = new char[100];" diff --git a/test/testmathlib.cpp b/test/testmathlib.cpp index 3167e4a5f..07d0fd622 100644 --- a/test/testmathlib.cpp +++ b/test/testmathlib.cpp @@ -57,7 +57,6 @@ private: TEST_CASE(toDoubleNumber); TEST_CASE(naninf); TEST_CASE(isNullValue); - TEST_CASE(incdec); TEST_CASE(sin); TEST_CASE(cos); TEST_CASE(tan); @@ -1192,27 +1191,6 @@ private: ASSERT_EQUALS(false, MathLib::isNullValue("-ENOMEM")); } - void incdec() const { - // increment - { - const MathLib::biguint num = ~10U; - const std::string op = "++"; - const std::string strNum = MathLib::incdec(MathLib::toString(num), op); - const MathLib::biguint incrementedNum = MathLib::toULongNumber(strNum); - ASSERT_EQUALS(num + 1U, incrementedNum); - } - // decrement - { - const MathLib::biguint num = ~10U; - const std::string op = "--"; - const std::string strNum = MathLib::incdec(MathLib::toString(num), op); - const MathLib::biguint decrementedNum = MathLib::toULongNumber(strNum); - ASSERT_EQUALS(num - 1U, decrementedNum); - } - // invalid operation - ASSERT_THROW(MathLib::incdec("1", "x"), InternalError); // throw - } - void sin() const { ASSERT_EQUALS("0.0", MathLib::sin("0")); } diff --git a/test/testother.cpp b/test/testother.cpp index 6446bdf56..406371886 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -64,6 +64,7 @@ private: TEST_CASE(zeroDiv11); TEST_CASE(zeroDiv12); TEST_CASE(zeroDiv13); + TEST_CASE(zeroDiv14); // #1169 TEST_CASE(zeroDivCond); // division by zero / useless condition @@ -587,6 +588,17 @@ private: ASSERT_EQUALS("[test.cpp:4]: (error) Division by zero.\n", errout.str()); } + void zeroDiv14() { + check("void f() {\n" // #1169 + " double dx = 1.;\n" + " int ix = 1;\n" + " int i = 1;\n" + " std::cout << ix / (i >> 1) << std::endl;\n" + " std::cout << dx / (i >> 1) << std::endl;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5]: (error) Division by zero.\n", errout.str()); + } + void zeroDivCond() { check("void f(unsigned int x) {\n" " int y = 17 / x;\n" diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 6a73b8bab..38f53c57c 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -101,9 +101,7 @@ private: TEST_CASE(simplifyArrayAccessSyntax); TEST_CASE(pointeralias1); - TEST_CASE(pointeralias2); TEST_CASE(pointeralias3); - TEST_CASE(pointeralias4); // struct ABC { } abc; => struct ABC { }; ABC abc; TEST_CASE(simplifyStructDecl1); @@ -137,58 +135,36 @@ private: TEST_CASE(simplifyNamespaceAliases1); TEST_CASE(simplifyNamespaceAliases2); // ticket #10281 - TEST_CASE(simplifyKnownVariables1); TEST_CASE(simplifyKnownVariables2); TEST_CASE(simplifyKnownVariables3); TEST_CASE(simplifyKnownVariables4); TEST_CASE(simplifyKnownVariables5); - TEST_CASE(simplifyKnownVariables6); - TEST_CASE(simplifyKnownVariables7); - TEST_CASE(simplifyKnownVariables8); - TEST_CASE(simplifyKnownVariables9); - TEST_CASE(simplifyKnownVariables10); - TEST_CASE(simplifyKnownVariables11); TEST_CASE(simplifyKnownVariables13); TEST_CASE(simplifyKnownVariables14); - TEST_CASE(simplifyKnownVariables15); TEST_CASE(simplifyKnownVariables16); TEST_CASE(simplifyKnownVariables17); TEST_CASE(simplifyKnownVariables18); TEST_CASE(simplifyKnownVariables19); - TEST_CASE(simplifyKnownVariables20); TEST_CASE(simplifyKnownVariables21); - TEST_CASE(simplifyKnownVariables22); - TEST_CASE(simplifyKnownVariables23); TEST_CASE(simplifyKnownVariables25); - TEST_CASE(simplifyKnownVariables27); - TEST_CASE(simplifyKnownVariables28); // FIXME Does expression id handle these? TEST_CASE(simplifyKnownVariables29); // ticket #1811 TEST_CASE(simplifyKnownVariables30); - TEST_CASE(simplifyKnownVariables31); - TEST_CASE(simplifyKnownVariables32); // const - TEST_CASE(simplifyKnownVariables33); // struct variable TEST_CASE(simplifyKnownVariables34); TEST_CASE(simplifyKnownVariables36); // ticket #2304 - known value for strcpy parameter - TEST_CASE(simplifyKnownVariables39); - TEST_CASE(simplifyKnownVariables41); // p=&x; if (p) .. TEST_CASE(simplifyKnownVariables42); // ticket #2031 - known string value after strcpy TEST_CASE(simplifyKnownVariables43); TEST_CASE(simplifyKnownVariables44); // ticket #3117 - don't simplify static variables - TEST_CASE(simplifyKnownVariables45); // ticket #3281 - static constant variable not simplified TEST_CASE(simplifyKnownVariables46); // ticket #3587 - >> TEST_CASE(simplifyKnownVariables47); // ticket #3627 - >> TEST_CASE(simplifyKnownVariables48); // ticket #3754 - wrong simplification in for loop header TEST_CASE(simplifyKnownVariables49); // #3691 - continue in switch TEST_CASE(simplifyKnownVariables50); // #4066 sprintf changes TEST_CASE(simplifyKnownVariables51); // #4409 hang - TEST_CASE(simplifyKnownVariables53); // references TEST_CASE(simplifyKnownVariables54); // #4913 'x' is not 0 after *--x=0; - TEST_CASE(simplifyKnownVariables55); // pointer alias TEST_CASE(simplifyKnownVariables56); // ticket #5301 - >> TEST_CASE(simplifyKnownVariables57); // ticket #4724 TEST_CASE(simplifyKnownVariables58); // ticket #5268 TEST_CASE(simplifyKnownVariables59); // skip for header - TEST_CASE(simplifyKnownVariables60); // #6829 TEST_CASE(simplifyKnownVariables61); // #7805 TEST_CASE(simplifyKnownVariables62); // #5666 - p=&str[0] TEST_CASE(simplifyKnownVariables63); // #10798 @@ -203,11 +179,8 @@ private: TEST_CASE(simplifyKnownVariablesClassMember); // #2815 - value of class member may be changed by function call TEST_CASE(simplifyKnownVariablesFunctionCalls); // Function calls (don't assume pass by reference) TEST_CASE(simplifyKnownVariablesGlobalVars); - TEST_CASE(simplifyKnownVariablesPointerAliasFunctionCall); // #7440 TEST_CASE(simplifyKnownVariablesNamespace); // #10059 - TEST_CASE(simplify_constants2); - TEST_CASE(simplify_constants4); TEST_CASE(simplify_constants6); // Ticket #5625: Ternary operator as template parameter TEST_CASE(simplifyVarDeclInitLists); } @@ -2607,16 +2580,6 @@ private: } } - void pointeralias2() { - const char code[] = "void f()\n" - "{\n" - " int i;\n" - " int *p = &i;\n" - " return *p;\n" - "}\n"; - ASSERT_EQUALS("void f ( ) { int i ; int * p ; return i ; }", tok(code)); - } - void pointeralias3() { const char code[] = "void f()\n" "{\n" @@ -2635,18 +2598,6 @@ private: ASSERT_EQUALS(expected, tok(code)); } - void pointeralias4() { - const char code[] = "int f()\n" - "{\n" - " int i;\n" - " int *p = &i;\n" - " *p = 5;\n" - " return i;\n" - "}\n"; - const char expected[] = "int f ( ) { int i ; int * p ; i = 5 ; return 5 ; }"; - ASSERT_EQUALS(expected, tok(code)); - } - void simplifyStructDecl1() { { const char code[] = "struct ABC { } abc;"; @@ -3228,37 +3179,9 @@ private: std::istringstream istr(code); ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); - (tokenizer.simplifyKnownVariables)(); - return tokenizer.tokens()->stringifyList(nullptr, false); } - void simplifyKnownVariables1() { - { - const char code[] = "void f()\n" - "{\n" - " int a = 10;\n" - " if (a);\n" - "}\n"; - - ASSERT_EQUALS( - "void f ( ) { int a ; a = 10 ; if ( 10 ) { ; } }", - simplifyKnownVariables(code)); - } - - { - const char code[] = "void f()\n" - "{\n" - " int a = 10;\n" - " if (!a);\n" - "}\n"; - - ASSERT_EQUALS( - "void f ( ) { int a ; a = 10 ; if ( ! 10 ) { ; } }", - simplifyKnownVariables(code)); - } - } - void simplifyKnownVariables2() { const char code[] = "void f()\n" "{\n" @@ -3313,136 +3236,6 @@ private: simplifyKnownVariables(code)); } - void simplifyKnownVariables6() { - const char code[] = "void f()\n" - "{\n" - " char str[2];" - " int a = 4;\n" - " str[a] = 0;\n" - "}\n"; - - ASSERT_EQUALS( - "void f ( ) { char str [ 2 ] ; int a ; a = 4 ; str [ 4 ] = 0 ; }", - simplifyKnownVariables(code)); - } - - void simplifyKnownVariables7() { - const char code[] = "void foo()\n" - "{\n" - " int i = 22;\n" - " abc[i++] = 1;\n" - " abc[++i] = 2;\n" - "}\n"; - - ASSERT_EQUALS( - "void foo ( ) { int i ; i = 24 ; abc [ 22 ] = 1 ; abc [ 24 ] = 2 ; }", - simplifyKnownVariables(code)); - } - - void simplifyKnownVariables8() { - const char code[] = "void foo()\n" - "{\n" - " int i = 22;\n" - " i++;\n" - " abc[i] = 0;\n" - "}\n"; - - ASSERT_EQUALS( - "void foo ( ) { int i ; i = 23 ; abc [ 23 ] = 0 ; }", - simplifyKnownVariables(code)); - } - - void simplifyKnownVariables9() { - const char code[] = "void foo()\n" - "{\n" - " int a = 1, b = 2;\n" - " if (a < b)\n" - " ;\n" - "}\n"; - - ASSERT_EQUALS( - "void foo ( ) { int a ; a = 1 ; int b ; b = 2 ; if ( 1 < 2 ) { ; } }", - simplifyKnownVariables(code)); - } - - void simplifyKnownVariables10() { - { - const char code[] = "void f()\n" - "{\n" - " bool b=false;\n" - "\n" - " {\n" - " b = true;\n" - " }\n" - "\n" - " if( b )\n" - " {\n" - " a();\n" - " }\n" - "}\n"; - - const std::string expected1("void f ( ) {" - " bool b ; b = false ;" - " { b = true ; }"); - - TODO_ASSERT_EQUALS( - expected1 + " if ( true ) { a ( ) ; } }", - expected1 + " if ( b ) { a ( ) ; } }", - simplifyKnownVariables(code)); - - } - - { - const char code[] = "void f()\n" - "{\n" - " bool b=false;\n" - " { b = false; }\n" - " {\n" - " b = true;\n" - " }\n" - "\n" - " if( b )\n" - " {\n" - " a();\n" - " }\n" - "}\n"; - - TODO_ASSERT_EQUALS( - "void f ( ) { bool b ; b = false ; { b = false ; } { b = true ; } if ( true ) { a ( ) ; } }", - "void f ( ) { bool b ; b = false ; { b = false ; } { b = true ; } if ( b ) { a ( ) ; } }", - simplifyKnownVariables(code)); - } - - { - const char code[] = "void f()\n" - "{\n" - " int b=0;\n" - " b = 1;\n" - " for( int i = 0; i < 10; i++ )" - " {\n" - " }\n" - "\n" - " return b;\n" - "}\n"; - - ASSERT_EQUALS( - "void f ( ) { int b ; b = 0 ; b = 1 ; for ( int i = 0 ; i < 10 ; i ++ ) { } return 1 ; }", - simplifyKnownVariables(code)); - } - } - - void simplifyKnownVariables11() { - const char code[] = "const int foo = 0;\n" - "int main()\n" - "{\n" - " int foo=0;\n" - "}\n"; - - ASSERT_EQUALS( - "int main ( ) { int foo ; foo = 0 ; }", - simplifyKnownVariables(code)); - } - void simplifyKnownVariables13() { const char code[] = "void f()\n" "{\n" @@ -3461,32 +3254,6 @@ private: ASSERT_EQUALS(code, simplifyKnownVariables(code)); } - void simplifyKnownVariables15() { - { - const char code[] = "int main()\n" - "{\n" - " int x=5;\n" - " std::cout << 10 / x << std::endl;\n" - "}\n"; - - ASSERT_EQUALS( - "int main ( ) { int x ; x = 5 ; std :: cout << 10 / 5 << std :: endl ; }", - simplifyKnownVariables(code)); - } - - { - const char code[] = "int main()\n" - "{\n" - " int x=5;\n" - " std::cout << x / ( x == 1 ) << std::endl;\n" - "}\n"; - - ASSERT_EQUALS( - "int main ( ) { int x ; x = 5 ; std :: cout << 5 / ( 5 == 1 ) << std :: endl ; }", - simplifyKnownVariables(code)); - } - } - void simplifyKnownVariables16() { // ticket #807 - segmentation fault when macro isn't found const char code[] = "void f ( ) { int n = 1; DISPATCH(while); }"; @@ -3515,111 +3282,12 @@ private: simplifyKnownVariables(code)); } - void simplifyKnownVariables20() { - const char code[] = "void f()\n" - "{\n" - " int i = 0;\n" - " if (x) {\n" - " if (i) i=0;\n" - " }\n" - "}\n"; - - ASSERT_EQUALS( - "void f ( ) { int i ; i = 0 ; if ( x ) { if ( 0 ) { i = 0 ; } } }", - simplifyKnownVariables(code)); - } - void simplifyKnownVariables21() { - const char code[] = "void foo() { int n = 10; for (int i = 0; i < n; ++i) { } }"; - - ASSERT_EQUALS( - "void foo ( ) { int n ; n = 10 ; for ( int i = 0 ; i < 10 ; ++ i ) { } }", - simplifyKnownVariables(code)); - ASSERT_EQUALS( "void foo ( int i ) { int n ; n = i ; for ( i = 0 ; i < n ; ++ i ) { } }", simplifyKnownVariables("void foo(int i) { int n = i; for (i = 0; i < n; ++i) { } }")); } - void simplifyKnownVariables22() { - // This testcase is related to ticket #1169 - { - const char code[] = "void foo()\n" - "{\n" - " int n = 10;\n" - " i = (n >> 1);\n" - "}\n"; - - ASSERT_EQUALS( - "void foo ( ) { int n ; n = 10 ; i = 10 >> 1 ; }", - simplifyKnownVariables(code)); - } - { - const char code[] = "void foo()\n" - "{\n" - " int n = 10;\n" - " i = (n << 1);\n" - "}\n"; - - ASSERT_EQUALS( - "void foo ( ) { int n ; n = 10 ; i = 10 << 1 ; }", - simplifyKnownVariables(code)); - } - { - const char code[] = "void foo()\n" - "{\n" - " int n = 10;\n" - " i = (1 << n);\n" - "}\n"; - - ASSERT_EQUALS( - "void foo ( ) { int n ; n = 10 ; i = 1 << 10 ; }", - simplifyKnownVariables(code)); - } - { - const char code[] = "void foo()\n" - "{\n" - " int n = 10;\n" - " i = (1 >> n);\n" - "}\n"; - - ASSERT_EQUALS( - "void foo ( ) { int n ; n = 10 ; i = 1 >> 10 ; }", - simplifyKnownVariables(code)); - } - } - - void simplifyKnownVariables23() { - // This testcase is related to ticket #1596 - const char code[] = "void foo(int x)\n" - "{\n" - " int a[10], c = 0;\n" - " if (x) {\n" - " a[c] = 0;\n" - " c++;\n" - " } else {\n" - " a[c] = 0;\n" - " }\n" - "}\n"; - - TODO_ASSERT_EQUALS( - "void foo ( int x ) " - "{" - " int a [ 10 ] ; int c ; c = 0 ;" - " if ( x ) { a [ 0 ] = 0 ; c = 1 ; }" - " else { a [ 0 ] = 0 ; } " - "}", - - "void foo ( int x ) " - "{" - " int a [ 10 ] ; int c ; c = 0 ;" - " if ( x ) { a [ 0 ] = 0 ; c ++ ; }" - " else { a [ c ] = 0 ; } " - "}", - - simplifyKnownVariables(code)); - } - void simplifyKnownVariables25() { { // This testcase is related to ticket #1646 @@ -3672,43 +3340,6 @@ private: } } - void simplifyKnownVariables27() { - // This testcase is related to ticket #1633 - const char code[] = "void foo()\n" - "{\n" - " int i1 = 1;\n" - " int i2 = 2;\n" - " int i3 = (i1 + i2) * 3;\n" - "}\n"; - ASSERT_EQUALS( - "void foo ( ) " - "{" - " int i1 ; i1 = 1 ;" - " int i2 ; i2 = 2 ;" - " int i3 ; i3 = ( 1 + 2 ) * 3 ; " - "}", - simplifyKnownVariables(code)); - } - - void simplifyKnownVariables28() { - const char code[] = "void foo(int g)\n" - "{\n" - " int i = 2;\n" - " if (g) {\n" - " }\n" - " if (i > 0) {\n" - " }\n" - "}\n"; - ASSERT_EQUALS( - "void foo ( int g ) " - "{" - " int i ; i = 2 ;" - " if ( g ) { }" - " if ( 2 > 0 ) { } " - "}", - simplifyKnownVariables(code)); - } - void simplifyKnownVariables29() { // ticket #1811 { const char code[] = "int foo(int u, int v)\n" @@ -4049,48 +3680,6 @@ private: ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); } - void simplifyKnownVariables31() { - const char code[] = "void foo(const char str[]) {\n" - " const char *p = str;\n" - " if (p[0] == 0) {\n" - " }\n" - "}\n"; - const char expected[] = "void foo ( const char str [ ] ) {\n" - "const char * p ; p = str ;\n" - "if ( str [ 0 ] == 0 ) {\n" - "}\n" - "}"; - ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); - } - - void simplifyKnownVariables32() { - { - const char code[] = "void foo() {\n" - " const int x = 0;\n" - " bar(0,x);\n" - "}\n"; - const char expected[] = "void foo ( ) {\n\nbar ( 0 , 0 ) ;\n}"; - ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); - } - - { - const char code[] = "static int const SZ = 22; char str[SZ];\n"; - ASSERT_EQUALS("char str [ 22 ] ;", tokenizeAndStringify(code,true)); - } - } - - void simplifyKnownVariables33() { - const char code[] = "static void foo(struct Foo *foo) {\n" - " foo->a = 23;\n" - " x[foo->a] = 0;\n" - "}\n"; - const char expected[] = "static void foo ( struct Foo * foo ) {\n" - "foo . a = 23 ;\n" - "x [ 23 ] = 0 ;\n" - "}"; - ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); - } - void simplifyKnownVariables34() { const char code[] = "void f() {\n" " int x = 10;\n" @@ -4106,13 +3695,6 @@ private: } void simplifyKnownVariables36() { - // Ticket #2304 - const char code[] = "void f() {" - " const char *q = \"hello\";" - " strcpy(p, q);" - "}"; - const char expected[] = "void f ( ) { const char * q ; q = \"hello\" ; strcpy ( p , \"hello\" ) ; }"; - ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); // Ticket #5972 const char code2[] = "void f() {" @@ -4123,50 +3705,7 @@ private: ASSERT_EQUALS(expected2, tokenizeAndStringify(code2, true)); } - void simplifyKnownVariables39() { - // Ticket #2296 - simplify pointer alias 'delete p;' - { - const char code[] = "void f() {\n" - " int *x;\n" - " int *y = x;\n" - " delete y;\n" - "}"; - ASSERT_EQUALS("void f ( ) {\nint * x ;\nint * y ; y = x ;\ndelete x ;\n}", tokenizeAndStringify(code, true)); - } - { - const char code[] = "void f() {\n" - " int *x;\n" - " int *y = x;\n" - " delete [] y;\n" - "}"; - ASSERT_EQUALS("void f ( ) {\nint * x ;\nint * y ; y = x ;\ndelete [ ] x ;\n}", tokenizeAndStringify(code, true)); - } - } - - void simplifyKnownVariables41() { - const char code[] = "void f() {\n" - " int x = 0;\n" - " const int *p; p = &x;\n" - " if (p) { return 0; }\n" - "}"; - ASSERT_EQUALS("void f ( ) {\nint x ; x = 0 ;\nconst int * p ; p = & x ;\nif ( & x ) { return 0 ; }\n}", tokenizeAndStringify(code, true)); - } - void simplifyKnownVariables42() { - { - const char code[] = "void f() {\n" - " char str1[10], str2[10];\n" - " strcpy(str1, \"abc\");\n" - " strcpy(str2, str1);\n" - "}"; - const char expected[] = "void f ( ) {\n" - "char str1 [ 10 ] ; char str2 [ 10 ] ;\n" - "strcpy ( str1 , \"abc\" ) ;\n" - "strcpy ( str2 , \"abc\" ) ;\n" - "}"; - ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); - } - { const char code[] = "void f() {\n" " char a[10];\n" @@ -4261,20 +3800,6 @@ private: ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); } - void simplifyKnownVariables45() { - const char code[] = "class Fred {\n" - "private:\n" - " const static int NUM = 2;\n" - " int array[NUM];\n" - "}"; - const char expected[] = "class Fred {\n" - "private:\n" - "\n" - "int array [ 2 ] ;\n" - "}"; - ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); - } - void simplifyKnownVariables46() { const char code[] = "void f() {\n" " int x = 0;\n" @@ -4335,45 +3860,6 @@ private: } void simplifyKnownVariables50() { // #4066 - { - const char code[] = "void f() {\n" - " char str1[10], str2[10];\n" - " sprintf(str1, \"%%\");\n" - " strcpy(str2, str1);\n" - "}"; - const char expected[] = "void f ( ) {\n" - "char str1 [ 10 ] ; char str2 [ 10 ] ;\n" - "sprintf ( str1 , \"%%\" ) ;\n" - "strcpy ( str2 , \"%\" ) ;\n" - "}"; - ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); - } - { - const char code[] = "void f() {\n" - " char str1[25], str2[25];\n" - " sprintf(str1, \"abcdef%%%% and %% and %\");\n" - " strcpy(str2, str1);\n" - "}"; - const char expected[] = "void f ( ) {\n" - "char str1 [ 25 ] ; char str2 [ 25 ] ;\n" - "sprintf ( str1 , \"abcdef%%%% and %% and %\" ) ;\n" - "strcpy ( str2 , \"abcdef%% and % and %\" ) ;\n" - "}"; - ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); - } - { - const char code[] = "void f() {\n" - " char str1[10], str2[10];\n" - " sprintf(str1, \"abc\");\n" - " strcpy(str2, str1);\n" - "}"; - const char expected[] = "void f ( ) {\n" - "char str1 [ 10 ] ; char str2 [ 10 ] ;\n" - "sprintf ( str1 , \"abc\" ) ;\n" - "strcpy ( str2 , \"abc\" ) ;\n" - "}"; - ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); - } { //don't simplify '&x'! const char code[] = "const char * foo ( ) {\n" @@ -4425,21 +3911,10 @@ private: ASSERT_THROW(tokenizeAndStringify(code, true), InternalError); } - void simplifyKnownVariables53() { // references - ASSERT_EQUALS("void f ( ) { int x ; x = abc ( ) ; }", tokenizeAndStringify("void f() { int x; int &ref=x; ref=abc(); }", true)); - ASSERT_EQUALS("void f ( ) { int * p ; p = abc ( ) ; }", tokenizeAndStringify("void f() { int *p; int *&ref=p; ref=abc(); }", true)); - } - void simplifyKnownVariables54() { // #4913 ASSERT_EQUALS("void f ( int * p ) { * -- p = 0 ; * p = 0 ; }", tokenizeAndStringify("void f(int*p) { *--p=0; *p=0; }", true)); } - void simplifyKnownVariables55() { // pointer alias - ASSERT_EQUALS("void f ( ) { int a ; int * p ; if ( a > 0 ) { } }", tokenizeAndStringify("void f() { int a; int *p=&a; if (*p>0) {} }", true)); - ASSERT_EQUALS("void f ( ) { int a ; struct AB ab ; ab . a = & a ; if ( a > 0 ) { } }", tokenizeAndStringify("void f() { int a; struct AB ab; ab.a = &a; if (*ab.a>0) {} }", true)); - ASSERT_EQUALS("void f ( ) { int a ; int * p ; if ( x > a ) { } }", tokenizeAndStringify("void f() { int a; int *p=&a; if (x>*p) {} }", true)); - } - void simplifyKnownVariables56() { // ticket #5301 - >> ASSERT_EQUALS("void f ( ) { int a ; a = 0 ; int b ; b = 0 ; * p >> a >> b ; return a / b ; }", tokenizeAndStringify("void f() { int a=0,b=0; *p>>a>>b; return a/b; }", true)); @@ -4485,21 +3960,6 @@ private: "}", tokenizeAndStringify(code, true)); } - void simplifyKnownVariables60() { // #6829 - const char code[] = "void f() {\n" - " int i = 1;\n" - " const int * const constPtrToConst = &i;\n" - " std::cout << *constPtrToConst << std::endl;\n" - " std::cout << constPtrToConst << std::endl;\n" - "}"; - ASSERT_EQUALS("void f ( ) {\n" - "int i ; i = 1 ;\n" - "const int * const constPtrToConst ; constPtrToConst = & i ;\n" - "std :: cout << i << std :: endl ;\n" - "std :: cout << & i << std :: endl ;\n" - "}", tokenizeAndStringify(code, true)); - } - void simplifyKnownVariables61() { // #7805 tokenizeAndStringify("static const int XX = 0;\n" "enum E { XX };\n" @@ -4679,22 +4139,6 @@ private: ASSERT_EQUALS("static int x ; void f ( ) { x = 123 ; while ( ! x ) { dostuff ( ) ; } }", tokenizeAndStringify(code,true)); } - void simplifyKnownVariablesPointerAliasFunctionCall() { // #7440 - const char code[] = "int main() {\n" - " char* data = new char[100];\n" - " char** dataPtr = &data;\n" - " printf(\"test\");\n" - " delete [] *dataPtr;\n" - "}"; - const char exp[] = "int main ( ) {\n" - "char * data ; data = new char [ 100 ] ;\n" - "char * * dataPtr ; dataPtr = & data ;\n" - "printf ( \"test\" ) ;\n" - "delete [ ] data ;\n" - "}"; - ASSERT_EQUALS(exp, tokenizeAndStringify(code, /*simplify=*/ true)); - } - void simplifyKnownVariablesNamespace() { { // #10059 const char code[] = "namespace N {\n" @@ -4785,25 +4229,6 @@ private: } } - - void simplify_constants2() { - const char code[] = - "void f( Foo &foo, Foo *foo2 ) {\n" - "const int a = 45;\n" - "foo.a=a+a;\n" - "foo2->a=a;\n" - "}"; - ASSERT_EQUALS("void f ( Foo & foo , Foo * foo2 ) { foo . a = 90 ; foo2 . a = 45 ; }", tok(code)); - } - - void simplify_constants4() { - const char code[] = "static const int bSize = 4;\n" - "static const int aSize = 50;\n" - "x = bSize;\n" - "y = aSize;\n"; - ASSERT_EQUALS("x = 4 ; y = 50 ;", tok(code)); - } - void simplify_constants6() { // Ticket #5625 { const char code[] = "template < class T > struct foo ;\n"