From b70e1d5461dd00275e9b7ded52f7c29fc4354885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Thu, 2 Mar 2023 22:05:41 +0100 Subject: [PATCH] avoid some unchecked pointer dereferences (#4811) --- cli/cmdlineparser.cpp | 14 ++--- cli/cppcheckexecutor.cpp | 6 +-- cli/cppcheckexecutor.h | 2 +- gui/checkthread.cpp | 8 +-- lib/analyzerinfo.cpp | 6 +-- lib/analyzerinfo.h | 2 +- lib/astutils.cpp | 40 +++++++------- lib/astutils.h | 12 ++--- lib/checkbufferoverrun.cpp | 29 +++++------ lib/checkcondition.cpp | 44 ++++++++-------- lib/checkleakautovar.cpp | 86 +++++++++++++++--------------- lib/checkleakautovar.h | 8 +-- lib/checkmemoryleak.cpp | 4 ++ lib/checktype.cpp | 14 ++--- lib/checktype.h | 2 +- lib/cppcheck.cpp | 24 ++++----- lib/cppcheck.h | 4 +- lib/importproject.cpp | 20 +++---- lib/library.cpp | 10 ++-- lib/library.h | 6 +-- lib/preprocessor.cpp | 12 ++--- lib/programmemory.cpp | 50 +++++++++--------- lib/programmemory.h | 8 +-- lib/symboldatabase.cpp | 10 ++-- lib/symboldatabase.h | 2 +- lib/token.cpp | 4 +- lib/token.h | 4 +- lib/tokenize.cpp | 35 +++++++------ lib/tokenize.h | 6 +-- lib/valueflow.cpp | 104 ++++++++++++++++++------------------- lib/valueflow.h | 2 +- test/testlibrary.cpp | 4 +- 32 files changed, 292 insertions(+), 290 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 0cd599cb7..06c754d9a 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -81,7 +81,7 @@ static bool addFilesToList(const std::string& fileList, std::vector return true; } -static bool addIncludePathsToList(const std::string& fileList, std::list* pathNames) +static bool addIncludePathsToList(const std::string& fileList, std::list& pathNames) { std::ifstream files(fileList); if (files) { @@ -96,7 +96,7 @@ static bool addIncludePathsToList(const std::string& fileList, std::listemplace_back(std::move(pathName)); + pathNames.emplace_back(std::move(pathName)); } } return true; @@ -104,12 +104,12 @@ static bool addIncludePathsToList(const std::string& fileList, std::list* set) +static bool addPathsToSet(const std::string& fileName, std::set& set) { std::list templist; - if (!addIncludePathsToList(fileName, &templist)) + if (!addIncludePathsToList(fileName, templist)) return false; - set->insert(templist.cbegin(), templist.cend()); + set.insert(templist.cbegin(), templist.cend()); return true; } @@ -279,7 +279,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) else if (std::strncmp(argv[i], "--config-excludes-file=", 23) == 0) { // open this file and read every input file (1 file name per line) const std::string cfgExcludesFile(23 + argv[i]); - if (!addPathsToSet(cfgExcludesFile, &mSettings->configExcludePaths)) { + if (!addPathsToSet(cfgExcludesFile, mSettings->configExcludePaths)) { printError("unable to open config excludes file at '" + cfgExcludesFile + "'"); return false; } @@ -468,7 +468,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) else if (std::strncmp(argv[i], "--includes-file=", 16) == 0) { // open this file and read every input file (1 file name per line) const std::string includesFile(16 + argv[i]); - if (!addIncludePathsToList(includesFile, &mSettings->includePaths)) { + if (!addIncludePathsToList(includesFile, mSettings->includePaths)) { printError("unable to open includes file at '" + includesFile + "'"); return false; } diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index b9c28d36e..293e62fe8 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -568,9 +568,9 @@ bool CppCheckExecutor::tryLoadLibrary(Library& destination, const std::string& b */ // cppcheck-suppress passedByValue - used as callback so we need to preserve the signature // NOLINTNEXTLINE(performance-unnecessary-value-param) - used as callback so we need to preserve the signature -bool CppCheckExecutor::executeCommand(std::string exe, std::vector args, std::string redirect, std::string *output_) +bool CppCheckExecutor::executeCommand(std::string exe, std::vector args, std::string redirect, std::string &output_) { - output_->clear(); + output_.clear(); std::string joinedArgs; for (const std::string &arg : args) { @@ -596,7 +596,7 @@ bool CppCheckExecutor::executeCommand(std::string exe, std::vector return false; char buffer[1024]; while (fgets(buffer, sizeof(buffer), pipe.get()) != nullptr) - *output_ += buffer; + output_ += buffer; return true; } diff --git a/cli/cppcheckexecutor.h b/cli/cppcheckexecutor.h index e96acde34..3218b3d5d 100644 --- a/cli/cppcheckexecutor.h +++ b/cli/cppcheckexecutor.h @@ -114,7 +114,7 @@ public: /** * Execute a shell command and read the output from it. Returns true if command terminated successfully. */ - static bool executeCommand(std::string exe, std::vector args, std::string redirect, std::string *output_); + static bool executeCommand(std::string exe, std::vector args, std::string redirect, std::string &output_); static bool reportSuppressions(const Settings &settings, bool unusedFunctionCheckEnabled, const std::map &files, ErrorLogger& errorLogger); diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp index d5a2d4c08..ca95d8d62 100644 --- a/gui/checkthread.cpp +++ b/gui/checkthread.cpp @@ -45,9 +45,9 @@ #include // NOLINTNEXTLINE(performance-unnecessary-value-param) - used as callback so we need to preserve the signature -static bool executeCommand(std::string exe, std::vector args, std::string redirect, std::string *output) +static bool executeCommand(std::string exe, std::vector args, std::string redirect, std::string &output) { - output->clear(); + output.clear(); QStringList args2; for (const std::string &arg: args) @@ -60,9 +60,9 @@ static bool executeCommand(std::string exe, std::vector args, std:: if (redirect == "2>&1") { QString s1 = process.readAllStandardOutput(); QString s2 = process.readAllStandardError(); - *output = (s1 + "\n" + s2).toStdString(); + output = (s1 + "\n" + s2).toStdString(); } else - *output = process.readAllStandardOutput().toStdString(); + output = process.readAllStandardOutput().toStdString(); if (redirect.compare(0,3,"2> ") == 0) { std::ofstream fout(redirect.substr(3)); diff --git a/lib/analyzerinfo.cpp b/lib/analyzerinfo.cpp index 0f6ca6856..b3b6a3947 100644 --- a/lib/analyzerinfo.cpp +++ b/lib/analyzerinfo.cpp @@ -72,7 +72,7 @@ void AnalyzerInformation::close() } } -static bool skipAnalysis(const std::string &analyzerInfoFile, std::size_t hash, std::list *errors) +static bool skipAnalysis(const std::string &analyzerInfoFile, std::size_t hash, std::list &errors) { tinyxml2::XMLDocument doc; const tinyxml2::XMLError error = doc.LoadFile(analyzerInfoFile.c_str()); @@ -89,7 +89,7 @@ static bool skipAnalysis(const std::string &analyzerInfoFile, std::size_t hash, for (const tinyxml2::XMLElement *e = rootNode->FirstChildElement(); e; e = e->NextSiblingElement()) { if (std::strcmp(e->Name(), "error") == 0) - errors->emplace_back(e); + errors.emplace_back(e); } return true; @@ -127,7 +127,7 @@ std::string AnalyzerInformation::getAnalyzerInfoFile(const std::string &buildDir return Path::join(buildDir, filename) + ".analyzerinfo"; } -bool AnalyzerInformation::analyzeFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg, std::size_t hash, std::list *errors) +bool AnalyzerInformation::analyzeFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg, std::size_t hash, std::list &errors) { if (buildDir.empty() || sourcefile.empty()) return true; diff --git a/lib/analyzerinfo.h b/lib/analyzerinfo.h index b59e7b238..340d08f5e 100644 --- a/lib/analyzerinfo.h +++ b/lib/analyzerinfo.h @@ -55,7 +55,7 @@ public: /** Close current TU.analyzerinfo file */ void close(); - bool analyzeFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg, std::size_t hash, std::list *errors); + bool analyzeFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg, std::size_t hash, std::list &errors); void reportErr(const ErrorMessage &msg); void setFileInfo(const std::string &check, const std::string &fileInfo); static std::string getAnalyzerInfoFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg); diff --git a/lib/astutils.cpp b/lib/astutils.cpp index cc28af023..6132276e9 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -109,7 +109,7 @@ static int getArgumentPos(const Token* ftok, const Token* tokToFind){ } template )> -static void astFlattenRecursive(T* tok, std::vector* result, const char* op, nonneg int depth = 0) +static void astFlattenRecursive(T* tok, std::vector& result, const char* op, nonneg int depth = 0) { ++depth; if (!tok || depth >= 100) @@ -118,21 +118,21 @@ static void astFlattenRecursive(T* tok, std::vector* result, const char* op, astFlattenRecursive(tok->astOperand1(), result, op, depth); astFlattenRecursive(tok->astOperand2(), result, op, depth); } else { - result->push_back(tok); + result.push_back(tok); } } std::vector astFlatten(const Token* tok, const char* op) { std::vector result; - astFlattenRecursive(tok, &result, op); + astFlattenRecursive(tok, result, op); return result; } std::vector astFlatten(Token* tok, const char* op) { std::vector result; - astFlattenRecursive(tok, &result, op); + astFlattenRecursive(tok, result, op); return result; } @@ -865,12 +865,12 @@ const Token *findNextTokenFromBreak(const Token *breakToken) } bool extractForLoopValues(const Token *forToken, - nonneg int * const varid, - bool * const knownInitValue, - MathLib::bigint * const initValue, - bool * const partialCond, - MathLib::bigint * const stepValue, - MathLib::bigint * const lastValue) + nonneg int &varid, + bool &knownInitValue, + MathLib::bigint &initValue, + bool &partialCond, + MathLib::bigint &stepValue, + MathLib::bigint &lastValue) { if (!Token::simpleMatch(forToken, "for (") || !Token::simpleMatch(forToken->next()->astOperand2(), ";")) return false; @@ -880,28 +880,28 @@ bool extractForLoopValues(const Token *forToken, if (!initExpr || !initExpr->isBinaryOp() || initExpr->str() != "=" || !Token::Match(initExpr->astOperand1(), "%var%")) return false; std::vector minInitValue = getMinValue(ValueFlow::makeIntegralInferModel(), initExpr->astOperand2()->values()); - *varid = initExpr->astOperand1()->varId(); - *knownInitValue = initExpr->astOperand2()->hasKnownIntValue(); - *initValue = minInitValue.empty() ? 0 : minInitValue.front(); - *partialCond = Token::Match(condExpr, "%oror%|&&"); + varid = initExpr->astOperand1()->varId(); + knownInitValue = initExpr->astOperand2()->hasKnownIntValue(); + initValue = minInitValue.empty() ? 0 : minInitValue.front(); + partialCond = Token::Match(condExpr, "%oror%|&&"); visitAstNodes(condExpr, [varid, &condExpr](const Token *tok) { if (Token::Match(tok, "%oror%|&&")) return ChildrenToVisit::op1_and_op2; - if (Token::Match(tok, "<|<=") && tok->isBinaryOp() && tok->astOperand1()->varId() == *varid && tok->astOperand2()->hasKnownIntValue()) { + if (Token::Match(tok, "<|<=") && tok->isBinaryOp() && tok->astOperand1()->varId() == varid && tok->astOperand2()->hasKnownIntValue()) { if (Token::Match(condExpr, "%oror%|&&") || tok->astOperand2()->getKnownIntValue() < condExpr->astOperand2()->getKnownIntValue()) condExpr = tok; } return ChildrenToVisit::none; }); - if (!Token::Match(condExpr, "<|<=") || !condExpr->isBinaryOp() || condExpr->astOperand1()->varId() != *varid || !condExpr->astOperand2()->hasKnownIntValue()) + if (!Token::Match(condExpr, "<|<=") || !condExpr->isBinaryOp() || condExpr->astOperand1()->varId() != varid || !condExpr->astOperand2()->hasKnownIntValue()) return false; - if (!incExpr || !incExpr->isUnaryOp("++") || incExpr->astOperand1()->varId() != *varid) + if (!incExpr || !incExpr->isUnaryOp("++") || incExpr->astOperand1()->varId() != varid) return false; - *stepValue = 1; + stepValue = 1; if (condExpr->str() == "<") - *lastValue = condExpr->astOperand2()->getKnownIntValue() - 1; + lastValue = condExpr->astOperand2()->getKnownIntValue() - 1; else - *lastValue = condExpr->astOperand2()->getKnownIntValue(); + lastValue = condExpr->astOperand2()->getKnownIntValue(); return true; } diff --git a/lib/astutils.h b/lib/astutils.h index 7476e6281..e91599ec7 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -216,12 +216,12 @@ const Token *findNextTokenFromBreak(const Token *breakToken); * Extract for loop values: loopvar varid, init value, step value, last value (inclusive) */ bool extractForLoopValues(const Token *forToken, - nonneg int * const varid, - bool * const knownInitValue, - long long * const initValue, - bool * const partialCond, - long long * const stepValue, - long long * const lastValue); + nonneg int &varid, + bool &knownInitValue, + long long &initValue, + bool &partialCond, + long long &stepValue, + long long &lastValue); bool precedes(const Token * tok1, const Token * tok2); bool succeeds(const Token* tok1, const Token* tok2); diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 73e9dc2b5..8f91d4fa2 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -183,37 +183,36 @@ static int getMinFormatStringOutputLength(const std::vector ¶m //--------------------------------------------------------------------------- -static bool getDimensionsEtc(const Token * const arrayToken, const Settings *settings, std::vector * const dimensions, ErrorPath * const errorPath, bool * const mightBeLarger, MathLib::bigint* path) +static bool getDimensionsEtc(const Token * const arrayToken, const Settings *settings, std::vector &dimensions, ErrorPath &errorPath, bool &mightBeLarger, MathLib::bigint &path) { const Token *array = arrayToken; while (Token::Match(array, ".|::")) array = array->astOperand2(); if (array->variable() && array->variable()->isArray() && !array->variable()->dimensions().empty()) { - *dimensions = array->variable()->dimensions(); - if (dimensions->size() >= 1 && ((*dimensions)[0].num <= 1 || !(*dimensions)[0].tok)) { + dimensions = array->variable()->dimensions(); + if (dimensions[0].num <= 1 || !dimensions[0].tok) { visitAstNodes(arrayToken, [&](const Token *child) { if (child->originalName() == "->") { - *mightBeLarger = true; + mightBeLarger = true; return ChildrenToVisit::none; } return ChildrenToVisit::op1_and_op2; }); } - } else if (const Token *stringLiteral = array->getValueTokenMinStrSize(settings, path)) { + } else if (const Token *stringLiteral = array->getValueTokenMinStrSize(settings, &path)) { Dimension dim; dim.tok = nullptr; dim.num = Token::getStrArraySize(stringLiteral); dim.known = array->hasKnownValue(); - dimensions->emplace_back(dim); + dimensions.emplace_back(dim); } else if (array->valueType() && array->valueType()->pointer >= 1 && (array->valueType()->isIntegral() || array->valueType()->isFloat())) { const ValueFlow::Value *value = getBufferSizeValue(array); if (!value) return false; - if (path) - *path = value->path; - *errorPath = value->errorPath; + path = value->path; + errorPath = value->errorPath; Dimension dim; dim.known = value->isKnown(); dim.tok = nullptr; @@ -221,9 +220,9 @@ static bool getDimensionsEtc(const Token * const arrayToken, const Settings *set if (typeSize == 0) return false; dim.num = value->intvalue / typeSize; - dimensions->emplace_back(dim); + dimensions.emplace_back(dim); } - return !dimensions->empty(); + return !dimensions.empty(); } static ValueFlow::Value makeSizeValue(MathLib::bigint size, MathLib::bigint path) @@ -314,7 +313,7 @@ void CheckBufferOverrun::arrayIndex() ErrorPath errorPath; bool mightBeLarger = false; MathLib::bigint path = 0; - if (!getDimensionsEtc(tok->astOperand1(), mSettings, &dimensions, &errorPath, &mightBeLarger, &path)) + if (!getDimensionsEtc(tok->astOperand1(), mSettings, dimensions, errorPath, mightBeLarger, path)) continue; const Variable* const var = array->variable(); @@ -486,7 +485,7 @@ void CheckBufferOverrun::pointerArithmetic() ErrorPath errorPath; bool mightBeLarger = false; MathLib::bigint path = 0; - if (!getDimensionsEtc(arrayToken, mSettings, &dimensions, &errorPath, &mightBeLarger, &path)) + if (!getDimensionsEtc(arrayToken, mSettings, dimensions, errorPath, mightBeLarger, path)) continue; if (tok->str() == "+") { @@ -881,6 +880,8 @@ std::string CheckBufferOverrun::MyFileInfo::toString() const bool CheckBufferOverrun::isCtuUnsafeBufferUsage(const Check *check, const Token *argtok, MathLib::bigint *offset, int type) { + if (!offset) + return false; const CheckBufferOverrun *c = dynamic_cast(check); if (!c) return false; @@ -897,8 +898,6 @@ bool CheckBufferOverrun::isCtuUnsafeBufferUsage(const Check *check, const Token return false; if (!indexTok->hasKnownIntValue()) return false; - if (!offset) - return false; *offset = indexTok->getKnownIntValue() * argtok->valueType()->typeSize(*c->mSettings); return true; } diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index eaab9babf..ee57d9e5d 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -1004,11 +1004,11 @@ static inline T getvalue(const int test, const T value1, const T value2) return 0; } -static bool parseComparison(const Token *comp, bool *not1, std::string *op, std::string *value, const Token **expr, bool* inconclusive) +static bool parseComparison(const Token *comp, bool ¬1, std::string &op, std::string &value, const Token *&expr, bool &inconclusive) { - *not1 = false; + not1 = false; while (comp && comp->str() == "!") { - *not1 = !(*not1); + not1 = !(not1); comp = comp->astOperand1(); } @@ -1018,37 +1018,37 @@ static bool parseComparison(const Token *comp, bool *not1, std::string *op, std: const Token* op1 = comp->astOperand1(); const Token* op2 = comp->astOperand2(); if (!comp->isComparisonOp() || !op1 || !op2) { - *op = "!="; - *value = "0"; - *expr = comp; + op = "!="; + value = "0"; + expr = comp; } else if (op1->isLiteral()) { if (op1->isExpandedMacro()) return false; - *op = invertOperatorForOperandSwap(comp->str()); + op = invertOperatorForOperandSwap(comp->str()); if (op1->enumerator() && op1->enumerator()->value_known) - *value = MathLib::toString(op1->enumerator()->value); + value = MathLib::toString(op1->enumerator()->value); else - *value = op1->str(); - *expr = op2; + value = op1->str(); + expr = op2; } else if (comp->astOperand2()->isLiteral()) { if (op2->isExpandedMacro()) return false; - *op = comp->str(); + op = comp->str(); if (op2->enumerator() && op2->enumerator()->value_known) - *value = MathLib::toString(op2->enumerator()->value); + value = MathLib::toString(op2->enumerator()->value); else - *value = op2->str(); - *expr = op1; + value = op2->str(); + expr = op1; } else { - *op = "!="; - *value = "0"; - *expr = comp; + op = "!="; + value = "0"; + expr = comp; } - *inconclusive = *inconclusive || ((*value)[0] == '\'' && !(*op == "!=" || *op == "==")); + inconclusive = inconclusive || ((value)[0] == '\'' && !(op == "!=" || op == "==")); // Only float and int values are currently handled - if (!MathLib::isInt(*value) && !MathLib::isFloat(*value) && (*value)[0] != '\'') + if (!MathLib::isInt(value) && !MathLib::isFloat(value) && (value)[0] != '\'') return false; return true; @@ -1076,7 +1076,7 @@ static std::string conditionString(const Token * tok) bool not_; std::string op, value; const Token *expr; - if (parseComparison(tok, ¬_, &op, &value, &expr, &inconclusive) && expr->isName()) { + if (parseComparison(tok, not_, op, value, expr, inconclusive) && expr->isName()) { return conditionString(not_, expr, op, value); } } @@ -1192,13 +1192,13 @@ void CheckCondition::checkIncorrectLogicOperator() bool not1; std::string op1, value1; const Token *expr1 = nullptr; - parseable &= (parseComparison(comp1, ¬1, &op1, &value1, &expr1, &inconclusive)); + parseable &= (parseComparison(comp1, not1, op1, value1, expr1, inconclusive)); // Parse RHS bool not2; std::string op2, value2; const Token *expr2 = nullptr; - parseable &= (parseComparison(comp2, ¬2, &op2, &value2, &expr2, &inconclusive)); + parseable &= (parseComparison(comp2, not2, op2, value2, expr2, inconclusive)); if (inconclusive && !printInconclusive) continue; diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 8fe67d81a..633868b17 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -208,7 +208,7 @@ void CheckLeakAutoVar::check() // Empty variable info VarInfo varInfo; - checkScope(scope->bodyStart, &varInfo, notzero, 0); + checkScope(scope->bodyStart, varInfo, notzero, 0); } } @@ -287,7 +287,7 @@ static const Token * isFunctionCall(const Token * nameToken) } bool CheckLeakAutoVar::checkScope(const Token * const startToken, - VarInfo *varInfo, + VarInfo &varInfo, std::set notzero, nonneg int recursiveCount) { @@ -299,9 +299,9 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, if (++recursiveCount > recursiveLimit) // maximum number of "else if ()" throw InternalError(startToken, "Internal limit: CheckLeakAutoVar::checkScope() Maximum recursive count of 1000 reached.", InternalError::LIMIT); - std::map &alloctype = varInfo->alloctype; - std::map &possibleUsage = varInfo->possibleUsage; - const std::set conditionalAlloc(varInfo->conditionalAlloc); + std::map &alloctype = varInfo.alloctype; + std::map &possibleUsage = varInfo.possibleUsage; + const std::set conditionalAlloc(varInfo.conditionalAlloc); // Parse all tokens const Token * const endToken = startToken->link(); @@ -372,7 +372,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, if (Token::Match(tokAssignOp, "= %var% [+;]")) { if (varTok->tokAt(2)->varId() != varTok->varId()) { // If variable points at allocated memory => error - leakIfAllocated(varTok, *varInfo); + leakIfAllocated(varTok, varInfo); // no multivariable checking currently => bail out for rhs variables for (const Token *tok2 = varTok; tok2; tok2 = tok2->next()) { @@ -380,7 +380,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, break; } if (tok2->varId()) { - varInfo->erase(tok2->varId()); + varInfo.erase(tok2->varId()); } } } @@ -397,8 +397,8 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, // Variable has already been allocated => error if (conditionalAlloc.find(varTok->varId()) == conditionalAlloc.end()) - leakIfAllocated(varTok, *varInfo); - varInfo->erase(varTok->varId()); + leakIfAllocated(varTok, varInfo); + varInfo.erase(varTok->varId()); if (!isLocalVarNoAutoDealloc(varTok, mTokenizer->isCPP())) continue; @@ -488,8 +488,8 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, } if (Token::simpleMatch(closingParenthesis, ") {")) { - VarInfo varInfo1(*varInfo); // VarInfo for if code - VarInfo varInfo2(*varInfo); // VarInfo for else code + VarInfo varInfo1(varInfo); // VarInfo for if code + VarInfo varInfo2(varInfo); // VarInfo for else code // Skip expressions before commas const Token * astOperand2AfterCommas = tok->next()->astOperand2(); @@ -535,13 +535,13 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, return ChildrenToVisit::none; }); - if (!checkScope(closingParenthesis->next(), &varInfo1, notzero, recursiveCount)) { - varInfo->clear(); + if (!checkScope(closingParenthesis->next(), varInfo1, notzero, recursiveCount)) { + varInfo.clear(); continue; } closingParenthesis = closingParenthesis->linkAt(1); if (Token::simpleMatch(closingParenthesis, "} else {")) { - if (!checkScope(closingParenthesis->tokAt(2), &varInfo2, notzero, recursiveCount)) + if (!checkScope(closingParenthesis->tokAt(2), varInfo2, notzero, recursiveCount)) continue; tok = closingParenthesis->linkAt(2)->previous(); } else { @@ -549,7 +549,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, } VarInfo old; - old.swap(*varInfo); + old.swap(varInfo); std::map::const_iterator it; @@ -568,7 +568,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, for (it = varInfo1.alloctype.cbegin(); it != varInfo1.alloctype.cend(); ++it) { if (varInfo2.alloctype.find(it->first) == varInfo2.alloctype.end() && old.alloctype.find(it->first) == old.alloctype.end()) { - varInfo->conditionalAlloc.insert(it->first); + varInfo.conditionalAlloc.insert(it->first); } } @@ -576,20 +576,20 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, for (it = varInfo2.alloctype.cbegin(); it != varInfo2.alloctype.cend(); ++it) { if (varInfo1.alloctype.find(it->first) == varInfo1.alloctype.end() && old.alloctype.find(it->first) == old.alloctype.end()) { - varInfo->conditionalAlloc.insert(it->first); + varInfo.conditionalAlloc.insert(it->first); } } // Conditional allocation/deallocation for (it = varInfo1.alloctype.cbegin(); it != varInfo1.alloctype.cend(); ++it) { if (it->second.managed() && conditionalAlloc.find(it->first) != conditionalAlloc.end()) { - varInfo->conditionalAlloc.erase(it->first); + varInfo.conditionalAlloc.erase(it->first); varInfo2.erase(it->first); } } for (it = varInfo2.alloctype.cbegin(); it != varInfo2.alloctype.cend(); ++it) { if (it->second.managed() && conditionalAlloc.find(it->first) != conditionalAlloc.end()) { - varInfo->conditionalAlloc.erase(it->first); + varInfo.conditionalAlloc.erase(it->first); varInfo1.erase(it->first); } } @@ -604,14 +604,14 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, // unknown control.. (TODO: handle loops) else if ((Token::Match(tok, "%type% (") && Token::simpleMatch(tok->linkAt(1), ") {")) || Token::simpleMatch(tok, "do {")) { - varInfo->clear(); + varInfo.clear(); break; } // return else if (tok->str() == "return") { - ret(tok, *varInfo); - varInfo->clear(); + ret(tok, varInfo); + varInfo.clear(); } // throw @@ -625,8 +625,8 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, } // If the execution leaves the function then treat it as return if (!tryFound) - ret(tok, *varInfo); - varInfo->clear(); + ret(tok, varInfo); + varInfo.clear(); } // delete @@ -670,9 +670,9 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, bool unknown = false; if (mTokenizer->isScopeNoReturn(tok->tokAt(2), &unknown)) { if (!unknown) - varInfo->clear(); + varInfo.clear(); else if (!mSettings->library.isLeakIgnore(functionName) && !mSettings->library.isUse(functionName)) - varInfo->possibleUsageAll(functionName); + varInfo.possibleUsageAll(functionName); } } @@ -681,13 +681,13 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, // goto => weird execution path else if (tok->str() == "goto") { - varInfo->clear(); + varInfo.clear(); return false; } // continue/break else if (Token::Match(tok, "continue|break ;")) { - varInfo->clear(); + varInfo.clear(); } // Check smart pointer @@ -761,7 +761,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, break; } } else { // there is a deleter, but we can't check it -> assume that it deallocates correctly - varInfo->clear(); + varInfo.clear(); continue; } } @@ -772,23 +772,23 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, changeAllocStatus(varInfo, allocation, vtok, vtok); } } - ret(endToken, *varInfo, true); + ret(endToken, varInfo, true); return true; } -const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const tok, VarInfo *varInfo) +const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const tok, VarInfo &varInfo) { // Deallocation and then dereferencing pointer.. if (tok->varId() > 0) { // TODO : Write a separate checker for this that uses valueFlowForward. - const std::map::const_iterator var = varInfo->alloctype.find(tok->varId()); - if (var != varInfo->alloctype.end()) { + const std::map::const_iterator var = varInfo.alloctype.find(tok->varId()); + if (var != varInfo.alloctype.end()) { bool unknown = false; if (var->second.status == VarInfo::DEALLOC && CheckNullPointer::isPointerDeRef(tok, unknown, mSettings) && !unknown) { deallocUseError(tok, tok->str()); } else if (Token::simpleMatch(tok->tokAt(-2), "= &")) { - varInfo->erase(tok->varId()); + varInfo.erase(tok->varId()); } else { // check if tok is assigned into another variable const Token *rhs = tok; @@ -802,7 +802,7 @@ const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t } if (rhs->varId() == tok->varId()) { // simple assignment - varInfo->erase(tok->varId()); + varInfo.erase(tok->varId()); } else if (rhs->str() == "(" && !mSettings->library.returnValue(rhs->astOperand1()).empty()) { // #9298, assignment through return value of a function const std::string &returnValue = mSettings->library.returnValue(rhs->astOperand1()); @@ -812,14 +812,14 @@ const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t if (func) { const std::string arg = "arg" + std::to_string(argn + 1); if (returnValue == arg) { - varInfo->erase(tok->varId()); + varInfo.erase(tok->varId()); } } } } } } else if (Token::Match(tok->previous(), "& %name% = %var% ;")) { - varInfo->referenced.insert(tok->tokAt(2)->varId()); + varInfo.referenced.insert(tok->tokAt(2)->varId()); } } @@ -863,23 +863,23 @@ void CheckLeakAutoVar::changeAllocStatusIfRealloc(std::map &alloctype = varInfo->alloctype; + std::map &alloctype = varInfo.alloctype; const std::map::iterator var = alloctype.find(arg->varId()); if (var != alloctype.end()) { if (allocation.status == VarInfo::NOALLOC) { // possible usage - varInfo->possibleUsage[arg->varId()] = tok->str(); + varInfo.possibleUsage[arg->varId()] = tok->str(); if (var->second.status == VarInfo::DEALLOC && arg->previous()->str() == "&") - varInfo->erase(arg->varId()); + varInfo.erase(arg->varId()); } else if (var->second.managed()) { doubleFreeError(tok, var->second.allocTok, arg->str(), allocation.type); var->second.status = allocation.status; } else if (var->second.type != allocation.type && var->second.type != 0) { // mismatching allocation and deallocation mismatchError(tok, var->second.allocTok, arg->str()); - varInfo->erase(arg->varId()); + varInfo.erase(arg->varId()); } else { // deallocation var->second.status = allocation.status; @@ -892,7 +892,7 @@ void CheckLeakAutoVar::changeAllocStatus(VarInfo *varInfo, const VarInfo::AllocI } } -void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpeningPar, VarInfo *varInfo, const VarInfo::AllocInfo& allocation, const Library::AllocFunc* af) +void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpeningPar, VarInfo &varInfo, const VarInfo::AllocInfo& allocation, const Library::AllocFunc* af) { // Ignore function call? if (mSettings->library.isLeakIgnore(mSettings->library.getFunctionName(tokName))) diff --git a/lib/checkleakautovar.h b/lib/checkleakautovar.h index dd24e0ad0..882cd8594 100644 --- a/lib/checkleakautovar.h +++ b/lib/checkleakautovar.h @@ -126,7 +126,7 @@ private: /** check for leaks in a function scope */ bool checkScope(const Token * const startToken, - VarInfo *varInfo, + VarInfo &varInfo, std::set notzero, nonneg int recursiveCount); @@ -135,13 +135,13 @@ private: * @param varInfo Variable info * @return next token to process (if no other checks needed for this token). NULL if other checks could be performed. */ - const Token * checkTokenInsideExpression(const Token * const tok, VarInfo *varInfo); + const Token * checkTokenInsideExpression(const Token * const tok, VarInfo &varInfo); /** parse function call */ - void functionCall(const Token *tokName, const Token *tokOpeningPar, VarInfo *varInfo, const VarInfo::AllocInfo& allocation, const Library::AllocFunc* af); + void functionCall(const Token *tokName, const Token *tokOpeningPar, VarInfo &varInfo, const VarInfo::AllocInfo& allocation, const Library::AllocFunc* af); /** parse changes in allocation status */ - void changeAllocStatus(VarInfo *varInfo, const VarInfo::AllocInfo& allocation, const Token* tok, const Token* arg); + void changeAllocStatus(VarInfo &varInfo, const VarInfo::AllocInfo& allocation, const Token* tok, const Token* arg); /** update allocation status if reallocation function */ void changeAllocStatusIfRealloc(std::map &alloctype, const Token *fTok, const Token *retTok); diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index f7cbece50..2f006fca7 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -728,6 +728,8 @@ void CheckMemoryLeakStructMember::check() bool CheckMemoryLeakStructMember::isMalloc(const Variable *variable) { + if (!variable) + return false; const int declarationId(variable->declarationId()); bool alloc = false; for (const Token *tok2 = variable->nameToken(); tok2 && tok2 != variable->scope()->bodyEnd; tok2 = tok2->next()) { @@ -742,6 +744,8 @@ bool CheckMemoryLeakStructMember::isMalloc(const Variable *variable) void CheckMemoryLeakStructMember::checkStructVariable(const Variable * const variable) { + if (!variable) + return; // Is struct variable a pointer? if (variable->isArrayOrPointer()) { // Check that variable is allocated with malloc diff --git a/lib/checktype.cpp b/lib/checktype.cpp index 0b6ba6c3c..15b4eb54f 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -387,22 +387,19 @@ void CheckType::checkFloatToIntegerOverflow() { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { const ValueType *vtint, *vtfloat; - const std::list *floatValues; // Explicit cast if (Token::Match(tok, "( %name%") && tok->astOperand1() && !tok->astOperand2()) { vtint = tok->valueType(); vtfloat = tok->astOperand1()->valueType(); - floatValues = &tok->astOperand1()->values(); - checkFloatToIntegerOverflow(tok, vtint, vtfloat, floatValues); + checkFloatToIntegerOverflow(tok, vtint, vtfloat, tok->astOperand1()->values()); } // Assignment else if (tok->str() == "=" && tok->astOperand1() && tok->astOperand2()) { vtint = tok->astOperand1()->valueType(); vtfloat = tok->astOperand2()->valueType(); - floatValues = &tok->astOperand2()->values(); - checkFloatToIntegerOverflow(tok, vtint, vtfloat, floatValues); + checkFloatToIntegerOverflow(tok, vtint, vtfloat, tok->astOperand2()->values()); } else if (tok->str() == "return" && tok->astOperand1() && tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->isFloat()) { @@ -412,14 +409,13 @@ void CheckType::checkFloatToIntegerOverflow() if (scope && scope->type == Scope::ScopeType::eFunction && scope->function && scope->function->retDef) { const ValueType &valueType = ValueType::parseDecl(scope->function->retDef, mSettings, mTokenizer->isCPP()); vtfloat = tok->astOperand1()->valueType(); - floatValues = &tok->astOperand1()->values(); - checkFloatToIntegerOverflow(tok, &valueType, vtfloat, floatValues); + checkFloatToIntegerOverflow(tok, &valueType, vtfloat, tok->astOperand1()->values()); } } } } -void CheckType::checkFloatToIntegerOverflow(const Token *tok, const ValueType *vtint, const ValueType *vtfloat, const std::list *floatValues) +void CheckType::checkFloatToIntegerOverflow(const Token *tok, const ValueType *vtint, const ValueType *vtfloat, const std::list &floatValues) { // Conversion of float to integer? if (!vtint || !vtint->isIntegral()) @@ -427,7 +423,7 @@ void CheckType::checkFloatToIntegerOverflow(const Token *tok, const ValueType *v if (!vtfloat || !vtfloat->isFloat()) return; - for (const ValueFlow::Value &f : *floatValues) { + for (const ValueFlow::Value &f : floatValues) { if (f.valueType != ValueFlow::Value::ValueType::FLOAT) continue; if (!mSettings->isEnabled(&f, false)) diff --git a/lib/checktype.h b/lib/checktype.h index be8559995..34417b371 100644 --- a/lib/checktype.h +++ b/lib/checktype.h @@ -75,7 +75,7 @@ public: /** @brief %Check for float to integer overflow */ void checkFloatToIntegerOverflow(); - void checkFloatToIntegerOverflow(const Token *tok, const ValueType *vtint, const ValueType *vtfloat, const std::list *floatValues); + void checkFloatToIntegerOverflow(const Token *tok, const ValueType *vtint, const ValueType *vtfloat, const std::list &floatValues); private: diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 330161f72..cdb14f1d1 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -317,7 +317,7 @@ static std::string executeAddon(const AddonInfo &addonInfo, const std::string &defaultPythonExe, const std::string &file, const std::string &premiumArgs, - const std::function,std::string,std::string*)> &executeCommand) + const std::function,std::string,std::string&)> &executeCommand) { const std::string redirect = "2>&1"; @@ -337,7 +337,7 @@ static std::string executeAddon(const AddonInfo &addonInfo, #endif for (const char* py_exe : py_exes) { std::string out; - if (executeCommand(py_exe, split("--version"), redirect, &out) && out.compare(0, 7, "Python ") == 0 && std::isdigit(out[7])) { + if (executeCommand(py_exe, split("--version"), redirect, out) && out.compare(0, 7, "Python ") == 0 && std::isdigit(out[7])) { pythonExe = py_exe; break; } @@ -357,7 +357,7 @@ static std::string executeAddon(const AddonInfo &addonInfo, args += fileArg; std::string result; - if (!executeCommand(pythonExe, split(args), redirect, &result)) { + if (!executeCommand(pythonExe, split(args), redirect, result)) { std::string message("Failed to execute addon (command: '" + pythonExe + " " + args + "'). Exitcode is nonzero."); if (result.size() > 2) { message = message + "\n" + message + "\nOutput:\n" + result; @@ -390,7 +390,7 @@ static std::string getDefinesFlags(const std::string &semicolonSeparatedString) CppCheck::CppCheck(ErrorLogger &errorLogger, bool useGlobalSuppressions, - std::function,std::string,std::string*)> executeCommand) + std::function,std::string,std::string&)> executeCommand) : mErrorLogger(errorLogger) , mExitCode(0) , mUseGlobalSuppressions(useGlobalSuppressions) @@ -423,7 +423,7 @@ const char * CppCheck::extraVersion() return ExtraVersion; } -static bool reportClangErrors(std::istream &is, const std::function& reportErr, std::vector *warnings) +static bool reportClangErrors(std::istream &is, const std::function& reportErr, std::vector &warnings) { std::string line; while (std::getline(is, line)) { @@ -433,7 +433,7 @@ static bool reportClangErrors(std::istream &is, const std::functionpush_back(std::move(errmsg)); + warnings.push_back(std::move(errmsg)); continue; } @@ -512,7 +512,7 @@ unsigned int CppCheck::check(const std::string &path) } std::string output2; - if (!mExecuteCommand(exe,split(args2),redirect2,&output2) || output2.find("TranslationUnitDecl") == std::string::npos) { + if (!mExecuteCommand(exe,split(args2),redirect2,output2) || output2.find("TranslationUnitDecl") == std::string::npos) { std::cerr << "Failed to execute '" << exe << " " << args2 << " " << redirect2 << "'" << std::endl; return 0; } @@ -524,14 +524,14 @@ unsigned int CppCheck::check(const std::string &path) auto reportError = [this](const ErrorMessage& errorMessage) { reportErr(errorMessage); }; - if (reportClangErrors(fin, reportError, &compilerWarnings)) + if (reportClangErrors(fin, reportError, compilerWarnings)) return 0; } else { std::istringstream istr(output2); auto reportError = [this](const ErrorMessage& errorMessage) { reportErr(errorMessage); }; - if (reportClangErrors(istr, reportError, &compilerWarnings)) + if (reportClangErrors(istr, reportError, compilerWarnings)) return 0; } @@ -762,7 +762,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string // Calculate hash so it can be compared with old hash / future hashes const std::size_t hash = preprocessor.calculateHash(tokens1, toolinfo.str()); std::list errors; - if (!mAnalyzerInformation.analyzeFile(mSettings.buildDir, filename, cfgname, hash, &errors)) { + if (!mAnalyzerInformation.analyzeFile(mSettings.buildDir, filename, cfgname, hash, errors)) { while (!errors.empty()) { reportErr(errors.front()); errors.pop_front(); @@ -1699,7 +1699,7 @@ void CppCheck::analyseClangTidy(const ImportProject::FileSettings &fileSettings) const std::string args = "-quiet -checks=*,-clang-analyzer-*,-llvm* \"" + fileSettings.filename + "\" -- " + allIncludes + allDefines; std::string output; - if (!mExecuteCommand(exe, split(args), emptyString, &output)) { + if (!mExecuteCommand(exe, split(args), emptyString, output)) { std::cerr << "Failed to execute '" << exe << "'" << std::endl; return; } diff --git a/lib/cppcheck.h b/lib/cppcheck.h index d4ffab71e..1d7411a47 100644 --- a/lib/cppcheck.h +++ b/lib/cppcheck.h @@ -55,7 +55,7 @@ public: */ CppCheck(ErrorLogger &errorLogger, bool useGlobalSuppressions, - std::function,std::string,std::string*)> executeCommand); + std::function,std::string,std::string&)> executeCommand); /** * @brief Destructor. @@ -240,7 +240,7 @@ private: AnalyzerInformation mAnalyzerInformation; /** Callback for executing a shell command (exe, args, output) */ - std::function,std::string,std::string*)> mExecuteCommand; + std::function,std::string,std::string&)> mExecuteCommand; std::ofstream mPlistFile; }; diff --git a/lib/importproject.cpp b/lib/importproject.cpp index cbe5a59e5..9e5b90710 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -626,7 +626,7 @@ static std::list toStringList(const std::string &s) return ret; } -static void importPropertyGroup(const tinyxml2::XMLElement *node, std::map *variables, std::string *includePath, bool *useOfMfc) +static void importPropertyGroup(const tinyxml2::XMLElement *node, std::map &variables, std::string &includePath, bool *useOfMfc) { if (useOfMfc) { for (const tinyxml2::XMLElement *e = node->FirstChildElement(); e; e = e->NextSiblingElement()) { @@ -642,7 +642,7 @@ static void importPropertyGroup(const tinyxml2::XMLElement *node, std::mapFirstChildElement(); propertyGroup; propertyGroup = propertyGroup->NextSiblingElement()) { const std::string name(propertyGroup->Name()); const char *text = propertyGroup->GetText(); - (*variables)[name] = std::string(text ? text : ""); + variables[name] = std::string(text ? text : ""); } } else if (!labelAttribute) { @@ -655,22 +655,22 @@ static void importPropertyGroup(const tinyxml2::XMLElement *node, std::map *variables, std::string *includePath, const std::string &additionalIncludeDirectories, std::list &itemDefinitionGroupList) +static void loadVisualStudioProperties(const std::string &props, std::map &variables, std::string &includePath, const std::string &additionalIncludeDirectories, std::list &itemDefinitionGroupList) { std::string filename(props); // variables can't be resolved - if (!simplifyPathWithVariables(filename, *variables)) + if (!simplifyPathWithVariables(filename, variables)) return; // prepend project dir (if it exists) to transform relative paths into absolute ones - if (!Path::isAbsolute(filename) && variables->count("ProjectDir") > 0) - filename = Path::getAbsoluteFilePath(variables->at("ProjectDir") + filename); + if (!Path::isAbsolute(filename) && variables.count("ProjectDir") > 0) + filename = Path::getAbsoluteFilePath(variables.at("ProjectDir") + filename); tinyxml2::XMLDocument doc; if (doc.LoadFile(filename.c_str()) != tinyxml2::XML_SUCCESS) @@ -750,7 +750,7 @@ bool ImportProject::importVcxproj(const std::string &filename, std::mapName(), "ItemDefinitionGroup") == 0) { itemDefinitionGroupList.emplace_back(node, additionalIncludeDirectories); } else if (std::strcmp(node->Name(), "PropertyGroup") == 0) { - importPropertyGroup(node, &variables, &includePath, &useOfMfc); + importPropertyGroup(node, variables, includePath, &useOfMfc); } else if (std::strcmp(node->Name(), "ImportGroup") == 0) { const char *labelAttribute = node->Attribute("Label"); if (labelAttribute && std::strcmp(labelAttribute, "PropertySheets") == 0) { @@ -758,7 +758,7 @@ bool ImportProject::importVcxproj(const std::string &filename, std::mapName(), "Import") == 0) { const char *projectAttribute = e->Attribute("Project"); if (projectAttribute) - loadVisualStudioProperties(projectAttribute, &variables, &includePath, additionalIncludeDirectories, itemDefinitionGroupList); + loadVisualStudioProperties(projectAttribute, variables, includePath, additionalIncludeDirectories, itemDefinitionGroupList); } } } diff --git a/lib/library.cpp b/lib/library.cpp index b6dbff7fa..01c4129b7 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -953,10 +953,10 @@ bool Library::isFloatArgValid(const Token *ftok, int argnr, double argvalue) con return false; } -std::string Library::getFunctionName(const Token *ftok, bool *error) const +std::string Library::getFunctionName(const Token *ftok, bool &error) const { if (!ftok) { - *error = true; + error = true; return ""; } if (ftok->isName()) { @@ -980,13 +980,13 @@ std::string Library::getFunctionName(const Token *ftok, bool *error) const if (ftok->str() == "." && ftok->astOperand1()) { const std::string type = astCanonicalType(ftok->astOperand1()); if (type.empty()) { - *error = true; + error = true; return ""; } return type + "::" + getFunctionName(ftok->astOperand2(),error); } - *error = true; + error = true; return ""; } @@ -999,7 +999,7 @@ std::string Library::getFunctionName(const Token *ftok) const if (ftok->astParent()) { bool error = false; const Token * tok = ftok->astParent()->isUnaryOp("&") ? ftok->astParent()->astOperand1() : ftok->next()->astOperand1(); - const std::string ret = getFunctionName(tok, &error); + const std::string ret = getFunctionName(tok, error); return error ? std::string() : ret; } diff --git a/lib/library.h b/lib/library.h index 0537f58c6..501fe1aad 100644 --- a/lib/library.h +++ b/lib/library.h @@ -154,7 +154,7 @@ public: return ((id > 0) && ((id & 1) == 0)); } static bool ismemory(const AllocFunc* const func) { - return ((func->groupId > 0) && ((func->groupId & 1) == 0)); + return func && (func->groupId > 0) && ((func->groupId & 1) == 0); } /** is allocation type resource? */ @@ -162,7 +162,7 @@ public: return ((id > 0) && ((id & 1) == 1)); } static bool isresource(const AllocFunc* const func) { - return ((func->groupId > 0) && ((func->groupId & 1) == 1)); + return func && (func->groupId > 0) && ((func->groupId & 1) == 1); } bool formatstr_function(const Token* ftok) const; @@ -652,7 +652,7 @@ private: const ArgumentChecks * getarg(const Token *ftok, int argnr) const; - std::string getFunctionName(const Token *ftok, bool *error) const; + std::string getFunctionName(const Token *ftok, bool &error) const; static const AllocFunc* getAllocDealloc(const std::map &data, const std::string &name) { const std::map::const_iterator it = data.find(name); diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 3fa5663b0..18de15fd2 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -84,7 +84,7 @@ namespace { }; } -static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std::list &inlineSuppressions, std::list *bad) +static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std::list &inlineSuppressions, std::list &bad) { const std::string cppchecksuppress("cppcheck-suppress"); @@ -110,7 +110,7 @@ static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std: std::vector suppressions = Suppressions::parseMultiSuppressComment(comment, &errmsg); if (!errmsg.empty()) - bad->emplace_back(tok->location, std::move(errmsg)); + bad.emplace_back(tok->location, std::move(errmsg)); std::copy_if(suppressions.cbegin(), suppressions.cend(), std::back_inserter(inlineSuppressions), [](const Suppressions::Suppression& s) { return !s.errorId.empty(); @@ -126,13 +126,13 @@ static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std: inlineSuppressions.push_back(std::move(s)); if (!errmsg.empty()) - bad->emplace_back(tok->location, std::move(errmsg)); + bad.emplace_back(tok->location, std::move(errmsg)); } return true; } -static void addinlineSuppressions(const simplecpp::TokenList &tokens, Settings &mSettings, std::list *bad) +static void addinlineSuppressions(const simplecpp::TokenList &tokens, Settings &mSettings, std::list &bad) { for (const simplecpp::Token *tok = tokens.cfront(); tok; tok = tok->next) { if (!tok->comment) @@ -192,10 +192,10 @@ void Preprocessor::inlineSuppressions(const simplecpp::TokenList &tokens) if (!mSettings.inlineSuppressions) return; std::list err; - ::addinlineSuppressions(tokens, mSettings, &err); + ::addinlineSuppressions(tokens, mSettings, err); for (std::map::const_iterator it = mTokenLists.cbegin(); it != mTokenLists.cend(); ++it) { if (it->second) - ::addinlineSuppressions(*it->second, mSettings, &err); + ::addinlineSuppressions(*it->second, mSettings, err); } for (const BadInlineSuppression &bad : err) { error(bad.location.file(), bad.location.line, bad.errmsg); diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index a65805834..94eae0efd 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -58,7 +58,7 @@ void ProgramMemory::setValue(const Token* expr, const ValueFlow::Value& value) { if (tok->hasKnownIntValue()) return {tok->values().front().intvalue}; MathLib::bigint result = 0; - if (getIntValue(tok->exprId(), &result)) + if (getIntValue(tok->exprId(), result)) return {result}; return {}; }, @@ -77,11 +77,11 @@ const ValueFlow::Value* ProgramMemory::getValue(nonneg int exprid, bool impossib } // cppcheck-suppress unusedFunction -bool ProgramMemory::getIntValue(nonneg int exprid, MathLib::bigint* result) const +bool ProgramMemory::getIntValue(nonneg int exprid, MathLib::bigint& result) const { const ValueFlow::Value* value = getValue(exprid); if (value && value->isIntValue()) { - *result = value->intvalue; + result = value->intvalue; return true; } return false; @@ -106,25 +106,25 @@ bool ProgramMemory::getTokValue(nonneg int exprid, const Token** result) const } // cppcheck-suppress unusedFunction -bool ProgramMemory::getContainerSizeValue(nonneg int exprid, MathLib::bigint* result) const +bool ProgramMemory::getContainerSizeValue(nonneg int exprid, MathLib::bigint& result) const { const ValueFlow::Value* value = getValue(exprid); if (value && value->isContainerSizeValue()) { - *result = value->intvalue; + result = value->intvalue; return true; } return false; } -bool ProgramMemory::getContainerEmptyValue(nonneg int exprid, MathLib::bigint* result) const +bool ProgramMemory::getContainerEmptyValue(nonneg int exprid, MathLib::bigint& result) const { const ValueFlow::Value* value = getValue(exprid, true); if (value && value->isContainerSizeValue()) { if (value->isImpossible() && value->intvalue == 0) { - *result = false; + result = false; return true; } if (!value->isImpossible()) { - *result = (value->intvalue == 0); + result = (value->intvalue == 0); return true; } } @@ -210,7 +210,7 @@ static bool evaluateCondition(const std::string& op, } MathLib::bigint result = 0; bool error = false; - execute(condition, &pm, &result, &error, settings); + execute(condition, pm, &result, &error, settings); return !error && result == r; } @@ -259,7 +259,7 @@ void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Toke return {t->values().front().intvalue}; MathLib::bigint result = 0; bool error = false; - execute(t, &pm, &result, &error); + execute(t, pm, &result, &error); if (!error) return {result}; return std::vector{}; @@ -323,7 +323,7 @@ static void fillProgramMemoryFromConditions(ProgramMemory& pm, const Scope* scop return; MathLib::bigint result = 0; bool error = false; - execute(condTok, &pm, &result, &error); + execute(condTok, pm, &result, &error); if (error) programMemoryParseCondition(pm, condTok, endTok, settings, scope->type != Scope::eElse); } @@ -719,7 +719,7 @@ static std::unordered_map createBuiltinLibr return ValueFlow::Value::unknown(); const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue; ValueFlow::Value v; - combineValueProperties(args[0], args[1], &v); + combineValueProperties(args[0], args[1], v); v.floatValue = std::atan2(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue); v.valueType = ValueFlow::Value::ValueType::FLOAT; return v; @@ -731,7 +731,7 @@ static std::unordered_map createBuiltinLibr return ValueFlow::Value::unknown(); const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue; ValueFlow::Value v; - combineValueProperties(args[0], args[1], &v); + combineValueProperties(args[0], args[1], v); v.floatValue = std::remainder(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue); v.valueType = ValueFlow::Value::ValueType::FLOAT; return v; @@ -743,7 +743,7 @@ static std::unordered_map createBuiltinLibr return ValueFlow::Value::unknown(); const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue; ValueFlow::Value v; - combineValueProperties(args[0], args[1], &v); + combineValueProperties(args[0], args[1], v); v.floatValue = std::nextafter(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue); v.valueType = ValueFlow::Value::ValueType::FLOAT; return v; @@ -755,7 +755,7 @@ static std::unordered_map createBuiltinLibr return ValueFlow::Value::unknown(); const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue; ValueFlow::Value v; - combineValueProperties(args[0], args[1], &v); + combineValueProperties(args[0], args[1], v); v.floatValue = std::nexttoward(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue); v.valueType = ValueFlow::Value::ValueType::FLOAT; return v; @@ -767,7 +767,7 @@ static std::unordered_map createBuiltinLibr return ValueFlow::Value::unknown(); const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue; ValueFlow::Value v; - combineValueProperties(args[0], args[1], &v); + combineValueProperties(args[0], args[1], v); v.floatValue = std::hypot(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue); v.valueType = ValueFlow::Value::ValueType::FLOAT; return v; @@ -779,7 +779,7 @@ static std::unordered_map createBuiltinLibr return ValueFlow::Value::unknown(); const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue; ValueFlow::Value v; - combineValueProperties(args[0], args[1], &v); + combineValueProperties(args[0], args[1], v); v.floatValue = std::fdim(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue); v.valueType = ValueFlow::Value::ValueType::FLOAT; return v; @@ -791,7 +791,7 @@ static std::unordered_map createBuiltinLibr return ValueFlow::Value::unknown(); const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue; ValueFlow::Value v; - combineValueProperties(args[0], args[1], &v); + combineValueProperties(args[0], args[1], v); v.floatValue = std::fmax(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue); v.valueType = ValueFlow::Value::ValueType::FLOAT; return v; @@ -803,7 +803,7 @@ static std::unordered_map createBuiltinLibr return ValueFlow::Value::unknown(); const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue; ValueFlow::Value v; - combineValueProperties(args[0], args[1], &v); + combineValueProperties(args[0], args[1], v); v.floatValue = std::fmin(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue); v.valueType = ValueFlow::Value::ValueType::FLOAT; return v; @@ -815,7 +815,7 @@ static std::unordered_map createBuiltinLibr return ValueFlow::Value::unknown(); const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue; ValueFlow::Value v; - combineValueProperties(args[0], args[1], &v); + combineValueProperties(args[0], args[1], v); v.floatValue = std::fmod(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue); v.valueType = ValueFlow::Value::ValueType::FLOAT; return v; @@ -827,7 +827,7 @@ static std::unordered_map createBuiltinLibr return ValueFlow::Value::unknown(); const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue; ValueFlow::Value v; - combineValueProperties(args[0], args[1], &v); + combineValueProperties(args[0], args[1], v); v.floatValue = std::pow(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue); v.valueType = ValueFlow::Value::ValueType::FLOAT; return v; @@ -839,7 +839,7 @@ static std::unordered_map createBuiltinLibr return ValueFlow::Value::unknown(); const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue; ValueFlow::Value v; - combineValueProperties(args[0], args[1], &v); + combineValueProperties(args[0], args[1], v); v.floatValue = std::scalbln(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue); v.valueType = ValueFlow::Value::ValueType::FLOAT; return v; @@ -851,7 +851,7 @@ static std::unordered_map createBuiltinLibr return ValueFlow::Value::unknown(); const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue; ValueFlow::Value v; - combineValueProperties(args[0], args[1], &v); + combineValueProperties(args[0], args[1], v); v.floatValue = std::ldexp(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue); v.valueType = ValueFlow::Value::ValueType::FLOAT; return v; @@ -1408,12 +1408,12 @@ ValueFlow::Value evaluateLibraryFunction(const std::unordered_maplink()->previous(); // add array dimensions if present if (tok && tok->next()->str() == "[") - setFlag(fIsArray, arrayDimensions(settings, &isContainer)); + setFlag(fIsArray, arrayDimensions(settings, isContainer)); } if (!tok) return; @@ -3502,14 +3502,14 @@ bool Type::isDerivedFrom(const std::string & ancestor) const return false; } -bool Variable::arrayDimensions(const Settings* settings, bool* isContainer) +bool Variable::arrayDimensions(const Settings* settings, bool& isContainer) { - *isContainer = false; + isContainer = false; const Library::Container* container = settings->library.detectContainer(mTypeStartToken); if (container && container->arrayLike_indexOp && container->size_templateArgNo > 0) { const Token* tok = Token::findsimplematch(mTypeStartToken, "<"); if (tok) { - *isContainer = true; + isContainer = true; Dimension dimension_; tok = tok->next(); for (int i = 0; i < container->size_templateArgNo && tok; i++) { diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 9942e1620..b3c71c4fa 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -226,7 +226,7 @@ class CPPCHECKLIB Variable { * @param isContainer Is the array container-like? * @return true if array, false if not */ - bool arrayDimensions(const Settings* settings, bool* isContainer); + bool arrayDimensions(const Settings* settings, bool& isContainer); public: Variable(const Token *name_, const Token *start_, const Token *end_, diff --git a/lib/token.cpp b/lib/token.cpp index 50558bd84..c27c4e9fc 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -2496,13 +2496,13 @@ void TokenImpl::setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, M } } -bool TokenImpl::getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, MathLib::bigint *value) const +bool TokenImpl::getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, MathLib::bigint &value) const { struct CppcheckAttributes *attr = mCppcheckAttributes; while (attr && attr->type != type) attr = attr->next; if (attr) - *value = attr->value; + value = attr->value; return attr != nullptr; } diff --git a/lib/token.h b/lib/token.h index 09581df40..6b5536105 100644 --- a/lib/token.h +++ b/lib/token.h @@ -132,7 +132,7 @@ struct TokenImpl { TokenDebug mDebug; void setCppcheckAttribute(CppcheckAttributes::Type type, MathLib::bigint value); - bool getCppcheckAttribute(CppcheckAttributes::Type type, MathLib::bigint *value) const; + bool getCppcheckAttribute(CppcheckAttributes::Type type, MathLib::bigint &value) const; TokenImpl() : mVarId(0), @@ -559,7 +559,7 @@ public: void setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, MathLib::bigint value) { mImpl->setCppcheckAttribute(type, value); } - bool getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, MathLib::bigint *value) const { + bool getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, MathLib::bigint &value) const { return mImpl->getCppcheckAttribute(type, value); } bool hasCppcheckAttributes() const { diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 34fd69559..b68cd8450 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3483,8 +3483,11 @@ public: const std::map& map(bool global) const { return global ? mVariableId_global : mVariableId; } - nonneg int* getVarId() const { - return &mVarId; + nonneg int getVarId() const { + return mVarId; + } + nonneg int& getVarId() { + return mVarId; } }; @@ -3661,7 +3664,7 @@ static bool setVarIdParseDeclaration(const Token **tok, const VariableMap& varia void Tokenizer::setVarIdStructMembers(Token **tok1, std::map>& structMembers, - nonneg int *varId) const + nonneg int &varId) const { Token *tok = *tok1; @@ -3680,8 +3683,8 @@ void Tokenizer::setVarIdStructMembers(Token **tok1, tok = tok->next(); const std::map::iterator it = members.find(tok->str()); if (it == members.end()) { - members[tok->str()] = ++(*varId); - tok->varId(*varId); + members[tok->str()] = ++varId; + tok->varId(varId); } else { tok->varId(it->second); } @@ -3714,8 +3717,8 @@ void Tokenizer::setVarIdStructMembers(Token **tok1, std::map& members = structMembers[struct_varid]; const std::map::iterator it = members.find(tok->str()); if (it == members.end()) { - members[tok->str()] = ++(*varId); - tok->varId(*varId); + members[tok->str()] = ++varId; + tok->varId(varId); } else { tok->varId(it->second); } @@ -3726,7 +3729,7 @@ void Tokenizer::setVarIdStructMembers(Token **tok1, void Tokenizer::setVarIdClassDeclaration(const Token * const startToken, - const VariableMap &variableMap, + VariableMap &variableMap, const nonneg int scopeStartVarId, std::map>& structMembers) { @@ -3808,7 +3811,7 @@ void Tokenizer::setVarIdClassFunction(const std::string &classname, const Token * const endToken, const std::map &varlist, std::map>& structMembers, - nonneg int *varId_) + nonneg int &varId_) { for (Token *tok2 = startToken; tok2 && tok2 != endToken; tok2 = tok2->next()) { if (tok2->varId() != 0 || !tok2->isName()) @@ -3889,7 +3892,7 @@ void Tokenizer::setVarIdPass1() if (!variableMap.leaveScope()) cppcheckError(tok); } else if (tok->str() == "{") { - scopeStack.emplace(true, scopeStack.top().isStructInit || tok->strAt(-1) == "=", /*isEnum=*/ false, *variableMap.getVarId()); + scopeStack.emplace(true, scopeStack.top().isStructInit || tok->strAt(-1) == "=", /*isEnum=*/ false, variableMap.getVarId()); // check if this '{' is a start of an "if" body const Token * ifToken = tok->previous(); @@ -3951,7 +3954,7 @@ void Tokenizer::setVarIdPass1() variableMap.enterScope(); } initlist = false; - scopeStack.emplace(isExecutable, scopeStack.top().isStructInit || tok->strAt(-1) == "=", isEnumStart(tok), *variableMap.getVarId()); + scopeStack.emplace(isExecutable, scopeStack.top().isStructInit || tok->strAt(-1) == "=", isEnumStart(tok), variableMap.getVarId()); } else { /* if (tok->str() == "}") */ bool isNamespace = false; for (const Token *tok1 = tok->link()->previous(); tok1 && tok1->isName(); tok1 = tok1->previous()) { @@ -4212,7 +4215,7 @@ void Tokenizer::setVarIdPass1() } } - mVarId = *variableMap.getVarId(); + mVarId = variableMap.getVarId(); } namespace { @@ -4460,14 +4463,14 @@ void Tokenizer::setVarIdPass2() if (tok2->str() == "(") { Token *funcstart = const_cast(isFunctionHead(tok2, "{")); if (funcstart) { - setVarIdClassFunction(scopeName2 + classname, funcstart, funcstart->link(), thisClassVars, structMembers, &mVarId); + setVarIdClassFunction(scopeName2 + classname, funcstart, funcstart->link(), thisClassVars, structMembers, mVarId); tok2 = funcstart->link(); continue; } } if (tok2->str() == "{") { if (tok2->strAt(-1) == ")") - setVarIdClassFunction(scopeName2 + classname, tok2, tok2->link(), thisClassVars, structMembers, &mVarId); + setVarIdClassFunction(scopeName2 + classname, tok2, tok2->link(), thisClassVars, structMembers, mVarId); tok2 = tok2->link(); } else if (Token::Match(tok2, "( %name%|)") && !Token::Match(tok2->link(), "(|[")) { tok2 = tok2->link(); @@ -4513,7 +4516,7 @@ void Tokenizer::setVarIdPass2() // If this is a function implementation.. add it to funclist Token * start = const_cast(isFunctionHead(tok2, "{")); if (start) { - setVarIdClassFunction(classname, start, start->link(), thisClassVars, structMembers, &mVarId); + setVarIdClassFunction(classname, start, start->link(), thisClassVars, structMembers, mVarId); } if (Token::Match(tok2, ") %name% (")) @@ -4547,7 +4550,7 @@ void Tokenizer::setVarIdPass2() tok3 = tok3->linkAt(1); } if (Token::Match(tok3, ")|} {")) { - setVarIdClassFunction(classname, tok2, tok3->next()->link(), thisClassVars, structMembers, &mVarId); + setVarIdClassFunction(classname, tok2, tok3->next()->link(), thisClassVars, structMembers, mVarId); } } } diff --git a/lib/tokenize.h b/lib/tokenize.h index 43a754b56..0ba1f9705 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -587,20 +587,20 @@ private: void unsupportedTypedef(const Token *tok) const; void setVarIdClassDeclaration(const Token * const startToken, - const VariableMap &variableMap, + VariableMap &variableMap, const nonneg int scopeStartVarId, std::map>& structMembers); void setVarIdStructMembers(Token **tok1, std::map>& structMembers, - nonneg int *varId) const; + nonneg int &varId) const; void setVarIdClassFunction(const std::string &classname, Token * const startToken, const Token * const endToken, const std::map &varlist, std::map>& structMembers, - nonneg int *varId_); + nonneg int &varId_); /** * Output list of unknown types. diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index ec726bca8..8bf847703 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -418,47 +418,47 @@ static bool isNumeric(const ValueFlow::Value& value) { return value.isIntValue() || value.isFloatValue(); } -void ValueFlow::combineValueProperties(const ValueFlow::Value &value1, const ValueFlow::Value &value2, ValueFlow::Value *result) +void ValueFlow::combineValueProperties(const ValueFlow::Value &value1, const ValueFlow::Value &value2, ValueFlow::Value &result) { if (value1.isKnown() && value2.isKnown()) - result->setKnown(); + result.setKnown(); else if (value1.isImpossible() || value2.isImpossible()) - result->setImpossible(); + result.setImpossible(); else if (value1.isInconclusive() || value2.isInconclusive()) - result->setInconclusive(); + result.setInconclusive(); else - result->setPossible(); + result.setPossible(); if (value1.tokvalue) - result->tokvalue = value1.tokvalue; + result.tokvalue = value1.tokvalue; else if (value2.tokvalue) - result->tokvalue = value2.tokvalue; + result.tokvalue = value2.tokvalue; if (value1.isSymbolicValue()) { - result->valueType = value1.valueType; - result->tokvalue = value1.tokvalue; + result.valueType = value1.valueType; + result.tokvalue = value1.tokvalue; } if (value2.isSymbolicValue()) { - result->valueType = value2.valueType; - result->tokvalue = value2.tokvalue; + result.valueType = value2.valueType; + result.tokvalue = value2.tokvalue; } if (value1.isIteratorValue()) - result->valueType = value1.valueType; + result.valueType = value1.valueType; if (value2.isIteratorValue()) - result->valueType = value2.valueType; - result->condition = value1.condition ? value1.condition : value2.condition; - result->varId = (value1.varId != 0) ? value1.varId : value2.varId; - result->varvalue = (result->varId == value1.varId) ? value1.varvalue : value2.varvalue; - result->errorPath = (value1.errorPath.empty() ? value2 : value1).errorPath; - result->safe = value1.safe || value2.safe; + result.valueType = value2.valueType; + result.condition = value1.condition ? value1.condition : value2.condition; + result.varId = (value1.varId != 0) ? value1.varId : value2.varId; + result.varvalue = (result.varId == value1.varId) ? value1.varvalue : value2.varvalue; + result.errorPath = (value1.errorPath.empty() ? value2 : value1).errorPath; + result.safe = value1.safe || value2.safe; if (value1.bound == ValueFlow::Value::Bound::Point || value2.bound == ValueFlow::Value::Bound::Point) { if (value1.bound == ValueFlow::Value::Bound::Upper || value2.bound == ValueFlow::Value::Bound::Upper) - result->bound = ValueFlow::Value::Bound::Upper; + result.bound = ValueFlow::Value::Bound::Upper; if (value1.bound == ValueFlow::Value::Bound::Lower || value2.bound == ValueFlow::Value::Bound::Lower) - result->bound = ValueFlow::Value::Bound::Lower; + result.bound = ValueFlow::Value::Bound::Lower; } if (value1.path != value2.path) - result->path = -1; + result.path = -1; else - result->path = value1.path; + result.path = value1.path; } static const Token *getCastTypeStartToken(const Token *parent, const Settings* settings) @@ -652,7 +652,7 @@ static void setTokenValue(Token* tok, else continue; - combineValueProperties(value1, value2, &result); + combineValueProperties(value1, value2, result); if (Token::simpleMatch(parent, "==") && result.intvalue) continue; @@ -854,7 +854,7 @@ static void setTokenValue(Token* tok, if (!isCompatibleValues(value1, value2)) continue; ValueFlow::Value result(0); - combineValueProperties(value1, value2, &result); + combineValueProperties(value1, value2, result); if (astIsFloat(parent, false)) { if (!result.isIntValue() && !result.isFloatValue()) continue; @@ -1097,7 +1097,7 @@ size_t ValueFlow::getSizeOf(const ValueType &vt, const Settings *settings) } -static bool getMinMaxValues(const ValueType* vt, const cppcheck::Platform& platform, MathLib::bigint* minValue, MathLib::bigint* maxValue); +static bool getMinMaxValues(const ValueType* vt, const cppcheck::Platform& platform, MathLib::bigint& minValue, MathLib::bigint& maxValue); // Handle various constants.. static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, bool cpp) @@ -1108,7 +1108,7 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, b const ValueType* vt = tok->valueType(); if (vt && vt->sign == ValueType::UNSIGNED && signedValue < 0 && ValueFlow::getSizeOf(*vt, settings) < sizeof(MathLib::bigint)) { MathLib::bigint minValue{}, maxValue{}; - if (getMinMaxValues(tok->valueType(), *settings, &minValue, &maxValue)) + if (getMinMaxValues(tok->valueType(), *settings, minValue, maxValue)) signedValue += maxValue + 1; } ValueFlow::Value value(signedValue); @@ -2817,7 +2817,7 @@ struct ValueFlowAnalyzer : Analyzer { } else { MathLib::bigint out = 0; bool error = false; - execute(tok, &pm, &out, &error, getSettings()); + execute(tok, pm, &out, &error, getSettings()); if (!error) result.push_back(out); } @@ -2844,7 +2844,7 @@ struct ValueFlowAnalyzer : Analyzer { return {value->intvalue == 0}; ProgramMemory pm = pms.get(tok, ctx, getProgramState()); MathLib::bigint out = 0; - if (pm.getContainerEmptyValue(tok->exprId(), &out)) + if (pm.getContainerEmptyValue(tok->exprId(), out)) return {static_cast(out)}; return {}; } else { @@ -6344,9 +6344,9 @@ struct ConditionHandler { ProgramMemory pm; fillFromPath(pm, initTok, path); fillFromPath(pm, condTok, path); - execute(initTok, &pm, nullptr, nullptr); + execute(initTok, pm, nullptr, nullptr); MathLib::bigint result = 1; - execute(condTok, &pm, &result, nullptr); + execute(condTok, pm, &result, nullptr); if (result == 0) return; // Remove condition since for condition is not redundant @@ -6762,10 +6762,10 @@ static bool valueFlowForLoop2(const Token *tok, ProgramMemory programMemory; MathLib::bigint result(0); bool error = false; - execute(firstExpression, &programMemory, &result, &error); + execute(firstExpression, programMemory, &result, &error); if (error) return false; - execute(secondExpression, &programMemory, &result, &error); + execute(secondExpression, programMemory, &result, &error); if (result == 0) // 2nd expression is false => no looping return false; if (error) { @@ -6788,9 +6788,9 @@ static bool valueFlowForLoop2(const Token *tok, int maxcount = 10000; while (result != 0 && !error && --maxcount > 0) { endMemory = programMemory; - execute(thirdExpression, &programMemory, &result, &error); + execute(thirdExpression, programMemory, &result, &error); if (!error) - execute(secondExpression, &programMemory, &result, &error); + execute(secondExpression, programMemory, &result, &error); } if (memory1) @@ -6954,7 +6954,7 @@ static void valueFlowForLoop(TokenList *tokenlist, SymbolDatabase* symboldatabas bool knownInitValue, partialCond; MathLib::bigint initValue, stepValue, lastValue; - if (extractForLoopValues(tok, &varid, &knownInitValue, &initValue, &partialCond, &stepValue, &lastValue)) { + if (extractForLoopValues(tok, varid, knownInitValue, initValue, partialCond, stepValue, lastValue)) { const bool executeBody = !knownInitValue || initValue <= lastValue; const Token* vartok = Token::findmatch(tok, "%varid%", bodyStart, varid); if (executeBody && vartok) { @@ -7556,7 +7556,7 @@ static void valueFlowFunctionReturn(TokenList *tokenlist, ErrorLogger *errorLogg MathLib::bigint result = 0; bool error = false; execute(functionScope->bodyStart->next()->astOperand1(), - &programMemory, + programMemory, &result, &error); if (!error) { @@ -8631,7 +8631,7 @@ static void valueFlowDynamicBufferSize(TokenList* tokenlist, SymbolDatabase* sym } } -static bool getMinMaxValues(const ValueType *vt, const cppcheck::Platform &platform, MathLib::bigint *minValue, MathLib::bigint *maxValue) +static bool getMinMaxValues(const ValueType *vt, const cppcheck::Platform &platform, MathLib::bigint &minValue, MathLib::bigint &maxValue) { if (!vt || !vt->isIntegral() || vt->pointer) return false; @@ -8661,23 +8661,23 @@ static bool getMinMaxValues(const ValueType *vt, const cppcheck::Platform &platf } if (bits == 1) { - *minValue = 0; - *maxValue = 1; + minValue = 0; + maxValue = 1; } else if (bits < 62) { if (vt->sign == ValueType::Sign::UNSIGNED) { - *minValue = 0; - *maxValue = (1LL << bits) - 1; + minValue = 0; + maxValue = (1LL << bits) - 1; } else { - *minValue = -(1LL << (bits - 1)); - *maxValue = (1LL << (bits - 1)) - 1; + minValue = -(1LL << (bits - 1)); + maxValue = (1LL << (bits - 1)) - 1; } } else if (bits == 64) { if (vt->sign == ValueType::Sign::UNSIGNED) { - *minValue = 0; - *maxValue = LLONG_MAX; // todo max unsigned value + minValue = 0; + maxValue = LLONG_MAX; // todo max unsigned value } else { - *minValue = LLONG_MIN; - *maxValue = LLONG_MAX; + minValue = LLONG_MIN; + maxValue = LLONG_MAX; } } else { return false; @@ -8686,7 +8686,7 @@ static bool getMinMaxValues(const ValueType *vt, const cppcheck::Platform &platf return true; } -static bool getMinMaxValues(const std::string &typestr, const Settings *settings, MathLib::bigint *minvalue, MathLib::bigint *maxvalue) +static bool getMinMaxValues(const std::string &typestr, const Settings *settings, MathLib::bigint &minvalue, MathLib::bigint &maxvalue) { TokenList typeTokens(settings); std::istringstream istr(typestr+";"); @@ -8732,8 +8732,8 @@ static void valueFlowSafeFunctions(TokenList* tokenlist, SymbolDatabase* symbold } MathLib::bigint low, high; - bool isLow = arg.nameToken()->getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::LOW, &low); - bool isHigh = arg.nameToken()->getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::HIGH, &high); + bool isLow = arg.nameToken()->getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::LOW, low); + bool isHigh = arg.nameToken()->getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::HIGH, high); if (!isLow && !isHigh && !all) continue; @@ -8743,7 +8743,7 @@ static void valueFlowSafeFunctions(TokenList* tokenlist, SymbolDatabase* symbold if ((!isLow || !isHigh) && all) { MathLib::bigint minValue, maxValue; - if (getMinMaxValues(arg.valueType(), *settings, &minValue, &maxValue)) { + if (getMinMaxValues(arg.valueType(), *settings, minValue, maxValue)) { if (!isLow) low = minValue; if (!isHigh) @@ -8808,7 +8808,7 @@ static void valueFlowUnknownFunctionReturn(TokenList *tokenlist, const Settings // Get min/max values for return type const std::string &typestr = settings->library.returnValueType(tok->previous()); MathLib::bigint minvalue, maxvalue; - if (!getMinMaxValues(typestr, settings, &minvalue, &maxvalue)) + if (!getMinMaxValues(typestr, settings, minvalue, maxvalue)) continue; for (MathLib::bigint value : unknownValues) { diff --git a/lib/valueflow.h b/lib/valueflow.h index 007154eae..9ff9c753a 100644 --- a/lib/valueflow.h +++ b/lib/valueflow.h @@ -126,7 +126,7 @@ namespace ValueFlow { const Token* getEndOfExprScope(const Token* tok, const Scope* defaultScope = nullptr, bool smallest = true); - void combineValueProperties(const Value& value1, const Value& value2, Value* result); + void combineValueProperties(const Value& value1, const Value& value2, Value& result); } #endif // valueflowH diff --git a/test/testlibrary.cpp b/test/testlibrary.cpp index ba78e1e0d..08a4311f6 100644 --- a/test/testlibrary.cpp +++ b/test/testlibrary.cpp @@ -662,10 +662,10 @@ private: ASSERT(library.loadxmldata(xmldata, sizeof(xmldata))); ASSERT(library.functions.empty()); - ASSERT(Library::ismemory(library.getAllocFuncInfo("CreateX"))); - ASSERT_EQUALS(library.allocId("CreateX"), library.deallocId("DeleteX")); const Library::AllocFunc* af = library.getAllocFuncInfo("CreateX"); ASSERT(af && af->arg == -1); + ASSERT(Library::ismemory(af)); + ASSERT_EQUALS(library.allocId("CreateX"), library.deallocId("DeleteX")); const Library::AllocFunc* df = library.getDeallocFuncInfo("DeleteX"); ASSERT(df && df->arg == 1); }