From 93b18bd2d8f74e87ad513e58565557071da1ba2d Mon Sep 17 00:00:00 2001 From: firewave Date: Mon, 15 Apr 2024 19:48:28 +0200 Subject: [PATCH] changed most `Settings` pointers to references --- Makefile | 2 +- lib/astutils.cpp | 193 ++++++++++++++++++------------------ lib/astutils.h | 39 ++++---- lib/checkautovariables.cpp | 16 +-- lib/checkbool.cpp | 6 +- lib/checkbufferoverrun.cpp | 30 +++--- lib/checkclass.cpp | 2 +- lib/checkcondition.cpp | 52 +++++----- lib/checkfunctions.cpp | 4 +- lib/checkio.cpp | 18 ++-- lib/checkio.h | 4 +- lib/checkleakautovar.cpp | 6 +- lib/checkother.cpp | 92 ++++++++--------- lib/checkstl.cpp | 58 +++++------ lib/checkstring.cpp | 6 +- lib/checktype.cpp | 10 +- lib/checkuninitvar.cpp | 4 +- lib/checkunusedvar.cpp | 6 +- lib/ctu.cpp | 2 +- lib/forwardanalyzer.cpp | 6 +- lib/fwdanalysis.cpp | 19 ++-- lib/fwdanalysis.h | 6 +- lib/library.cpp | 6 +- lib/library.h | 2 +- lib/programmemory.cpp | 76 +++++++------- lib/programmemory.h | 8 +- lib/symboldatabase.cpp | 23 ++--- lib/symboldatabase.h | 6 +- lib/token.cpp | 16 +-- lib/token.h | 6 +- lib/valueflow.cpp | 168 +++++++++++++++---------------- lib/valueflow.h | 9 +- oss-fuzz/Makefile | 2 +- test/testastutils.cpp | 11 +- test/testsymboldatabase.cpp | 78 +++++++-------- 35 files changed, 498 insertions(+), 494 deletions(-) diff --git a/Makefile b/Makefile index f482051b8fa..a3d89deabe9 100644 --- a/Makefile +++ b/Makefile @@ -582,7 +582,7 @@ $(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/ $(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/forwardanalyzer.cpp -$(libcppdir)/fwdanalysis.o: lib/fwdanalysis.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h +$(libcppdir)/fwdanalysis.o: lib/fwdanalysis.cpp lib/addoninfo.h lib/astutils.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/fwdanalysis.cpp $(libcppdir)/importproject.o: lib/importproject.cpp externals/picojson/picojson.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/config.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 105d780fd88..70f93932f94 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -704,7 +704,7 @@ static bool isInConstructorList(const Token* tok) return Token::simpleMatch(parent, ":") && !Token::simpleMatch(parent->astParent(), "?"); } -std::vector getParentValueTypes(const Token* tok, const Settings* settings, const Token** parent) +std::vector getParentValueTypes(const Token* tok, const Settings& settings, const Token** parent) { if (!tok) return {}; @@ -755,13 +755,13 @@ std::vector getParentValueTypes(const Token* tok, const Settings* set } } } - if (settings && Token::Match(tok->astParent()->tokAt(-2), ". push_back|push_front|insert|push (") && + if (Token::Match(tok->astParent()->tokAt(-2), ". push_back|push_front|insert|push (") && astIsContainer(tok->astParent()->tokAt(-2)->astOperand1())) { const Token* contTok = tok->astParent()->tokAt(-2)->astOperand1(); const ValueType* vtCont = contTok->valueType(); if (!vtCont->containerTypeToken) return {}; - ValueType vtParent = ValueType::parseDecl(vtCont->containerTypeToken, *settings); + ValueType vtParent = ValueType::parseDecl(vtCont->containerTypeToken, settings); return {std::move(vtParent)}; } // The return type of a function is not the parent valuetype @@ -1151,7 +1151,7 @@ bool isStructuredBindingVariable(const Variable* var) /// This takes a token that refers to a variable and it will return the token /// to the expression that the variable is assigned to. If its not valid to /// make such substitution then it will return the original token. -static const Token * followVariableExpression(const Token * tok, const Token * end = nullptr) +static const Token * followVariableExpression(const Settings& settings, const Token * tok, const Token * end = nullptr) { if (!tok) return tok; @@ -1189,7 +1189,7 @@ static const Token * followVariableExpression(const Token * tok, const Token * e const Token * lastTok = precedes(tok, end) ? end : tok; // If this is in a loop then check if variables are modified in the entire scope const Token * endToken = (isInLoopCondition(tok) || isInLoopCondition(varTok) || var->scope() != tok->scope()) ? var->scope()->bodyEnd : lastTok; - if (!var->isConst() && (!precedes(varTok, endToken) || isVariableChanged(varTok, endToken, tok->varId(), false, nullptr))) + if (!var->isConst() && (!precedes(varTok, endToken) || isVariableChanged(varTok, endToken, tok->varId(), false, settings))) return tok; if (precedes(varTok, endToken) && isAliased(varTok, endToken, tok->varId())) return tok; @@ -1201,7 +1201,7 @@ static const Token * followVariableExpression(const Token * tok, const Token * e return tok; } else if (!precedes(startToken, endToken)) { return tok; - } else if (findExpressionChanged(varTok, startToken, endToken, nullptr)) { + } else if (findExpressionChanged(varTok, startToken, endToken, settings)) { return tok; } return varTok; @@ -1474,7 +1474,7 @@ static bool isForLoopIncrement(const Token* const tok) parent->astParent()->astParent()->astOperand1()->str() == "for"; } -bool isUsedAsBool(const Token* const tok, const Settings* settings) +bool isUsedAsBool(const Token* const tok, const Settings& settings) { if (!tok) return false; @@ -1499,9 +1499,9 @@ bool isUsedAsBool(const Token* const tok, const Settings* settings) if (Token::Match(parent, "&&|!|%oror%")) return true; if (parent->isCast()) - return !Token::simpleMatch(parent->astOperand1(), "dynamic_cast") && isUsedAsBool(parent); + return !Token::simpleMatch(parent->astOperand1(), "dynamic_cast") && isUsedAsBool(parent, settings); if (parent->isUnaryOp("*")) - return isUsedAsBool(parent); + return isUsedAsBool(parent, settings); if (Token::Match(parent, "==|!=") && (tok->astSibling()->isNumber() || tok->astSibling()->isKeyword()) && tok->astSibling()->hasKnownIntValue() && tok->astSibling()->values().front().intvalue == 0) return true; @@ -1536,12 +1536,12 @@ bool compareTokenFlags(const Token* tok1, const Token* tok2, bool macro) { return true; } -static bool astIsBoolLike(const Token* tok) +static bool astIsBoolLike(const Token* tok, const Settings& settings) { - return astIsBool(tok) || isUsedAsBool(tok); + return astIsBool(tok) || isUsedAsBool(tok, settings); } -bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Library& library, bool pure, bool followVar, ErrorPath* errors) +bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Settings& settings, bool pure, bool followVar, ErrorPath* errors) { if (tok1 == tok2) return true; @@ -1555,11 +1555,11 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Li tok2 = tok2->astOperand2(); } // Skip double not - if (Token::simpleMatch(tok1, "!") && Token::simpleMatch(tok1->astOperand1(), "!") && !Token::simpleMatch(tok1->astParent(), "=") && astIsBoolLike(tok2)) { - return isSameExpression(macro, tok1->astOperand1()->astOperand1(), tok2, library, pure, followVar, errors); + if (Token::simpleMatch(tok1, "!") && Token::simpleMatch(tok1->astOperand1(), "!") && !Token::simpleMatch(tok1->astParent(), "=") && astIsBoolLike(tok2, settings)) { + return isSameExpression(macro, tok1->astOperand1()->astOperand1(), tok2, settings, pure, followVar, errors); } - if (Token::simpleMatch(tok2, "!") && Token::simpleMatch(tok2->astOperand1(), "!") && !Token::simpleMatch(tok2->astParent(), "=") && astIsBoolLike(tok1)) { - return isSameExpression(macro, tok1, tok2->astOperand1()->astOperand1(), library, pure, followVar, errors); + if (Token::simpleMatch(tok2, "!") && Token::simpleMatch(tok2->astOperand1(), "!") && !Token::simpleMatch(tok2->astParent(), "=") && astIsBoolLike(tok1, settings)) { + return isSameExpression(macro, tok1, tok2->astOperand1()->astOperand1(), settings, pure, followVar, errors); } const bool tok_str_eq = tok1->str() == tok2->str(); if (!tok_str_eq && isDifferentKnownValues(tok1, tok2)) @@ -1575,20 +1575,20 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Li // Follow variable if (followVar && !tok_str_eq && (followTok1->varId() || followTok2->varId() || followTok1->enumerator() || followTok2->enumerator())) { - const Token * varTok1 = followVariableExpression(followTok1, followTok2); + const Token * varTok1 = followVariableExpression(settings, followTok1, followTok2); if ((varTok1->str() == followTok2->str()) || isSameConstantValue(macro, varTok1, followTok2)) { followVariableExpressionError(followTok1, varTok1, errors); - return isSameExpression(macro, varTok1, followTok2, library, true, followVar, errors); + return isSameExpression(macro, varTok1, followTok2, settings, true, followVar, errors); } - const Token * varTok2 = followVariableExpression(followTok2, followTok1); + const Token * varTok2 = followVariableExpression(settings, followTok2, followTok1); if ((followTok1->str() == varTok2->str()) || isSameConstantValue(macro, followTok1, varTok2)) { followVariableExpressionError(followTok2, varTok2, errors); - return isSameExpression(macro, followTok1, varTok2, library, true, followVar, errors); + return isSameExpression(macro, followTok1, varTok2, settings, true, followVar, errors); } if ((varTok1->str() == varTok2->str()) || isSameConstantValue(macro, varTok1, varTok2)) { followVariableExpressionError(tok1, varTok1, errors); followVariableExpressionError(tok2, varTok2, errors); - return isSameExpression(macro, varTok1, varTok2, library, true, followVar, errors); + return isSameExpression(macro, varTok1, varTok2, settings, true, followVar, errors); } } // Follow references @@ -1600,17 +1600,17 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Li const Token *start = refTok1, *end = refTok2; if (!precedes(start, end)) std::swap(start, end); - if (findExpressionChanged(start, start, end, nullptr)) + if (findExpressionChanged(start, start, end, settings)) return false; } - return isSameExpression(macro, refTok1, refTok2, library, pure, followVar, errors); + return isSameExpression(macro, refTok1, refTok2, settings, pure, followVar, errors); } } if (tok1->varId() != tok2->varId() || !tok_str_eq || tok1->originalName() != tok2->originalName()) { if ((Token::Match(tok1,"<|>") && Token::Match(tok2,"<|>")) || (Token::Match(tok1,"<=|>=") && Token::Match(tok2,"<=|>="))) { - return isSameExpression(macro, tok1->astOperand1(), tok2->astOperand2(), library, pure, followVar, errors) && - isSameExpression(macro, tok1->astOperand2(), tok2->astOperand1(), library, pure, followVar, errors); + return isSameExpression(macro, tok1->astOperand1(), tok2->astOperand2(), settings, pure, followVar, errors) && + isSameExpression(macro, tok1->astOperand2(), tok2->astOperand1(), settings, pure, followVar, errors); } const Token* condTok = nullptr; const Token* exprTok = nullptr; @@ -1647,8 +1647,8 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Li compare = true; } } - if (compare && astIsBoolLike(varTok1) && astIsBoolLike(varTok2)) - return isSameExpression(macro, varTok1, varTok2, library, pure, followVar, errors); + if (compare && astIsBoolLike(varTok1, settings) && astIsBoolLike(varTok2, settings)) + return isSameExpression(macro, varTok1, varTok2, settings, pure, followVar, errors); } return false; @@ -1667,14 +1667,14 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Li return false; const bool lhsIsConst = (lhs->variable() && lhs->variable()->isConst()) || (lhs->valueType() && lhs->valueType()->constness > 0) || - (Token::Match(lhs, "%var% . %name% (") && library.isFunctionConst(lhs->tokAt(2))); + (Token::Match(lhs, "%var% . %name% (") && settings.library.isFunctionConst(lhs->tokAt(2))); if (!lhsIsConst) return false; } else { const Token * ftok = tok1; if (Token::simpleMatch(tok1->previous(), "::")) ftok = tok1->previous(); - if (!library.isFunctionConst(ftok) && !ftok->isAttributeConst() && !ftok->isAttributePure()) + if (!settings.library.isFunctionConst(ftok) && !ftok->isAttributeConst() && !ftok->isAttributePure()) return false; } } else { @@ -1729,9 +1729,9 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Li return false; } bool noncommutativeEquals = - isSameExpression(macro, tok1->astOperand1(), tok2->astOperand1(), library, pure, followVar, errors); + isSameExpression(macro, tok1->astOperand1(), tok2->astOperand1(), settings, pure, followVar, errors); noncommutativeEquals = noncommutativeEquals && - isSameExpression(macro, tok1->astOperand2(), tok2->astOperand2(), library, pure, followVar, errors); + isSameExpression(macro, tok1->astOperand2(), tok2->astOperand2(), settings, pure, followVar, errors); if (noncommutativeEquals) return true; @@ -1746,9 +1746,9 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Li const bool commutative = tok1->isBinaryOp() && Token::Match(tok1, "%or%|%oror%|+|*|&|&&|^|==|!="); bool commutativeEquals = commutative && - isSameExpression(macro, tok1->astOperand2(), tok2->astOperand1(), library, pure, followVar, errors); + isSameExpression(macro, tok1->astOperand2(), tok2->astOperand1(), settings, pure, followVar, errors); commutativeEquals = commutativeEquals && - isSameExpression(macro, tok1->astOperand1(), tok2->astOperand2(), library, pure, followVar, errors); + isSameExpression(macro, tok1->astOperand1(), tok2->astOperand2(), settings, pure, followVar, errors); return commutativeEquals; @@ -1772,12 +1772,12 @@ static bool isZeroBoundCond(const Token * const cond) return false; } -bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const cond2, const Library& library, bool pure, bool followVar, ErrorPath* errors) +bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const cond2, const Settings& settings, bool pure, bool followVar, ErrorPath* errors) { if (!cond1 || !cond2) return false; - if (isSameExpression(true, cond1, cond2, library, pure, followVar, errors)) + if (isSameExpression(true, cond1, cond2, settings, pure, followVar, errors)) return false; if (!isNot && cond1->str() == "&&" && cond2->str() == "&&") { @@ -1787,8 +1787,8 @@ bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const c for (const Token* tok2: { cond2->astOperand1(), cond2->astOperand2() }) { - if (isSameExpression(true, tok1, tok2, library, pure, followVar, errors)) { - if (isOppositeCond(isNot, tok1->astSibling(), tok2->astSibling(), library, pure, followVar, errors)) + if (isSameExpression(true, tok1, tok2, settings, pure, followVar, errors)) { + if (isOppositeCond(isNot, tok1->astSibling(), tok2->astSibling(), settings, pure, followVar, errors)) return true; } } @@ -1806,30 +1806,30 @@ bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const c orCond = cond2; otherCond = cond1; } - return isOppositeCond(isNot, orCond->astOperand1(), otherCond, library, pure, followVar, errors) && - isOppositeCond(isNot, orCond->astOperand2(), otherCond, library, pure, followVar, errors); + return isOppositeCond(isNot, orCond->astOperand1(), otherCond, settings, pure, followVar, errors) && + isOppositeCond(isNot, orCond->astOperand2(), otherCond, settings, pure, followVar, errors); } if (cond1->str() == "!") { if (cond2->str() == "!=") { if (cond2->astOperand1() && cond2->astOperand1()->str() == "0") - return isSameExpression(true, cond1->astOperand1(), cond2->astOperand2(), library, pure, followVar, errors); + return isSameExpression(true, cond1->astOperand1(), cond2->astOperand2(), settings, pure, followVar, errors); if (cond2->astOperand2() && cond2->astOperand2()->str() == "0") - return isSameExpression(true, cond1->astOperand1(), cond2->astOperand1(), library, pure, followVar, errors); + return isSameExpression(true, cond1->astOperand1(), cond2->astOperand1(), settings, pure, followVar, errors); } - if (!isUsedAsBool(cond2)) + if (!isUsedAsBool(cond2, settings)) return false; - return isSameExpression(true, cond1->astOperand1(), cond2, library, pure, followVar, errors); + return isSameExpression(true, cond1->astOperand1(), cond2, settings, pure, followVar, errors); } if (cond2->str() == "!") - return isOppositeCond(isNot, cond2, cond1, library, pure, followVar, errors); + return isOppositeCond(isNot, cond2, cond1, settings, pure, followVar, errors); if (!isNot) { if (cond1->str() == "==" && cond2->str() == "==") { - if (isSameExpression(true, cond1->astOperand1(), cond2->astOperand1(), library, pure, followVar, errors)) + if (isSameExpression(true, cond1->astOperand1(), cond2->astOperand1(), settings, pure, followVar, errors)) return isDifferentKnownValues(cond1->astOperand2(), cond2->astOperand2()); - if (isSameExpression(true, cond1->astOperand2(), cond2->astOperand2(), library, pure, followVar, errors)) + if (isSameExpression(true, cond1->astOperand2(), cond2->astOperand2(), settings, pure, followVar, errors)) return isDifferentKnownValues(cond1->astOperand1(), cond2->astOperand1()); } // TODO: Handle reverse conditions @@ -1838,7 +1838,7 @@ bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const c isSameExpression(true, cond1->astOperand1()->astOperand1(), cond2->astOperand1()->astOperand1()->astOperand1(), - library, + settings, pure, followVar, errors)) { @@ -1850,7 +1850,7 @@ bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const c isSameExpression(true, cond2->astOperand1()->astOperand1(), cond1->astOperand1()->astOperand1()->astOperand1(), - library, + settings, pure, followVar, errors)) { @@ -1866,11 +1866,11 @@ bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const c // condition found .. get comparator std::string comp2; - if (isSameExpression(true, cond1->astOperand1(), cond2->astOperand1(), library, pure, followVar, errors) && - isSameExpression(true, cond1->astOperand2(), cond2->astOperand2(), library, pure, followVar, errors)) { + if (isSameExpression(true, cond1->astOperand1(), cond2->astOperand1(), settings, pure, followVar, errors) && + isSameExpression(true, cond1->astOperand2(), cond2->astOperand2(), settings, pure, followVar, errors)) { comp2 = cond2->str(); - } else if (isSameExpression(true, cond1->astOperand1(), cond2->astOperand2(), library, pure, followVar, errors) && - isSameExpression(true, cond1->astOperand2(), cond2->astOperand1(), library, pure, followVar, errors)) { + } else if (isSameExpression(true, cond1->astOperand1(), cond2->astOperand2(), settings, pure, followVar, errors) && + isSameExpression(true, cond1->astOperand2(), cond2->astOperand1(), settings, pure, followVar, errors)) { comp2 = cond2->str(); if (comp2[0] == '>') comp2[0] = '<'; @@ -1906,7 +1906,7 @@ bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const c if (!expr1 || !value1 || !expr2 || !value2) { return false; } - if (!isSameExpression(true, expr1, expr2, library, pure, followVar, errors)) + if (!isSameExpression(true, expr1, expr2, settings, pure, followVar, errors)) return false; const ValueFlow::Value &rhsValue1 = value1->values().front(); @@ -1934,16 +1934,16 @@ bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const c ))); } -bool isOppositeExpression(const Token * const tok1, const Token * const tok2, const Library& library, bool pure, bool followVar, ErrorPath* errors) +bool isOppositeExpression(const Token * const tok1, const Token * const tok2, const Settings& settings, bool pure, bool followVar, ErrorPath* errors) { if (!tok1 || !tok2) return false; - if (isOppositeCond(true, tok1, tok2, library, pure, followVar, errors)) + if (isOppositeCond(true, tok1, tok2, settings, pure, followVar, errors)) return true; if (tok1->isUnaryOp("-") && !(tok2->astParent() && tok2->astParent()->tokType() == Token::eBitOp)) - return isSameExpression(true, tok1->astOperand1(), tok2, library, pure, followVar, errors); + return isSameExpression(true, tok1->astOperand1(), tok2, settings, pure, followVar, errors); if (tok2->isUnaryOp("-") && !(tok2->astParent() && tok2->astParent()->tokType() == Token::eBitOp)) - return isSameExpression(true, tok2->astOperand1(), tok1, library, pure, followVar, errors); + return isSameExpression(true, tok2->astOperand1(), tok1, settings, pure, followVar, errors); return false; } @@ -2250,7 +2250,7 @@ bool isWithinScope(const Token* tok, const Variable* var, Scope::ScopeType type) return false; } -bool isVariableChangedByFunctionCall(const Token *tok, int indirect, nonneg int varid, const Settings *settings, bool *inconclusive) +bool isVariableChangedByFunctionCall(const Token *tok, int indirect, nonneg int varid, const Settings &settings, bool *inconclusive) { if (!tok) return false; @@ -2425,7 +2425,7 @@ static bool isArray(const Token* tok) return false; } -bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Settings *settings, bool *inconclusive) +bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Settings &settings, bool *inconclusive) { if (!tok) return false; @@ -2464,29 +2464,27 @@ bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Setti const bool possiblyPassedByReference = (parenTok->next() == tok1 || Token::Match(tok1->previous(), ", %name% [,)}]")); if (!tok->function() && !tok->variable() && tok->isName()) { - if (settings) { - // Check if direction (in, out, inout) is specified in the library configuration and use that - const Library::ArgumentChecks::Direction argDirection = settings->library.getArgDirection(tok, 1 + argnr); - if (argDirection == Library::ArgumentChecks::Direction::DIR_IN) - return false; + // Check if direction (in, out, inout) is specified in the library configuration and use that + const Library::ArgumentChecks::Direction argDirection = settings.library.getArgDirection(tok, 1 + argnr); + if (argDirection == Library::ArgumentChecks::Direction::DIR_IN) + return false; - const bool requireNonNull = settings->library.isnullargbad(tok, 1 + argnr); - if (argDirection == Library::ArgumentChecks::Direction::DIR_OUT || - argDirection == Library::ArgumentChecks::Direction::DIR_INOUT) { - if (indirect == 0 && isArray(tok1)) - return true; - const bool requireInit = settings->library.isuninitargbad(tok, 1 + argnr); - // Assume that if the variable must be initialized then the indirection is 1 - if (indirect > 0 && requireInit && requireNonNull) - return true; - } - if (Token::simpleMatch(tok->tokAt(-2), "std :: tie")) + const bool requireNonNull = settings.library.isnullargbad(tok, 1 + argnr); + if (argDirection == Library::ArgumentChecks::Direction::DIR_OUT || + argDirection == Library::ArgumentChecks::Direction::DIR_INOUT) { + if (indirect == 0 && isArray(tok1)) + return true; + const bool requireInit = settings.library.isuninitargbad(tok, 1 + argnr); + // Assume that if the variable must be initialized then the indirection is 1 + if (indirect > 0 && requireInit && requireNonNull) return true; - // if the library says 0 is invalid - // => it is assumed that parameter is an in parameter (TODO: this is a bad heuristic) - if (indirect == 0 && requireNonNull) - return false; } + if (Token::simpleMatch(tok->tokAt(-2), "std :: tie")) + return true; + // if the library says 0 is invalid + // => it is assumed that parameter is an in parameter (TODO: this is a bad heuristic) + if (indirect == 0 && requireNonNull) + return false; // possible pass-by-reference => inconclusive if (possiblyPassedByReference) { if (inconclusive != nullptr) @@ -2535,7 +2533,7 @@ bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Setti return false; } -bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, int depth) +bool isVariableChanged(const Token *tok, int indirect, const Settings &settings, int depth) { if (!tok) return false; @@ -2657,7 +2655,7 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, return false; } } - if ((settings && settings->library.isFunctionConst(ftok)) || (astIsSmartPointer(tok) && ftok->str() == "get")) // TODO: replace with action/yield? + if (settings.library.isFunctionConst(ftok) || (astIsSmartPointer(tok) && ftok->str() == "get")) // TODO: replace with action/yield? return false; const Function * fun = ftok->function(); @@ -2753,12 +2751,12 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, return false; } -bool isVariableChanged(const Token *start, const Token *end, const nonneg int exprid, bool globalvar, const Settings *settings, int depth) +bool isVariableChanged(const Token *start, const Token *end, const nonneg int exprid, bool globalvar, const Settings &settings, int depth) { return findVariableChanged(start, end, 0, exprid, globalvar, settings, depth) != nullptr; } -bool isVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, int depth) +bool isVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings &settings, int depth) { return findVariableChanged(start, end, indirect, exprid, globalvar, settings, depth) != nullptr; } @@ -2802,7 +2800,7 @@ static bool isExpressionChangedAt(const F& getExprTok, int indirect, const nonneg int exprid, bool globalvar, - const Settings* settings, + const Settings& settings, int depth) { if (depth < 0) @@ -2837,7 +2835,7 @@ bool isExpressionChangedAt(const Token* expr, const Token* tok, int indirect, bool globalvar, - const Settings* settings, + const Settings& settings, int depth) { return isExpressionChangedAt([&] { @@ -2845,7 +2843,7 @@ bool isExpressionChangedAt(const Token* expr, }, tok, indirect, expr->exprId(), globalvar, settings, depth); } -Token* findVariableChanged(Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, int depth) +Token* findVariableChanged(Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings &settings, int depth) { if (!precedes(start, end)) return nullptr; @@ -2861,12 +2859,12 @@ Token* findVariableChanged(Token *start, const Token *end, int indirect, const n return nullptr; } -const Token* findVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, int depth) +const Token* findVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings &settings, int depth) { return findVariableChanged(const_cast(start), end, indirect, exprid, globalvar, settings, depth); } -bool isVariableChanged(const Variable * var, const Settings *settings, int depth) +bool isVariableChanged(const Variable * var, const Settings &settings, int depth) { if (!var) return false; @@ -2889,7 +2887,7 @@ bool isVariablesChanged(const Token* start, const Token* end, int indirect, const std::vector &vars, - const Settings* settings) + const Settings& settings) { std::set varids; std::transform(vars.cbegin(), vars.cend(), std::inserter(varids, varids.begin()), [](const Variable* var) { @@ -2911,7 +2909,7 @@ bool isVariablesChanged(const Token* start, return false; } -bool isThisChanged(const Token* tok, int indirect, const Settings* settings) +bool isThisChanged(const Token* tok, int indirect, const Settings& settings) { if ((Token::Match(tok->previous(), "%name% (") && !Token::simpleMatch(tok->astOperand1(), ".")) || Token::Match(tok->tokAt(-3), "this . %name% (")) { @@ -2927,7 +2925,7 @@ bool isThisChanged(const Token* tok, int indirect, const Settings* settings) return false; } -const Token* findThisChanged(const Token* start, const Token* end, int indirect, const Settings* settings) +static const Token* findThisChanged(const Token* start, const Token* end, int indirect, const Settings& settings) { if (!precedes(start, end)) return nullptr; @@ -2944,7 +2942,7 @@ template static const Token* findExpressionChangedImpl(const Token* expr, const Token* start, const Token* end, - const Settings* settings, + const Settings& settings, int depth, Find find) { @@ -2977,9 +2975,10 @@ static const Token* findExpressionChangedImpl(const Token* expr, if (vt->type == ValueType::ITERATOR) ++indirect; } - for (int i = 0; i <= indirect; ++i) + for (int i = 0; i <= indirect; ++i) { if (isExpressionChangedAt(tok, tok2, i, global, settings, depth)) return true; + } return false; }); if (modifedTok) { @@ -3019,7 +3018,7 @@ namespace { const Token* findExpressionChanged(const Token* expr, const Token* start, const Token* end, - const Settings* settings, + const Settings& settings, int depth) { return findExpressionChangedImpl(expr, start, end, settings, depth, ExpressionChangedSimpleFind{}); @@ -3028,12 +3027,12 @@ const Token* findExpressionChanged(const Token* expr, const Token* findExpressionChangedSkipDeadCode(const Token* expr, const Token* start, const Token* end, - const Settings* settings, + const Settings& settings, const std::function(const Token* tok)>& evaluate, int depth) { return findExpressionChangedImpl( - expr, start, end, settings, depth, ExpressionChangedSkipDeadCode{settings->library, evaluate}); + expr, start, end, settings, depth, ExpressionChangedSkipDeadCode{settings.library, evaluate}); } const Token* getArgumentStart(const Token* ftok) @@ -3362,7 +3361,7 @@ ExprUsage getExprUsage(const Token* tok, int indirect, const Settings& settings) return ExprUsage::NotUsed; if (Token::simpleMatch(parent, ":") && Token::simpleMatch(parent->astParent(), "?")) return getExprUsage(parent->astParent(), indirect, settings); - if (isUsedAsBool(tok, &settings)) + if (isUsedAsBool(tok, settings)) return ExprUsage::NotUsed; } if (indirect == 0) { diff --git a/lib/astutils.h b/lib/astutils.h index 6426225253e..0543548ba89 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -212,7 +212,7 @@ const Token* getParentLifetime(const Token* tok); const Token* getParentLifetime(const Token* tok, const Library& library); std::vector getParentValueTypes(const Token* tok, - const Settings* settings = nullptr, + const Settings& settings, const Token** parent = nullptr); bool astIsLHS(const Token* tok); @@ -262,7 +262,7 @@ SmallVector followAllReferences(const Token* tok, int depth = 20); const Token* followReferences(const Token* tok, ErrorPath* errors = nullptr); -CPPCHECKLIB bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Library& library, bool pure, bool followVar, ErrorPath* errors=nullptr); +CPPCHECKLIB bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Settings& settings, bool pure, bool followVar, ErrorPath* errors=nullptr); bool isEqualKnownValue(const Token * const tok1, const Token * const tok2); @@ -273,7 +273,7 @@ const Token* isInLoopCondition(const Token* tok); /** * Is token used as boolean, that is to say cast to a bool, or used as a condition in a if/while/for */ -CPPCHECKLIB bool isUsedAsBool(const Token* const tok, const Settings* settings = nullptr); +CPPCHECKLIB bool isUsedAsBool(const Token* const tok, const Settings& settings); /** * Are the tokens' flags equal? @@ -285,12 +285,12 @@ bool compareTokenFlags(const Token* tok1, const Token* tok2, bool macro); * @param isNot do you want to know if cond1 is !cond2 or if cond1 and cond2 are non-overlapping. true: cond1==!cond2 false: cond1==true => cond2==false * @param cond1 condition1 * @param cond2 condition2 - * @param library files data + * @param settings settings * @param pure boolean */ -bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const cond2, const Library& library, bool pure, bool followVar, ErrorPath* errors=nullptr); +bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const cond2, const Settings& settings, bool pure, bool followVar, ErrorPath* errors=nullptr); -bool isOppositeExpression(const Token * const tok1, const Token * const tok2, const Library& library, bool pure, bool followVar, ErrorPath* errors=nullptr); +bool isOppositeExpression(const Token * const tok1, const Token * const tok2, const Settings& settings, bool pure, bool followVar, ErrorPath* errors=nullptr); bool isConstFunctionCall(const Token* ftok, const Library& library); @@ -328,7 +328,7 @@ std::vector getArgumentVars(const Token* tok, int argnr); * @param settings program settings * @param inconclusive pointer to output variable which indicates that the answer of the question is inconclusive */ -bool isVariableChangedByFunctionCall(const Token *tok, int indirect, nonneg int varid, const Settings *settings, bool *inconclusive); +bool isVariableChangedByFunctionCall(const Token *tok, int indirect, nonneg int varid, const Settings &settings, bool *inconclusive); /** Is variable changed by function call? * In case the answer of the question is inconclusive, e.g. because the function declaration is not known @@ -338,38 +338,37 @@ bool isVariableChangedByFunctionCall(const Token *tok, int indirect, nonneg int * @param settings program settings * @param inconclusive pointer to output variable which indicates that the answer of the question is inconclusive */ -CPPCHECKLIB bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Settings *settings, bool *inconclusive); +CPPCHECKLIB bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Settings &settings, bool *inconclusive); /** Is variable changed in block of code? */ -CPPCHECKLIB bool isVariableChanged(const Token *start, const Token *end, const nonneg int exprid, bool globalvar, const Settings *settings, int depth = 20); -bool isVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, int depth = 20); +CPPCHECKLIB bool isVariableChanged(const Token *start, const Token *end, const nonneg int exprid, bool globalvar, const Settings &settings, int depth = 20); +bool isVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings &settings, int depth = 20); -bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, int depth = 20); +bool isVariableChanged(const Token *tok, int indirect, const Settings &settings, int depth = 20); -bool isVariableChanged(const Variable * var, const Settings *settings, int depth = 20); +bool isVariableChanged(const Variable * var, const Settings &settings, int depth = 20); bool isVariablesChanged(const Token* start, const Token* end, int indirect, const std::vector &vars, - const Settings* settings); + const Settings& settings); -bool isThisChanged(const Token* tok, int indirect, const Settings* settings); -const Token* findThisChanged(const Token* start, const Token* end, int indirect, const Settings* settings); +bool isThisChanged(const Token* tok, int indirect, const Settings& settings); -const Token* findVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, int depth = 20); -Token* findVariableChanged(Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, int depth = 20); +const Token* findVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings &settings, int depth = 20); +Token* findVariableChanged(Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings &settings, int depth = 20); CPPCHECKLIB const Token* findExpressionChanged(const Token* expr, const Token* start, const Token* end, - const Settings* settings, + const Settings& settings, int depth = 20); const Token* findExpressionChangedSkipDeadCode(const Token* expr, const Token* start, const Token* end, - const Settings* settings, + const Settings& settings, const std::function(const Token* tok)>& evaluate, int depth = 20); @@ -377,7 +376,7 @@ bool isExpressionChangedAt(const Token* expr, const Token* tok, int indirect, bool globalvar, - const Settings* settings, + const Settings& settings, int depth = 20); /// If token is an alias if another variable diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index 17242326490..28e4e69a429 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -55,10 +55,10 @@ static bool isPtrArg(const Token *tok) return (var && var->isArgument() && var->isPointer()); } -static bool isArrayArg(const Token *tok, const Settings* settings) +static bool isArrayArg(const Token *tok, const Settings& settings) { const Variable *var = tok->variable(); - return (var && var->isArgument() && var->isArray() && !settings->library.isentrypoint(var->scope()->className)); + return (var && var->isArgument() && var->isArray() && !settings.library.isentrypoint(var->scope()->className)); } static bool isArrayVar(const Token *tok) @@ -290,7 +290,7 @@ void CheckAutoVariables::autoVariables() checkAutoVariableAssignment(tok->next(), inconclusive); tok = tok->tokAt(5); } else if (Token::Match(tok, "[;{}] %var% [") && Token::simpleMatch(tok->linkAt(2), "] =") && - (isPtrArg(tok->next()) || isArrayArg(tok->next(), mSettings)) && + (isPtrArg(tok->next()) || isArrayArg(tok->next(), *mSettings)) && isAutoVariableRHS(tok->linkAt(2)->next()->astOperand2())) { errorAutoVariableAssignment(tok->next(), false); } @@ -553,7 +553,7 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token for (const Token *tok = start; tok && tok != end; tok = tok->next()) { // Return reference from function if (returnRef && Token::simpleMatch(tok->astParent(), "return")) { - for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(tok, true)) { + for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(tok, *mSettings, true)) { if (!printInconclusive && lt.inconclusive) continue; const Variable* var = lt.token->variable(); @@ -573,14 +573,14 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token tok->variable()->declarationId() == tok->varId() && tok->variable()->isStatic() && !tok->variable()->isArgument()) { ErrorPath errorPath; - const Variable *var = ValueFlow::getLifetimeVariable(tok, errorPath); + const Variable *var = ValueFlow::getLifetimeVariable(tok, errorPath, *mSettings); if (var && isInScope(var->nameToken(), tok->scope())) { errorDanglingReference(tok, var, std::move(errorPath)); continue; } // Reference to temporary } else if (tok->variable() && (tok->variable()->isReference() || tok->variable()->isRValueReference())) { - for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(getParentLifetime(tok))) { + for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(getParentLifetime(tok), *mSettings)) { if (!printInconclusive && lt.inconclusive) continue; const Token * tokvalue = lt.token; @@ -601,7 +601,7 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token const Token* parent = getParentLifetime(val.tokvalue, mSettings->library); if (!exprs.insert(parent).second) continue; - for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(parent, escape || isAssignedToNonLocal(tok))) { + for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(parent, *mSettings, escape || isAssignedToNonLocal(tok))) { const Token * tokvalue = lt.token; if (val.isLocalLifetimeValue()) { if (escape) { @@ -650,7 +650,7 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token tok->scope()->bodyEnd, var->declarationId(), var->isGlobal(), - mSettings)) { + *mSettings)) { errorDanglngLifetime(tok2, &val); break; } diff --git a/lib/checkbool.cpp b/lib/checkbool.cpp index 609fc4c701a..238a5ce24d2 100644 --- a/lib/checkbool.cpp +++ b/lib/checkbool.cpp @@ -379,13 +379,13 @@ void CheckBool::checkComparisonOfBoolExpressionWithInt() if (astIsBool(numTok)) continue; - const ValueFlow::Value *minval = numTok->getValueLE(0, mSettings); + const ValueFlow::Value *minval = numTok->getValueLE(0, *mSettings); if (minval && minval->intvalue == 0 && (numInRhs ? Token::Match(tok, ">|==|!=") : Token::Match(tok, "<|==|!="))) minval = nullptr; - const ValueFlow::Value *maxval = numTok->getValueGE(1, mSettings); + const ValueFlow::Value *maxval = numTok->getValueGE(1, *mSettings); if (maxval && maxval->intvalue == 1 && (numInRhs ? Token::Match(tok, "<|==|!=") : Token::Match(tok, ">|==|!="))) @@ -506,7 +506,7 @@ void CheckBool::returnValueOfFunctionReturningBool() else if (tok->scope() && tok->scope()->isClassOrStruct()) tok = tok->scope()->bodyEnd; else if (Token::simpleMatch(tok, "return") && tok->astOperand1() && - (tok->astOperand1()->getValueGE(2, mSettings) || tok->astOperand1()->getValueLE(-1, mSettings)) && + (tok->astOperand1()->getValueGE(2, *mSettings) || tok->astOperand1()->getValueLE(-1, *mSettings)) && !(tok->astOperand1()->astOperand1() && Token::Match(tok->astOperand1(), "&|%or%"))) returnValueBoolError(tok); } diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 884ca51f2f3..5da7aa3ce5b 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -187,7 +187,7 @@ static int getMinFormatStringOutputLength(const std::vector ¶m //--------------------------------------------------------------------------- -static bool getDimensionsEtc(const Token * const arrayToken, const Settings *settings, std::vector &dimensions, ErrorPath &errorPath, bool &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, ".|::")) @@ -205,7 +205,7 @@ static bool getDimensionsEtc(const Token * const arrayToken, const Settings *set 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); @@ -220,7 +220,7 @@ static bool getDimensionsEtc(const Token * const arrayToken, const Settings *set Dimension dim; dim.known = value->isKnown(); dim.tok = nullptr; - const int typeSize = array->valueType()->typeSize(settings->platform, array->valueType()->pointer > 1); + const int typeSize = array->valueType()->typeSize(settings.platform, array->valueType()->pointer > 1); if (typeSize == 0) return false; dim.num = value->intvalue / typeSize; @@ -319,7 +319,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(); @@ -327,7 +327,7 @@ void CheckBufferOverrun::arrayIndex() const Token* changeTok = var->scope()->bodyStart; bool isChanged = false; while ((changeTok = findVariableChanged(changeTok->next(), var->scope()->bodyEnd, /*indirect*/ 0, var->declarationId(), - /*globalvar*/ false, mSettings))) { + /*globalvar*/ false, *mSettings))) { if (!Token::simpleMatch(changeTok->astParent(), "[")) { isChanged = true; break; @@ -349,7 +349,7 @@ void CheckBufferOverrun::arrayIndex() bool neg = false; std::vector negativeIndexes; for (const Token * indexToken : indexTokens) { - const ValueFlow::Value *negativeValue = indexToken->getValueLE(-1, mSettings); + const ValueFlow::Value *negativeValue = indexToken->getValueLE(-1, *mSettings); if (negativeValue) { negativeIndexes.emplace_back(*negativeValue); neg = true; @@ -493,7 +493,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() == "+") { @@ -506,7 +506,7 @@ void CheckBufferOverrun::pointerArithmetic() pointerArithmeticError(tok, indexToken, &indexValues.front()); } - if (const ValueFlow::Value *neg = indexToken->getValueLE(-1, mSettings)) + if (const ValueFlow::Value *neg = indexToken->getValueLE(-1, *mSettings)) pointerArithmeticError(tok, indexToken, neg); } else if (tok->str() == "-") { if (arrayToken->variable() && arrayToken->variable()->isArgument()) @@ -516,7 +516,7 @@ void CheckBufferOverrun::pointerArithmetic() while (Token::Match(array, ".|::")) array = array->astOperand2(); if (array->variable() && array->variable()->isArray()) { - const ValueFlow::Value *v = indexToken->getValueGE(1, mSettings); + const ValueFlow::Value *v = indexToken->getValueGE(1, *mSettings); if (v) pointerArithmeticError(tok, indexToken, v); } @@ -584,14 +584,14 @@ ValueFlow::Value CheckBufferOverrun::getBufferSize(const Token *bufTok) const } //--------------------------------------------------------------------------- -static bool checkBufferSize(const Token *ftok, const Library::ArgumentChecks::MinSize &minsize, const std::vector &args, const MathLib::bigint bufferSize, const Settings *settings, const Tokenizer* tokenizer) +static bool checkBufferSize(const Token *ftok, const Library::ArgumentChecks::MinSize &minsize, const std::vector &args, const MathLib::bigint bufferSize, const Settings &settings, const Tokenizer* tokenizer) { const Token * const arg = (minsize.arg > 0 && minsize.arg - 1 < args.size()) ? args[minsize.arg - 1] : nullptr; const Token * const arg2 = (minsize.arg2 > 0 && minsize.arg2 - 1 < args.size()) ? args[minsize.arg2 - 1] : nullptr; switch (minsize.type) { case Library::ArgumentChecks::MinSize::Type::STRLEN: - if (settings->library.isargformatstr(ftok, minsize.arg)) { + if (settings.library.isargformatstr(ftok, minsize.arg)) { return getMinFormatStringOutputLength(args, minsize.arg) < bufferSize; } else if (arg) { const Token *strtoken = arg->getValueTokenMaxStrLength(); @@ -678,7 +678,7 @@ void CheckBufferOverrun::bufferOverflow() } } const bool error = std::none_of(minsizes->begin(), minsizes->end(), [=](const Library::ArgumentChecks::MinSize &minsize) { - return checkBufferSize(tok, minsize, args, bufferSize.intvalue, mSettings, mTokenizer); + return checkBufferSize(tok, minsize, args, bufferSize.intvalue, *mSettings, mTokenizer); }); if (error) bufferOverflowError(args[argnr], &bufferSize, Certainty::normal); @@ -793,7 +793,7 @@ void CheckBufferOverrun::stringNotZeroTerminated() const Token *rhs = tok2->next()->astOperand2(); if (!rhs || !rhs->hasKnownIntValue() || rhs->getKnownIntValue() != 0) continue; - if (isSameExpression(false, args[0], tok2->link()->astOperand1(), mSettings->library, false, false)) + if (isSameExpression(false, args[0], tok2->link()->astOperand1(), *mSettings, false, false)) isZeroTerminated = true; } if (isZeroTerminated) @@ -1171,7 +1171,7 @@ void CheckBufferOverrun::negativeArraySize() const Token* const nameToken = var->nameToken(); if (!Token::Match(nameToken, "%var% [") || !nameToken->next()->astOperand2()) continue; - const ValueFlow::Value* sz = nameToken->next()->astOperand2()->getValueLE(-1, mSettings); + const ValueFlow::Value* sz = nameToken->next()->astOperand2()->getValueLE(-1, *mSettings); // don't warn about constant negative index because that is a compiler error if (sz && isVLAIndex(nameToken->next()->astOperand2())) negativeArraySizeError(nameToken); @@ -1184,7 +1184,7 @@ void CheckBufferOverrun::negativeArraySize() const Token* valOperand = tok->astOperand1()->astOperand2(); if (!valOperand) continue; - const ValueFlow::Value* sz = valOperand->getValueLE(-1, mSettings); + const ValueFlow::Value* sz = valOperand->getValueLE(-1, *mSettings); if (sz) negativeMemoryAllocationSizeError(tok, sz); } diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 7dc6c3f1468..6ae74d3d29a 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -983,7 +983,7 @@ void CheckClass::initializeVarList(const Function &func, std::listnext(); if (tok2->str() == "&") tok2 = tok2->next(); - if (isVariableChangedByFunctionCall(tok2, tok2->previous()->str() == "&", tok2->varId(), mSettings, nullptr)) + if (isVariableChangedByFunctionCall(tok2, tok2->previous()->str() == "&", tok2->varId(), *mSettings, nullptr)) assignVar(usage, tok2->varId()); } } diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index 3203bef3986..a4f82a0c615 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -200,7 +200,7 @@ bool CheckCondition::assignIfParseScope(const Token * const assignTok, // is variable changed in loop? const Token *bodyStart = tok2->linkAt(1)->next(); const Token *bodyEnd = bodyStart ? bodyStart->link() : nullptr; - if (!bodyEnd || bodyEnd->str() != "}" || isVariableChanged(bodyStart, bodyEnd, varid, !islocal, mSettings)) + if (!bodyEnd || bodyEnd->str() != "}" || isVariableChanged(bodyStart, bodyEnd, varid, !islocal, *mSettings)) continue; } @@ -435,7 +435,7 @@ bool CheckCondition::isOverlappingCond(const Token * const cond1, const Token * return false; // same expressions - if (isSameExpression(true, cond1, cond2, mSettings->library, pure, false)) + if (isSameExpression(true, cond1, cond2, *mSettings, pure, false)) return true; // bitwise overlap for example 'x&7' and 'x==1' @@ -458,7 +458,7 @@ bool CheckCondition::isOverlappingCond(const Token * const cond1, const Token * if (!num2->isNumber() || MathLib::isNegative(num2->str())) return false; - if (!isSameExpression(true, expr1, expr2, mSettings->library, pure, false)) + if (!isSameExpression(true, expr1, expr2, *mSettings, pure, false)) return false; const MathLib::bigint value1 = MathLib::toBigNumber(num1->str()); @@ -503,8 +503,8 @@ void CheckCondition::duplicateCondition() continue; ErrorPath errorPath; - if (!findExpressionChanged(cond1, scope.classDef->next(), cond2, mSettings) && - isSameExpression(true, cond1, cond2, mSettings->library, true, true, &errorPath)) + if (!findExpressionChanged(cond1, scope.classDef->next(), cond2, *mSettings) && + isSameExpression(true, cond1, cond2, *mSettings, true, true, &errorPath)) duplicateConditionError(cond1, cond2, std::move(errorPath)); } } @@ -553,11 +553,11 @@ void CheckCondition::multiCondition() if (tok2->astOperand2()) { ErrorPath errorPath; if (isOverlappingCond(cond1, tok2->astOperand2(), true) && - !findExpressionChanged(cond1, cond1, tok2->astOperand2(), mSettings)) + !findExpressionChanged(cond1, cond1, tok2->astOperand2(), *mSettings)) overlappingElseIfConditionError(tok2->astOperand2(), cond1->linenr()); else if (isOppositeCond( - true, cond1, tok2->astOperand2(), mSettings->library, true, true, &errorPath) && - !findExpressionChanged(cond1, cond1, tok2->astOperand2(), mSettings)) + true, cond1, tok2->astOperand2(), *mSettings, true, true, &errorPath) && + !findExpressionChanged(cond1, cond1, tok2->astOperand2(), *mSettings)) oppositeElseIfConditionError(cond1, tok2->astOperand2(), std::move(errorPath)); } } @@ -703,13 +703,13 @@ void CheckCondition::multiCondition2() const Token * const endToken = tok->scope()->bodyEnd; for (; tok && tok != endToken; tok = tok->next()) { - if (isExpressionChangedAt(cond1, tok, 0, false, mSettings)) + if (isExpressionChangedAt(cond1, tok, 0, false, *mSettings)) break; if (Token::Match(tok, "if|return")) { const Token * condStartToken = tok->str() == "if" ? tok->next() : tok; const Token * condEndToken = tok->str() == "if" ? condStartToken->link() : Token::findsimplematch(condStartToken, ";"); // Does condition modify tracked variables? - if (findExpressionChanged(cond1, condStartToken, condEndToken, mSettings)) + if (findExpressionChanged(cond1, condStartToken, condEndToken, *mSettings)) break; // Condition.. @@ -723,14 +723,14 @@ void CheckCondition::multiCondition2() if (!firstCondition) return ChildrenToVisit::none; if (firstCondition->str() == "&&") { - if (!isOppositeCond(false, firstCondition, cond2, mSettings->library, true, true)) + if (!isOppositeCond(false, firstCondition, cond2, *mSettings, true, true)) return ChildrenToVisit::op1_and_op2; } if (!firstCondition->hasKnownIntValue()) { - if (!isReturnVar && isOppositeCond(false, firstCondition, cond2, mSettings->library, true, true, &errorPath)) { + if (!isReturnVar && isOppositeCond(false, firstCondition, cond2, *mSettings, true, true, &errorPath)) { if (!isAliased(vars)) oppositeInnerConditionError(firstCondition, cond2, errorPath); - } else if (!isReturnVar && isSameExpression(true, firstCondition, cond2, mSettings->library, true, true, &errorPath)) { + } else if (!isReturnVar && isSameExpression(true, firstCondition, cond2, *mSettings, true, true, &errorPath)) { identicalInnerConditionError(firstCondition, cond2, errorPath); } } @@ -742,7 +742,7 @@ void CheckCondition::multiCondition2() return ChildrenToVisit::op1_and_op2; if ((!cond1->hasKnownIntValue() || !secondCondition->hasKnownIntValue()) && - isSameExpression(true, cond1, secondCondition, mSettings->library, true, true, &errorPath)) { + isSameExpression(true, cond1, secondCondition, *mSettings, true, true, &errorPath)) { if (!isAliased(vars) && !mTokenizer->hasIfdef(cond1, secondCondition)) { identicalConditionAfterEarlyExitError(cond1, secondCondition, errorPath); return ChildrenToVisit::done; @@ -753,7 +753,7 @@ void CheckCondition::multiCondition2() } } if (Token::Match(tok, "%name% (") && - isVariablesChanged(tok, tok->linkAt(1), 0, varsInCond, mSettings)) { + isVariablesChanged(tok, tok->linkAt(1), 0, varsInCond, *mSettings)) { break; } if (Token::Match(tok, "%type% (") && nonlocal && isNonConstFunctionCall(tok, mSettings->library)) // non const function call -> bailout if there are nonlocal variables @@ -782,7 +782,7 @@ void CheckCondition::multiCondition2() break; } const bool changed = std::any_of(vars.cbegin(), vars.cend(), [&](int varid) { - return isVariableChanged(tok1, tok2, varid, nonlocal, mSettings); + return isVariableChanged(tok1, tok2, varid, nonlocal, *mSettings); }); if (changed) break; @@ -1145,7 +1145,7 @@ void CheckCondition::checkIncorrectLogicOperator() ((tok->str() == "||" && tok->astOperand2()->str() == "&&") || (tok->str() == "&&" && tok->astOperand2()->str() == "||"))) { const Token* tok2 = tok->astOperand2()->astOperand1(); - if (isOppositeCond(true, tok->astOperand1(), tok2, mSettings->library, true, false)) { + if (isOppositeCond(true, tok->astOperand1(), tok2, *mSettings, true, false)) { std::string expr1(tok->astOperand1()->expressionString()); std::string expr2(tok->astOperand2()->astOperand1()->expressionString()); std::string expr3(tok->astOperand2()->astOperand2()->expressionString()); @@ -1177,7 +1177,7 @@ void CheckCondition::checkIncorrectLogicOperator() redundantConditionError(tok, msg, false); continue; } - if (isSameExpression(false, tok->astOperand1(), tok2, mSettings->library, true, true)) { + if (isSameExpression(false, tok->astOperand1(), tok2, *mSettings, true, true)) { std::string expr1(tok->astOperand1()->expressionString()); std::string expr2(tok->astOperand2()->astOperand1()->expressionString()); std::string expr3(tok->astOperand2()->astOperand2()->expressionString()); @@ -1242,7 +1242,7 @@ void CheckCondition::checkIncorrectLogicOperator() // Opposite comparisons around || or && => always true or always false const bool isLogicalOr(tok->str() == "||"); - if (!isfloat && isOppositeCond(isLogicalOr, tok->astOperand1(), tok->astOperand2(), mSettings->library, true, true, &errorPath)) { + if (!isfloat && isOppositeCond(isLogicalOr, tok->astOperand1(), tok->astOperand2(), *mSettings, true, true, &errorPath)) { if (!isIfConstexpr(tok)) { const bool alwaysTrue(isLogicalOr); incorrectLogicOperatorError(tok, conditionString(tok), alwaysTrue, inconclusive, errorPath); @@ -1253,9 +1253,9 @@ void CheckCondition::checkIncorrectLogicOperator() if (!parseable) continue; - if (isSameExpression(true, comp1, comp2, mSettings->library, true, true)) + if (isSameExpression(true, comp1, comp2, *mSettings, true, true)) continue; // same expressions => only report that there are same expressions - if (!isSameExpression(true, expr1, expr2, mSettings->library, true, true)) + if (!isSameExpression(true, expr1, expr2, *mSettings, true, true)) continue; @@ -1530,7 +1530,7 @@ void CheckCondition::alwaysTrueFalse() continue; if (condition->isConstexpr()) continue; - if (!isUsedAsBool(tok)) + if (!isUsedAsBool(tok, *mSettings)) continue; if (Token::simpleMatch(condition, "return") && Token::Match(tok, "%assign%")) continue; @@ -1559,7 +1559,7 @@ void CheckCondition::alwaysTrueFalse() isSameExpression(true, tok->astOperand1(), tok->astOperand2(), - mSettings->library, + *mSettings, true, true)) continue; @@ -1687,7 +1687,7 @@ void CheckCondition::checkInvalidTestForOverflow() if (!isSameExpression(true, expr, lhs->astSibling(), - mSettings->library, + *mSettings, true, false)) continue; @@ -1834,10 +1834,10 @@ void CheckCondition::checkDuplicateConditionalAssign() isRedundant = (isNegation && val == 0) || (!isNegation && val == 1); } else { // comparison if (!isSameExpression( - true, condTok->astOperand1(), assignTok->astOperand1(), mSettings->library, true, true)) + true, condTok->astOperand1(), assignTok->astOperand1(), *mSettings, true, true)) continue; if (!isSameExpression( - true, condTok->astOperand2(), assignTok->astOperand2(), mSettings->library, true, true)) + true, condTok->astOperand2(), assignTok->astOperand2(), *mSettings, true, true)) continue; } duplicateConditionalAssignError(condTok, assignTok, isRedundant); diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index bfc370faefe..d5494a3a034 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -115,7 +115,7 @@ void CheckFunctions::invalidFunctionUsage() const Token * const argtok = arguments[argnr-1]; // check ... - const ValueFlow::Value *invalidValue = argtok->getInvalidValue(functionToken,argnr,mSettings); + const ValueFlow::Value *invalidValue = argtok->getInvalidValue(functionToken,argnr,*mSettings); if (invalidValue) { invalidFunctionArgError(argtok, functionToken->next()->astOperand1()->expressionString(), argnr, invalidValue, mSettings->library.validarg(functionToken, argnr)); } @@ -148,7 +148,7 @@ void CheckFunctions::invalidFunctionUsage() // Is non-null terminated local variable of type char (e.g. char buf[] = {'x'};) ? if (variable && variable->isLocal() && valueType && (valueType->type == ValueType::Type::CHAR || valueType->type == ValueType::Type::WCHAR_T) - && !isVariablesChanged(variable->declEndToken(), functionToken, 0 /*indirect*/, { variable }, mSettings)) { + && !isVariablesChanged(variable->declEndToken(), functionToken, 0 /*indirect*/, { variable }, *mSettings)) { const Token* varTok = variable->declEndToken(); auto count = -1; // Find out explicitly set count, e.g.: char buf[3] = {...}. Variable 'count' is set to 3 then. if (varTok && Token::simpleMatch(varTok->astOperand1(), "[")) diff --git a/lib/checkio.cpp b/lib/checkio.cpp index cd919537b75..dbba502d743 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -696,9 +696,9 @@ void CheckIO::checkFormatString(const Token * const tok, } // Perform type checks - ArgumentInfo argInfo(argListTok, mSettings, mTokenizer->isCPP()); + ArgumentInfo argInfo(argListTok, *mSettings, mTokenizer->isCPP()); - if ((argInfo.typeToken && !argInfo.isLibraryType(mSettings)) || *i == ']') { + if ((argInfo.typeToken && !argInfo.isLibraryType(*mSettings)) || *i == ']') { if (scan) { std::string specifier; bool done = false; @@ -1342,7 +1342,7 @@ void CheckIO::checkFormatString(const Token * const tok, // We currently only support string literals, variables, and functions. /// @todo add non-string literals, and generic expressions -CheckIO::ArgumentInfo::ArgumentInfo(const Token * arg, const Settings *settings, bool _isCPP) +CheckIO::ArgumentInfo::ArgumentInfo(const Token * arg, const Settings &settings, bool _isCPP) : isCPP(_isCPP) { if (!arg) @@ -1486,12 +1486,12 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * arg, const Settings *settings, tempToken = new Token(tok1); if (tok1->next()->str() == "size") { // size_t is platform dependent - if (settings->platform.sizeof_size_t == 8) { + if (settings.platform.sizeof_size_t == 8) { tempToken->str("long"); - if (settings->platform.sizeof_long != 8) + if (settings.platform.sizeof_long != 8) tempToken->isLong(true); - } else if (settings->platform.sizeof_size_t == 4) { - if (settings->platform.sizeof_long == 4) { + } else if (settings.platform.sizeof_size_t == 4) { + if (settings.platform.sizeof_long == 4) { tempToken->str("long"); } else { tempToken->str("int"); @@ -1699,9 +1699,9 @@ bool CheckIO::ArgumentInfo::isKnownType() const return typeToken->isStandardType() || Token::Match(typeToken, "std :: string|wstring"); } -bool CheckIO::ArgumentInfo::isLibraryType(const Settings *settings) const +bool CheckIO::ArgumentInfo::isLibraryType(const Settings &settings) const { - return typeToken && typeToken->isStandardType() && settings->library.podtype(typeToken->str()); + return typeToken && typeToken->isStandardType() && settings.library.podtype(typeToken->str()); } void CheckIO::wrongPrintfScanfArgumentsError(const Token* tok, diff --git a/lib/checkio.h b/lib/checkio.h index cdc6b5e0e32..9ad6c6f2a50 100644 --- a/lib/checkio.h +++ b/lib/checkio.h @@ -75,7 +75,7 @@ class CPPCHECKLIB CheckIO : public Check { class ArgumentInfo { public: - ArgumentInfo(const Token *arg, const Settings *settings, bool _isCPP); + ArgumentInfo(const Token *arg, const Settings &settings, bool _isCPP); ~ArgumentInfo(); ArgumentInfo(const ArgumentInfo &) = delete; @@ -86,7 +86,7 @@ class CPPCHECKLIB CheckIO : public Check { bool isKnownType() const; bool isStdVectorOrString(); bool isStdContainer(const Token *tok); - bool isLibraryType(const Settings *settings) const; + bool isLibraryType(const Settings &settings) const; const Variable* variableInfo{}; const Token* typeToken{}; diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index de06c9f28aa..f68b26eb5b9 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -1097,7 +1097,7 @@ void CheckLeakAutoVar::leakIfAllocated(const Token *vartok, } } -static const Token* getOutparamAllocation(const Token* tok, const Settings* settings) +static const Token* getOutparamAllocation(const Token* tok, const Settings& settings) { if (!tok) return nullptr; @@ -1105,7 +1105,7 @@ static const Token* getOutparamAllocation(const Token* tok, const Settings* sett const Token* ftok = getTokenArgumentFunction(tok, argn); if (!ftok) return nullptr; - if (const Library::AllocFunc* allocFunc = settings->library.getAllocFuncInfo(ftok)) { + if (const Library::AllocFunc* allocFunc = settings.library.getAllocFuncInfo(ftok)) { if (allocFunc->arg == argn + 1) return ftok; } @@ -1168,7 +1168,7 @@ void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndO // don't warn when returning after checking return value of outparam allocation const Token* outparamFunc{}; if ((tok->scope()->type == Scope::ScopeType::eIf || tok->scope()->type== Scope::ScopeType::eElse) && - (outparamFunc = getOutparamAllocation(it->second.allocTok, mSettings))) { + (outparamFunc = getOutparamAllocation(it->second.allocTok, *mSettings))) { const Scope* scope = tok->scope(); if (scope->type == Scope::ScopeType::eElse) { scope = scope->bodyStart->tokAt(-2)->scope(); diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 171437a20db..801c2b70fcb 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -497,7 +497,7 @@ void CheckOther::checkRedundantAssignment() if (inconclusive && !mSettings->certainty.isEnabled(Certainty::inconclusive)) continue; - FwdAnalysis fwdAnalysis(mSettings->library); + FwdAnalysis fwdAnalysis(*mSettings); if (fwdAnalysis.hasOperand(tok->astOperand2(), tok->astOperand1())) continue; @@ -904,7 +904,7 @@ void CheckOther::redundantContinueError(const Token *tok) "'continue' is redundant since it is the last statement in a loop.", CWE561, Certainty::normal); } -static bool isSimpleExpr(const Token* tok, const Variable* var, const Settings* settings) { +static bool isSimpleExpr(const Token* tok, const Variable* var, const Settings& settings) { if (!tok) return false; if (tok->isNumber() || tok->tokType() == Token::eString || tok->tokType() == Token::eChar || tok->isBoolean()) @@ -913,7 +913,7 @@ static bool isSimpleExpr(const Token* tok, const Variable* var, const Settings* if (!needsCheck) { const Token* ftok = tok->previous(); if (Token::Match(ftok, "%name% (") && - ((ftok->function() && ftok->function()->isConst()) || settings->library.isFunctionConst(ftok->str(), /*pure*/ true))) + ((ftok->function() && ftok->function()->isConst()) || settings.library.isFunctionConst(ftok->str(), /*pure*/ true))) needsCheck = true; if (tok->isArithmeticalOp() && (!tok->astOperand1() || isSimpleExpr(tok->astOperand1(), var, settings)) && @@ -984,7 +984,7 @@ void CheckOther::checkVariableScope() bool isConstructor = false; if (Token::Match(tok, "; %varid% =", var->declarationId())) { // bailout for assignment tok = tok->tokAt(2)->astOperand2(); - if (!isSimpleExpr(tok, var, mSettings)) + if (!isSimpleExpr(tok, var, *mSettings)) continue; } else if (Token::Match(tok, "{|(")) { // bailout for constructor @@ -993,11 +993,11 @@ void CheckOther::checkVariableScope() bool bail = false; while (argTok) { if (Token::simpleMatch(argTok, ",")) { - if (!isSimpleExpr(argTok->astOperand2(), var, mSettings)) { + if (!isSimpleExpr(argTok->astOperand2(), var, *mSettings)) { bail = true; break; } - } else if (argTok->str() != "." && !isSimpleExpr(argTok, var, mSettings)) { + } else if (argTok->str() != "." && !isSimpleExpr(argTok, var, *mSettings)) { bail = true; break; } @@ -1262,7 +1262,7 @@ void CheckOther::checkPassByReference() if (!isRangeBasedFor && (!var->scope() || var->scope()->function->isImplicitlyVirtual())) continue; - if (!isVariableChanged(var, mSettings)) { + if (!isVariableChanged(var, *mSettings)) { passedByValueError(var, inconclusive, isRangeBasedFor); } } @@ -1364,7 +1364,7 @@ void CheckOther::checkConstVariable() continue; if (isStructuredBindingVariable(var)) // TODO: check all bound variables continue; - if (isVariableChanged(var, mSettings)) + if (isVariableChanged(var, *mSettings)) continue; const bool hasFunction = function != nullptr; if (!hasFunction) { @@ -1384,7 +1384,7 @@ void CheckOther::checkConstVariable() retTok = retTok->astOperand2(); if (Token::simpleMatch(retTok, "&")) retTok = retTok->astOperand1(); - return ValueFlow::hasLifetimeToken(getParentLifetime(retTok), var->nameToken()); + return ValueFlow::hasLifetimeToken(getParentLifetime(retTok), var->nameToken(), *mSettings); })) continue; } @@ -1416,7 +1416,7 @@ void CheckOther::checkConstVariable() continue; } else if (const Token* ftok = getTokenArgumentFunction(tok, argn)) { bool inconclusive{}; - if (var->valueType() && !isVariableChangedByFunctionCall(ftok, var->valueType()->pointer, var->declarationId(), mSettings, &inconclusive) && !inconclusive) + if (var->valueType() && !isVariableChangedByFunctionCall(ftok, var->valueType()->pointer, var->declarationId(), *mSettings, &inconclusive) && !inconclusive) continue; } usedInAssignment = true; @@ -1554,7 +1554,7 @@ void CheckOther::checkConstPointer() continue; else if (const Token* ftok = getTokenArgumentFunction(parent, argn)) { bool inconclusive{}; - if (!isVariableChangedByFunctionCall(ftok->next(), vt->pointer, var->declarationId(), mSettings, &inconclusive) && !inconclusive) + if (!isVariableChangedByFunctionCall(ftok->next(), vt->pointer, var->declarationId(), *mSettings, &inconclusive) && !inconclusive) continue; } } else { @@ -1572,7 +1572,7 @@ void CheckOther::checkConstPointer() const Variable* argVar = ftok->function()->getArgumentVar(argn); if (argVar && argVar->valueType() && argVar->valueType()->isConst(vt->pointer)) { bool inconclusive{}; - if (!isVariableChangedByFunctionCall(ftok, vt->pointer, var->declarationId(), mSettings, &inconclusive) && !inconclusive) + if (!isVariableChangedByFunctionCall(ftok, vt->pointer, var->declarationId(), *mSettings, &inconclusive) && !inconclusive) continue; } } @@ -1600,7 +1600,7 @@ void CheckOther::checkConstPointer() if (std::find(nonConstPointers.cbegin(), nonConstPointers.cend(), p) == nonConstPointers.cend()) { const Token *start = getVariableChangedStart(p); const int indirect = p->isArray() ? p->dimensions().size() : 1; - if (isVariableChanged(start, p->scope()->bodyEnd, indirect, p->declarationId(), false, mSettings)) + if (isVariableChanged(start, p->scope()->bodyEnd, indirect, p->declarationId(), false, *mSettings)) continue; if (p->typeStartToken() && p->typeStartToken()->isSimplifiedTypedef() && !(Token::simpleMatch(p->typeEndToken(), "*") && !p->typeEndToken()->isSimplifiedTypedef())) continue; @@ -1665,24 +1665,24 @@ void CheckOther::checkCharVariable() if (!tok->variable()->isArray() && !tok->variable()->isPointer()) continue; const Token *index = tok->next()->astOperand2(); - if (warning && tok->variable()->isArray() && astIsSignedChar(index) && index->getValueGE(0x80, mSettings)) + if (warning && tok->variable()->isArray() && astIsSignedChar(index) && index->getValueGE(0x80, *mSettings)) signedCharArrayIndexError(tok); - if (portability && astIsUnknownSignChar(index) && index->getValueGE(0x80, mSettings)) + if (portability && astIsUnknownSignChar(index) && index->getValueGE(0x80, *mSettings)) unknownSignCharArrayIndexError(tok); } else if (warning && Token::Match(tok, "[&|^]") && tok->isBinaryOp()) { bool warn = false; if (astIsSignedChar(tok->astOperand1())) { - const ValueFlow::Value *v1 = tok->astOperand1()->getValueLE(-1, mSettings); + const ValueFlow::Value *v1 = tok->astOperand1()->getValueLE(-1, *mSettings); const ValueFlow::Value *v2 = tok->astOperand2()->getMaxValue(false); if (!v1) - v1 = tok->astOperand1()->getValueGE(0x80, mSettings); + v1 = tok->astOperand1()->getValueGE(0x80, *mSettings); if (v1 && !(tok->str() == "&" && v2 && v2->isKnown() && v2->intvalue >= 0 && v2->intvalue < 0x100)) warn = true; } else if (astIsSignedChar(tok->astOperand2())) { - const ValueFlow::Value *v1 = tok->astOperand2()->getValueLE(-1, mSettings); + const ValueFlow::Value *v1 = tok->astOperand2()->getValueLE(-1, *mSettings); const ValueFlow::Value *v2 = tok->astOperand1()->getMaxValue(false); if (!v1) - v1 = tok->astOperand2()->getValueGE(0x80, mSettings); + v1 = tok->astOperand2()->getValueGE(0x80, *mSettings); if (v1 && !(tok->str() == "&" && v2 && v2->isKnown() && v2->intvalue >= 0 && v2->intvalue < 0x100)) warn = true; } @@ -2242,8 +2242,8 @@ void CheckOther::checkDuplicateBranch() if (branchTop1->str() != branchTop2->str()) continue; ErrorPath errorPath; - if (isSameExpression(false, branchTop1->astOperand1(), branchTop2->astOperand1(), mSettings->library, true, true, &errorPath) && - isSameExpression(false, branchTop1->astOperand2(), branchTop2->astOperand2(), mSettings->library, true, true, &errorPath)) + if (isSameExpression(false, branchTop1->astOperand1(), branchTop2->astOperand1(), *mSettings, true, true, &errorPath) && + isSameExpression(false, branchTop1->astOperand2(), branchTop2->astOperand2(), *mSettings, true, true, &errorPath)) duplicateBranchError(scope.classDef, scope.bodyEnd->next(), std::move(errorPath)); } } @@ -2431,8 +2431,8 @@ void CheckOther::checkDuplicateExpression() Token::Match(tok->astOperand2()->previous(), "%name% (") ) && tok->next()->tokType() != Token::eType && - isSameExpression(true, tok->next(), nextAssign->next(), mSettings->library, true, false) && - isSameExpression(true, tok->astOperand2(), nextAssign->astOperand2(), mSettings->library, true, false) && + isSameExpression(true, tok->next(), nextAssign->next(), *mSettings, true, false) && + isSameExpression(true, tok->astOperand2(), nextAssign->astOperand2(), *mSettings, true, false) && tok->astOperand2()->expressionString() == nextAssign->astOperand2()->expressionString()) { bool differentDomain = false; const Scope * varScope = var1->scope() ? var1->scope() : scope; @@ -2449,7 +2449,7 @@ void CheckOther::checkDuplicateExpression() !isSameExpression(true, tok->astOperand2(), assignTok->astOperand1(), - mSettings->library, + *mSettings, true, true)) continue; @@ -2458,7 +2458,7 @@ void CheckOther::checkDuplicateExpression() !isSameExpression(true, tok->astOperand2(), assignTok->astOperand2(), - mSettings->library, + *mSettings, true, true)) continue; @@ -2488,14 +2488,14 @@ void CheckOther::checkDuplicateExpression() if (isSameExpression(true, tok->astOperand1(), tok->astOperand2(), - mSettings->library, + *mSettings, true, followVar, &errorPath)) { if (isWithoutSideEffects(tok->astOperand1())) { const Token* loopTok = isInLoopCondition(tok); if (!loopTok || - !findExpressionChanged(tok, tok, loopTok->link()->next()->link(), mSettings)) { + !findExpressionChanged(tok, tok, loopTok->link()->next()->link(), *mSettings)) { const bool isEnum = tok->scope()->type == Scope::eEnum; const bool assignment = !isEnum && tok->str() == "="; if (assignment) @@ -2518,7 +2518,7 @@ void CheckOther::checkDuplicateExpression() isSameExpression(false, tok->astOperand1(), tok->astOperand2()->astOperand1(), - mSettings->library, + *mSettings, true, false)) { if (isWithoutSideEffects(tok->astOperand1())) { @@ -2526,7 +2526,7 @@ void CheckOther::checkDuplicateExpression() } } else if (isOppositeExpression(tok->astOperand1(), tok->astOperand2(), - mSettings->library, + *mSettings, false, true, &errorPath) && @@ -2538,7 +2538,7 @@ void CheckOther::checkDuplicateExpression() isSameExpression(true, tok->astOperand2(), tok->astOperand1()->astOperand2(), - mSettings->library, + *mSettings, true, followVar, &errorPath) && @@ -2546,7 +2546,7 @@ void CheckOther::checkDuplicateExpression() duplicateExpressionError(tok->astOperand2(), tok->astOperand1()->astOperand2(), tok, errorPath); else if (tok->astOperand2() && isConstExpression(tok->astOperand1(), mSettings->library)) { auto checkDuplicate = [&](const Token* exp1, const Token* exp2, const Token* ast1) { - if (isSameExpression(true, exp1, exp2, mSettings->library, true, true, &errorPath) && + if (isSameExpression(true, exp1, exp2, *mSettings, true, true, &errorPath) && isWithoutSideEffects(exp1) && isWithoutSideEffects(ast1->astOperand2())) duplicateExpressionError(exp1, exp2, tok, errorPath, /*hasMultipleExpr*/ true); @@ -2562,10 +2562,10 @@ void CheckOther::checkDuplicateExpression() } } else if (tok->astOperand1() && tok->astOperand2() && tok->str() == ":" && tok->astParent() && tok->astParent()->str() == "?") { if (!tok->astOperand1()->values().empty() && !tok->astOperand2()->values().empty() && isEqualKnownValue(tok->astOperand1(), tok->astOperand2()) && - !isVariableChanged(tok->astParent(), /*indirect*/ 0, mSettings) && + !isVariableChanged(tok->astParent(), /*indirect*/ 0, *mSettings) && isConstStatement(tok->astOperand1()) && isConstStatement(tok->astOperand2())) duplicateValueTernaryError(tok); - else if (isSameExpression(true, tok->astOperand1(), tok->astOperand2(), mSettings->library, false, true, &errorPath)) + else if (isSameExpression(true, tok->astOperand1(), tok->astOperand2(), *mSettings, false, true, &errorPath)) duplicateExpressionTernaryError(tok, std::move(errorPath)); } } @@ -2842,7 +2842,7 @@ void CheckOther::checkRedundantCopy() for (const Variable* var : symbolDatabase->variableList()) { if (!var || var->isReference() || var->isPointer() || (!var->type() && !var->isStlType()) || // bailout if var is of standard type, if it is a pointer or non-const - (!var->isConst() && isVariableChanged(var, mSettings))) + (!var->isConst() && isVariableChanged(var, *mSettings))) continue; const Token* startTok = var->nameToken(); @@ -2867,7 +2867,7 @@ void CheckOther::checkRedundantCopy() const Token* dot = tok->astOperand1(); if (Token::simpleMatch(dot, ".")) { - if (dot->astOperand1() && isVariableChanged(dot->astOperand1()->variable(), mSettings)) + if (dot->astOperand1() && isVariableChanged(dot->astOperand1()->variable(), *mSettings)) continue; if (isTemporary(dot, &mSettings->library, /*unknown*/ true)) continue; @@ -2904,7 +2904,7 @@ void CheckOther::redundantCopyError(const Token *tok,const std::string& varname) // Checking for shift by negative values //--------------------------------------------------------------------------- -static bool isNegative(const Token *tok, const Settings *settings) +static bool isNegative(const Token *tok, const Settings &settings) { return tok->valueType() && tok->valueType()->sign == ValueType::SIGNED && tok->getValueLE(-1LL, settings); } @@ -2941,9 +2941,9 @@ void CheckOther::checkNegativeBitwiseShift() continue; // Get negative rhs value. preferably a value which doesn't have 'condition'. - if (portability && isNegative(tok->astOperand1(), mSettings)) + if (portability && isNegative(tok->astOperand1(), *mSettings)) negativeBitwiseShiftError(tok, 1); - else if (isNegative(tok->astOperand2(), mSettings)) + else if (isNegative(tok->astOperand2(), *mSettings)) negativeBitwiseShiftError(tok, 2); } } @@ -3301,9 +3301,9 @@ void CheckOther::checkEvaluationOrder() if (tok2 == tok && tok->str() == "=" && parent->str() == "=" && - isSameExpression(false, tok->astOperand1(), parent->astOperand1(), mSettings->library, true, false)) { + isSameExpression(false, tok->astOperand1(), parent->astOperand1(), *mSettings, true, false)) { if (mSettings->severity.isEnabled(Severity::warning) && - isSameExpression(true, tok->astOperand1(), parent->astOperand1(), mSettings->library, true, false)) + isSameExpression(true, tok->astOperand1(), parent->astOperand1(), *mSettings, true, false)) selfAssignmentError(parent, tok->astOperand1()->expressionString()); break; } @@ -3316,7 +3316,7 @@ void CheckOther::checkEvaluationOrder() return ChildrenToVisit::none; // don't handle address-of for now if (tok3->str() == "(" && Token::simpleMatch(tok3->previous(), "sizeof")) return ChildrenToVisit::none; // don't care about sizeof usage - if (isSameExpression(false, tok->astOperand1(), tok3, mSettings->library, true, false)) + if (isSameExpression(false, tok->astOperand1(), tok3, *mSettings, true, false)) foundError = true; return foundError ? ChildrenToVisit::done : ChildrenToVisit::op1_and_op2; }); @@ -3371,7 +3371,7 @@ void CheckOther::checkAccessOfMovedVariable() if (usage == ExprUsage::Used) accessOfMoved = true; if (usage == ExprUsage::PassedByReference) - accessOfMoved = !isVariableChangedByFunctionCall(tok, 0, mSettings, &inconclusive); + accessOfMoved = !isVariableChangedByFunctionCall(tok, 0, *mSettings, &inconclusive); else if (usage == ExprUsage::Inconclusive) inconclusive = true; } @@ -3673,7 +3673,7 @@ void CheckOther::checkKnownArgument() continue; if (tok->isComparisonOp() && isSameExpression( - true, tok->astOperand1(), tok->astOperand2(), mSettings->library, true, true)) + true, tok->astOperand1(), tok->astOperand2(), *mSettings, true, true)) continue; // ensure that there is a integer variable in expression with unknown value const Token* vartok = nullptr; @@ -3759,7 +3759,7 @@ void CheckOther::checkKnownPointerToBool() return parent->isExpandedMacro(); })) continue; - if (!isUsedAsBool(tok, mSettings)) + if (!isUsedAsBool(tok, *mSettings)) continue; const ValueFlow::Value& value = tok->values().front(); knownPointerToBoolError(tok, &value); @@ -3966,7 +3966,7 @@ void CheckOther::checkOverlappingWrite() constexpr bool macro = true; constexpr bool pure = true; constexpr bool follow = true; - if (!isSameExpression(macro, ptr1, ptr2, mSettings->library, pure, follow, &errorPath)) + if (!isSameExpression(macro, ptr1, ptr2, *mSettings, pure, follow, &errorPath)) continue; overlappingWriteFunction(tok); } @@ -3991,7 +3991,7 @@ void CheckOther::checkOverlappingWrite() constexpr bool macro = true; constexpr bool pure = true; constexpr bool follow = true; - if (!isSameExpression(macro, buf1, buf2, mSettings->library, pure, follow, &errorPath)) + if (!isSameExpression(macro, buf1, buf2, *mSettings, pure, follow, &errorPath)) continue; overlappingWriteFunction(tok); } diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index e581a36fc47..2a7efc132e9 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -178,7 +178,7 @@ void CheckStl::outOfBounds() } if (indexTok && !indexTok->hasKnownIntValue()) { const ValueFlow::Value* value = - ValueFlow::findValue(indexTok->values(), mSettings, [&](const ValueFlow::Value& v) { + ValueFlow::findValue(indexTok->values(), *mSettings, [&](const ValueFlow::Value& v) { if (!v.isSymbolicValue()) return false; if (v.isImpossible()) @@ -283,7 +283,7 @@ bool CheckStl::isContainerSize(const Token *containerToken, const Token *expr) c return false; if (!Token::Match(expr->astOperand1(), ". %name% (")) return false; - if (!isSameExpression(false, containerToken, expr->astOperand1()->astOperand1(), mSettings->library, false, false)) + if (!isSameExpression(false, containerToken, expr->astOperand1()->astOperand1(), *mSettings, false, false)) return false; return containerToken->valueType()->container->getYield(expr->previous()->str()) == Library::Container::Yield::SIZE; } @@ -312,7 +312,7 @@ bool CheckStl::isContainerSizeGE(const Token * containerToken, const Token *expr op = expr->astOperand1(); else return false; - return op && op->getValueGE(0, mSettings); + return op && op->getValueGE(0, *mSettings); } return false; } @@ -705,11 +705,11 @@ static std::vector getAddressContainer(const Token* tok) static bool isSameIteratorContainerExpression(const Token* tok1, const Token* tok2, - const Library& library, + const Settings& settings, ValueFlow::Value::LifetimeKind kind = ValueFlow::Value::LifetimeKind::Iterator) { - if (isSameExpression(false, tok1, tok2, library, false, false)) { - return !astIsContainerOwned(tok1) || !isTemporary(tok1, &library); + if (isSameExpression(false, tok1, tok2, settings, false, false)) { + return !astIsContainerOwned(tok1) || !isTemporary(tok1, &settings.library); } if (astContainerYield(tok2) == Library::Container::Yield::ITEM) return true; @@ -718,7 +718,7 @@ static bool isSameIteratorContainerExpression(const Token* tok1, const auto address2 = getAddressContainer(tok2); return std::any_of(address1.begin(), address1.end(), [&](const Token* tok1) { return std::any_of(address2.begin(), address2.end(), [&](const Token* tok2) { - return isSameExpression(false, tok1, tok2, library, false, false); + return isSameExpression(false, tok1, tok2, settings, false, false); }); }); } @@ -756,7 +756,7 @@ bool CheckStl::checkIteratorPair(const Token* tok1, const Token* tok2) (!astIsContainer(val1.tokvalue) || !astIsContainer(val2.tokvalue))) return false; } - if (isSameIteratorContainerExpression(val1.tokvalue, val2.tokvalue, mSettings->library, val1.lifetimeKind)) + if (isSameIteratorContainerExpression(val1.tokvalue, val2.tokvalue, *mSettings, val1.lifetimeKind)) return false; if (val1.tokvalue->expressionString() == val2.tokvalue->expressionString()) iteratorsError(tok1, val1.tokvalue, val1.tokvalue->expressionString()); @@ -772,7 +772,7 @@ bool CheckStl::checkIteratorPair(const Token* tok1, const Token* tok2) } const Token* iter1 = getIteratorExpression(tok1); const Token* iter2 = getIteratorExpression(tok2); - if (iter1 && iter2 && !isSameIteratorContainerExpression(iter1, iter2, mSettings->library)) { + if (iter1 && iter2 && !isSameIteratorContainerExpression(iter1, iter2, *mSettings)) { mismatchingContainerExpressionError(iter1, iter2); return true; } @@ -826,7 +826,7 @@ void CheckStl::mismatchingContainers() if (iter1.tok == iter2.tok) continue; if (iter1.info->first && iter2.info->last && - isSameExpression(false, iter1.tok, iter2.tok, mSettings->library, false, false)) + isSameExpression(false, iter1.tok, iter2.tok, *mSettings, false, false)) sameIteratorExpressionError(iter1.tok); if (checkIteratorPair(iter1.tok, iter2.tok)) return; @@ -890,7 +890,7 @@ void CheckStl::mismatchingContainerIterator() continue; if (iterTok->str() == "*" && iterTok->astOperand1()->valueType() && iterTok->astOperand1()->valueType()->type == ValueType::ITERATOR) continue; - if (isSameIteratorContainerExpression(tok, val.tokvalue, mSettings->library)) + if (isSameIteratorContainerExpression(tok, val.tokvalue, *mSettings)) continue; mismatchingContainerIteratorError(tok, iterTok, val.tokvalue); } @@ -1168,7 +1168,7 @@ void CheckStl::invalidContainer() ErrorPath ep; bool addressOf = false; - const Variable* var = ValueFlow::getLifetimeVariable(info.tok, ep, &addressOf); + const Variable* var = ValueFlow::getLifetimeVariable(info.tok, ep, *mSettings, &addressOf); // Check the reference is created before the change if (var && var->declarationId() == r.tok->varId() && !addressOf) { // An argument always reaches @@ -1348,7 +1348,7 @@ void CheckStl::negativeIndex() const Library::Container * const container = mSettings->library.detectContainer(var->typeStartToken()); if (!container || !container->arrayLike_indexOp) continue; - const ValueFlow::Value *index = tok->next()->astOperand2()->getValueLE(-1, mSettings); + const ValueFlow::Value *index = tok->next()->astOperand2()->getValueLE(-1, *mSettings); if (!index) continue; negativeIndexError(tok, *index); @@ -1637,7 +1637,7 @@ static const Token* skipLocalVars(const Token* const tok) return tok; } -static const Token *findInsertValue(const Token *tok, const Token *containerTok, const Token *keyTok, const Library &library) +static const Token *findInsertValue(const Token *tok, const Token *containerTok, const Token *keyTok, const Settings &settings) { const Token *startTok = skipLocalVars(tok); const Token *top = startTok->astTop(); @@ -1662,8 +1662,8 @@ static const Token *findInsertValue(const Token *tok, const Token *containerTok, } if (!ikeyTok || !icontainerTok) return nullptr; - if (isSameExpression(true, containerTok, icontainerTok, library, true, false) && - isSameExpression(true, keyTok, ikeyTok, library, true, true)) { + if (isSameExpression(true, containerTok, icontainerTok, settings, true, false) && + isSameExpression(true, keyTok, ikeyTok, settings, true, true)) { if (ivalueTok) return ivalueTok; return ikeyTok; @@ -1698,16 +1698,16 @@ void CheckStl::checkFindInsert() continue; const Token *thenTok = tok->next()->link()->next(); - const Token *valueTok = findInsertValue(thenTok, containerTok, keyTok, mSettings->library); + const Token *valueTok = findInsertValue(thenTok, containerTok, keyTok, *mSettings); if (!valueTok) continue; if (Token::simpleMatch(thenTok->link(), "} else {")) { const Token *valueTok2 = - findInsertValue(thenTok->link()->tokAt(2), containerTok, keyTok, mSettings->library); + findInsertValue(thenTok->link()->tokAt(2), containerTok, keyTok, *mSettings); if (!valueTok2) continue; - if (isSameExpression(true, valueTok, valueTok2, mSettings->library, true, true)) { + if (isSameExpression(true, valueTok, valueTok2, *mSettings, true, true)) { checkFindInsertError(valueTok); } } else { @@ -2577,7 +2577,7 @@ static const Token *singleStatement(const Token *start) return endStatement; } -static const Token *singleAssignInScope(const Token *start, nonneg int varid, bool &input, bool &hasBreak, const Settings* settings) +static const Token *singleAssignInScope(const Token *start, nonneg int varid, bool &input, bool &hasBreak, const Settings& settings) { const Token *endStatement = singleStatement(start); if (!endStatement) @@ -2594,7 +2594,7 @@ static const Token *singleAssignInScope(const Token *start, nonneg int varid, bo return assignTok; } -static const Token *singleMemberCallInScope(const Token *start, nonneg int varid, bool &input, const Settings* settings) +static const Token *singleMemberCallInScope(const Token *start, nonneg int varid, bool &input, const Settings& settings) { if (start->str() != "{") return nullptr; @@ -2631,7 +2631,7 @@ static const Token *singleIncrementInScope(const Token *start, nonneg int varid, return varTok; } -static const Token *singleConditionalInScope(const Token *start, nonneg int varid, const Settings* settings) +static const Token *singleConditionalInScope(const Token *start, nonneg int varid, const Settings& settings) { if (start->str() != "{") return nullptr; @@ -2759,11 +2759,11 @@ namespace { int n = 1 + (astIsPointer(tok) ? 1 : 0); for (int i = 0; i < n; i++) { bool inconclusive = false; - if (isVariableChangedByFunctionCall(tok, i, settings, &inconclusive)) + if (isVariableChangedByFunctionCall(tok, i, *settings, &inconclusive)) return true; if (inconclusive) return true; - if (isVariableChanged(tok, i, settings)) + if (isVariableChanged(tok, i, *settings)) return true; } return false; @@ -2927,7 +2927,7 @@ void CheckStl::useStlAlgorithm() // Check for single assignment bool useLoopVarInAssign{}, hasBreak{}; - const Token *assignTok = singleAssignInScope(bodyTok, loopVar->varId(), useLoopVarInAssign, hasBreak, mSettings); + const Token *assignTok = singleAssignInScope(bodyTok, loopVar->varId(), useLoopVarInAssign, hasBreak, *mSettings); if (assignTok) { if (!checkAssignee(assignTok->astOperand1())) continue; @@ -2957,7 +2957,7 @@ void CheckStl::useStlAlgorithm() } // Check for container calls bool useLoopVarInMemCall; - const Token *memberAccessTok = singleMemberCallInScope(bodyTok, loopVar->varId(), useLoopVarInMemCall, mSettings); + const Token *memberAccessTok = singleMemberCallInScope(bodyTok, loopVar->varId(), useLoopVarInMemCall, *mSettings); if (memberAccessTok && !isIteratorLoop) { const Token *memberCallTok = memberAccessTok->astOperand2(); const int contVarId = memberAccessTok->astOperand1()->varId(); @@ -2990,10 +2990,10 @@ void CheckStl::useStlAlgorithm() } // Check for conditionals - const Token *condBodyTok = singleConditionalInScope(bodyTok, loopVar->varId(), mSettings); + const Token *condBodyTok = singleConditionalInScope(bodyTok, loopVar->varId(), *mSettings); if (condBodyTok) { // Check for single assign - assignTok = singleAssignInScope(condBodyTok, loopVar->varId(), useLoopVarInAssign, hasBreak, mSettings); + assignTok = singleAssignInScope(condBodyTok, loopVar->varId(), useLoopVarInAssign, hasBreak, *mSettings); if (assignTok) { if (!checkAssignee(assignTok->astOperand1())) continue; @@ -3021,7 +3021,7 @@ void CheckStl::useStlAlgorithm() } // Check for container call - memberAccessTok = singleMemberCallInScope(condBodyTok, loopVar->varId(), useLoopVarInMemCall, mSettings); + memberAccessTok = singleMemberCallInScope(condBodyTok, loopVar->varId(), useLoopVarInMemCall, *mSettings); if (memberAccessTok) { const Token *memberCallTok = memberAccessTok->astOperand2(); const int contVarId = memberAccessTok->astOperand1()->varId(); diff --git a/lib/checkstring.cpp b/lib/checkstring.cpp index 1c51fa5d8b9..4975672b79e 100644 --- a/lib/checkstring.cpp +++ b/lib/checkstring.cpp @@ -315,7 +315,7 @@ void CheckString::checkIncorrectStringCompare() } } } else if (Token::Match(tok, "%str%|%char%") && - isUsedAsBool(tok) && + isUsedAsBool(tok, *mSettings) && !isMacroUsage(tok)) incorrectStringBooleanError(tok, tok->str()); } @@ -396,7 +396,7 @@ void CheckString::overlappingStrcmp() if (args1[1]->isLiteral() && args2[1]->isLiteral() && args1[1]->str() != args2[1]->str() && - isSameExpression(true, args1[0], args2[0], mSettings->library, true, false)) + isSameExpression(true, args1[0], args2[0], *mSettings, true, false)) overlappingStrcmpError(eq0, ne0); } } @@ -447,7 +447,7 @@ void CheckString::sprintfOverlappingData() const bool same = isSameExpression(false, dest, arg, - mSettings->library, + *mSettings, true, false); if (same) { diff --git a/lib/checktype.cpp b/lib/checktype.cpp index df30f929601..e6781e4313a 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -99,11 +99,11 @@ void CheckType::checkTooBigBitwiseShift() continue; // Get biggest rhs value. preferably a value which doesn't have 'condition'. - const ValueFlow::Value * value = tok->astOperand2()->getValueGE(lhsbits, mSettings); + const ValueFlow::Value * value = tok->astOperand2()->getValueGE(lhsbits, *mSettings); if (value && mSettings->isEnabled(value, false)) tooBigBitwiseShiftError(tok, lhsbits, *value); else if (lhstype->sign == ValueType::Sign::SIGNED) { - value = tok->astOperand2()->getValueGE(lhsbits-1, mSettings); + value = tok->astOperand2()->getValueGE(lhsbits-1, *mSettings); if (value && mSettings->isEnabled(value, false)) tooBigSignedBitwiseShiftError(tok, lhsbits, *value); } @@ -198,9 +198,9 @@ void CheckType::checkIntegerOverflow() const MathLib::bigint maxvalue = (((MathLib::biguint)1) << (bits - 1)) - 1; // is there a overflow result value - const ValueFlow::Value *value = tok->getValueGE(maxvalue + 1, mSettings); + const ValueFlow::Value *value = tok->getValueGE(maxvalue + 1, *mSettings); if (!value) - value = tok->getValueLE(-maxvalue - 2, mSettings); + value = tok->getValueLE(-maxvalue - 2, *mSettings); if (!value || !mSettings->isEnabled(value,false)) continue; @@ -259,7 +259,7 @@ void CheckType::checkSignConversion() if (!tok1) continue; const ValueFlow::Value* negativeValue = - ValueFlow::findValue(tok1->values(), mSettings, [&](const ValueFlow::Value& v) { + ValueFlow::findValue(tok1->values(), *mSettings, [&](const ValueFlow::Value& v) { return !v.isImpossible() && v.isIntValue() && (v.intvalue <= -1 || v.wideintvalue <= -1); }); if (!negativeValue) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 2b8e566305b..51427b70df6 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1654,10 +1654,10 @@ void CheckUninitVar::valueFlowUninit() continue; if (usage != ExprUsage::Used) { if (!(Token::Match(tok->astParent(), ". %name% (|[") && uninitderef) && - isVariableChanged(tok, v->indirect, mSettings)) + isVariableChanged(tok, v->indirect, *mSettings)) continue; bool inconclusive = false; - if (isVariableChangedByFunctionCall(tok, v->indirect, mSettings, &inconclusive) || inconclusive) + if (isVariableChangedByFunctionCall(tok, v->indirect, *mSettings, &inconclusive) || inconclusive) continue; } uninitvarError(tok, *v); diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 15f989d8a99..80c2183dc1d 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -1301,7 +1301,7 @@ void CheckUnusedVar::checkFunctionVariableUsage() if (tok->previous() && tok->previous()->variable() && tok->previous()->variable()->nameToken()->scope()->type == Scope::eUnion) continue; - FwdAnalysis fwdAnalysis(mSettings->library); + FwdAnalysis fwdAnalysis(*mSettings); const Token* scopeEnd = ValueFlow::getEndOfExprScope(expr, scope, /*smallest*/ false); if (fwdAnalysis.unusedValue(expr, start, scopeEnd)) { if (!bailoutTypeName.empty()) { @@ -1309,7 +1309,7 @@ void CheckUnusedVar::checkFunctionVariableUsage() reportLibraryCfgError(tok, bailoutTypeName); continue; } - if (isTrivialInit && findExpressionChanged(expr, start, scopeEnd, mSettings)) + if (isTrivialInit && findExpressionChanged(expr, start, scopeEnd, *mSettings)) continue; // warn @@ -1693,7 +1693,7 @@ bool CheckUnusedVar::isFunctionWithoutSideEffects(const Function& func, const To // check if global variable is changed if (bodyVariable->isGlobal() || (pointersToGlobals.find(bodyVariable) != pointersToGlobals.end())) { const int indirect = bodyVariable->isArray() ? bodyVariable->dimensions().size() : bodyVariable->isPointer(); - if (isVariableChanged(bodyToken, indirect, mSettings)) { + if (isVariableChanged(bodyToken, indirect, *mSettings)) { return false; } // check if pointer to global variable assigned to another variable (another_var = &global_var) diff --git a/lib/ctu.cpp b/lib/ctu.cpp index 41e8a5aa0ed..b3be91fa0f9 100644 --- a/lib/ctu.cpp +++ b/lib/ctu.cpp @@ -451,7 +451,7 @@ static std::list> getUnsafeFunction(co int indirect = 0; if (argvar->valueType()) indirect = argvar->valueType()->pointer; - if (isVariableChanged(tok2->link(), tok2, indirect, argvar->declarationId(), false, &settings)) + if (isVariableChanged(tok2->link(), tok2, indirect, argvar->declarationId(), false, settings)) return ret; } if (Token::Match(tok2, "%oror%|&&|?")) { diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 2572ccc0613..0092238e7af 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -383,13 +383,13 @@ namespace { std::pair exprToks = stepTok->findExpressionStartEndTokens(); if (exprToks.first != nullptr && exprToks.second != nullptr) stepChangesCond |= - findExpressionChanged(condTok, exprToks.first, exprToks.second->next(), &settings) != nullptr; + findExpressionChanged(condTok, exprToks.first, exprToks.second->next(), settings) != nullptr; } - const bool bodyChangesCond = findExpressionChanged(condTok, endBlock->link(), endBlock, &settings); + const bool bodyChangesCond = findExpressionChanged(condTok, endBlock->link(), endBlock, settings); // Check for mutation in the condition const bool condChanged = nullptr != findAstNode(condTok, [&](const Token* tok) { - return isVariableChanged(tok, 0, &settings); + return isVariableChanged(tok, 0, settings); }); const bool changed = stepChangesCond || bodyChangesCond || condChanged; if (!changed) diff --git a/lib/fwdanalysis.cpp b/lib/fwdanalysis.cpp index c261b39ea96..712318bf063 100644 --- a/lib/fwdanalysis.cpp +++ b/lib/fwdanalysis.cpp @@ -21,6 +21,7 @@ #include "astutils.h" #include "config.h" #include "library.h" +#include "settings.h" #include "symboldatabase.h" #include "token.h" #include "vfvalue.h" @@ -236,7 +237,7 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * } } tok = bodyStart->link(); - if (isReturnScope(tok, mLibrary)) + if (isReturnScope(tok, mSettings.library)) return Result(Result::Type::BAILOUT); if (Token::simpleMatch(tok, "} else {")) tok = tok->linkAt(2); @@ -272,12 +273,12 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * if (exprVarIds.find(tok->varId()) != exprVarIds.end()) { const Token *parent = tok; bool other = false; - bool same = tok->astParent() && isSameExpression(false, expr, tok, mLibrary, true, false, nullptr); + bool same = tok->astParent() && isSameExpression(false, expr, tok, mSettings, true, false, nullptr); while (!same && Token::Match(parent->astParent(), "*|.|::|[|(|%cop%")) { parent = parent->astParent(); if (parent->str() == "(" && !parent->isCast()) break; - if (isSameExpression(false, expr, parent, mLibrary, true, false, nullptr)) { + if (isSameExpression(false, expr, parent, mSettings, true, false, nullptr)) { same = true; if (mWhat == What::ValueFlow) { KnownAndToken v; @@ -287,7 +288,7 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * } } if (Token::Match(parent, ". %var%") && parent->next()->varId() && exprVarIds.find(parent->next()->varId()) == exprVarIds.end() && - isSameExpression(false, expr->astOperand1(), parent->astOperand1(), mLibrary, true, false, nullptr)) { + isSameExpression(false, expr->astOperand1(), parent->astOperand1(), mSettings, true, false, nullptr)) { other = true; break; } @@ -317,7 +318,7 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * if (hasGccCompoundStatement(parent->astParent()->astOperand2())) return Result(Result::Type::BAILOUT); // cppcheck-suppress shadowFunction - TODO: fix this - const bool reassign = isSameExpression(false, expr, parent, mLibrary, false, false, nullptr); + const bool reassign = isSameExpression(false, expr, parent, mSettings, false, false, nullptr); if (reassign) return Result(Result::Type::WRITE, parent->astParent()); return Result(Result::Type::READ); @@ -343,7 +344,7 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * while (argnr < args.size() && args[argnr] != parent) argnr++; if (argnr < args.size()) { - const Library::Function* functionInfo = mLibrary.getFunction(ftok->astOperand1()); + const Library::Function* functionInfo = mSettings.library.getFunction(ftok->astOperand1()); if (functionInfo) { const auto it = functionInfo->argumentChecks.find(argnr + 1); if (it != functionInfo->argumentChecks.end() && it->second.direction == Library::ArgumentChecks::Direction::DIR_OUT) @@ -464,7 +465,7 @@ bool FwdAnalysis::hasOperand(const Token *tok, const Token *lhs) const { if (!tok) return false; - if (isSameExpression(false, tok, lhs, mLibrary, false, false, nullptr)) + if (isSameExpression(false, tok, lhs, mSettings, false, false, nullptr)) return true; return hasOperand(tok->astOperand1(), lhs) || hasOperand(tok->astOperand2(), lhs); } @@ -512,7 +513,7 @@ bool FwdAnalysis::possiblyAliased(const Token *expr, const Token *startToken) co if (tok->function() && tok->function()->getArgumentVar(argnr) && !tok->function()->getArgumentVar(argnr)->isReference() && !tok->function()->isConst()) continue; for (const Token *subexpr = expr; subexpr; subexpr = subexpr->astOperand1()) { - if (isSameExpression(macro, subexpr, args[argnr], mLibrary, pure, followVar)) { + if (isSameExpression(macro, subexpr, args[argnr], mSettings, pure, followVar)) { const Scope* scope = expr->scope(); // if there is no other variable, assume no aliasing if (scope->varlist.size() > 1) return true; @@ -537,7 +538,7 @@ bool FwdAnalysis::possiblyAliased(const Token *expr, const Token *startToken) co continue; for (const Token *subexpr = expr; subexpr; subexpr = subexpr->astOperand1()) { - if (subexpr != addrOf && isSameExpression(macro, subexpr, addrOf, mLibrary, pure, followVar)) + if (subexpr != addrOf && isSameExpression(macro, subexpr, addrOf, mSettings, pure, followVar)) return true; } } diff --git a/lib/fwdanalysis.h b/lib/fwdanalysis.h index 17fc29f7b42..b149dcef7af 100644 --- a/lib/fwdanalysis.h +++ b/lib/fwdanalysis.h @@ -27,7 +27,7 @@ #include class Token; -class Library; +class Settings; /** * Forward data flow analysis for checks @@ -37,7 +37,7 @@ class Library; */ class FwdAnalysis { public: - explicit FwdAnalysis(const Library &library) : mLibrary(library) {} + explicit FwdAnalysis(const Settings &settings) : mSettings(settings) {} bool hasOperand(const Token *tok, const Token *lhs) const; @@ -82,7 +82,7 @@ class FwdAnalysis { Result check(const Token *expr, const Token *startToken, const Token *endToken); Result checkRecursive(const Token *expr, const Token *startToken, const Token *endToken, const std::set &exprVarIds, bool local, bool inInnerClass, int depth=0); - const Library &mLibrary; + const Settings &mSettings; enum class What { Reassign, UnusedValue, ValueFlow } mWhat = What::Reassign; std::vector mValueFlow; bool mValueFlowKnown = true; diff --git a/lib/library.cpp b/lib/library.cpp index e8feeb07502..6080ebcfce9 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -1745,11 +1745,11 @@ bool Library::hasAnyTypeCheck(const std::string& typeName) const } std::shared_ptr createTokenFromExpression(const std::string& returnValue, - const Settings* settings, + const Settings& settings, bool cpp, std::unordered_map* lookupVarId) { - std::shared_ptr tokenList = std::make_shared(settings); + std::shared_ptr tokenList = std::make_shared(&settings); { const std::string code = "return " + returnValue + ";"; std::istringstream istr(code); @@ -1788,6 +1788,6 @@ std::shared_ptr createTokenFromExpression(const std::string& returnValue, // Evaluate expression tokenList->createAst(); Token* expr = tokenList->front()->astOperand1(); - ValueFlow::valueFlowConstantFoldAST(expr, *settings); + ValueFlow::valueFlowConstantFoldAST(expr, settings); return {tokenList, expr}; } diff --git a/lib/library.h b/lib/library.h index 11d59c676cd..a6076329606 100644 --- a/lib/library.h +++ b/lib/library.h @@ -606,7 +606,7 @@ class CPPCHECKLIB Library { CPPCHECKLIB const Library::Container * getLibraryContainer(const Token * tok); std::shared_ptr createTokenFromExpression(const std::string& returnValue, - const Settings* settings, + const Settings& settings, bool cpp, std::unordered_map* lookupVarId = nullptr); diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 49b11310104..7d5b50b910f 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -196,9 +196,9 @@ void ProgramMemory::insert(const ProgramMemory &pm) mValues.insert(p); } -static ValueFlow::Value execute(const Token* expr, ProgramMemory& pm, const Settings* settings); +static ValueFlow::Value execute(const Token* expr, ProgramMemory& pm, const Settings& settings); -static bool evaluateCondition(MathLib::bigint r, const Token* condition, ProgramMemory& pm, const Settings* settings) +static bool evaluateCondition(MathLib::bigint r, const Token* condition, ProgramMemory& pm, const Settings& settings) { if (!condition) return false; @@ -208,12 +208,12 @@ static bool evaluateCondition(MathLib::bigint r, const Token* condition, Program return !error && result == r; } -bool conditionIsFalse(const Token* condition, ProgramMemory pm, const Settings* settings) +bool conditionIsFalse(const Token* condition, ProgramMemory pm, const Settings& settings) { return evaluateCondition(0, condition, pm, settings); } -bool conditionIsTrue(const Token* condition, ProgramMemory pm, const Settings* settings) +bool conditionIsTrue(const Token* condition, ProgramMemory pm, const Settings& settings) { return evaluateCondition(1, condition, pm, settings); } @@ -271,7 +271,7 @@ static bool isBasicForLoop(const Token* tok) return true; } -static void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Token* endTok, const Settings* settings, bool then) +static void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Token* endTok, const Settings& settings, bool then) { auto eval = [&](const Token* t) -> std::vector { if (!t) @@ -300,7 +300,7 @@ static void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, con const bool impossible = (tok->str() == "==" && !then) || (tok->str() == "!=" && then); const ValueFlow::Value& v = then ? truevalue : falsevalue; pm.setValue(vartok, impossible ? asImpossible(v) : v); - const Token* containerTok = settings->library.getContainerFromYield(vartok, Library::Container::Yield::SIZE); + const Token* containerTok = settings.library.getContainerFromYield(vartok, Library::Container::Yield::SIZE); if (containerTok) pm.setContainerSizeValue(containerTok, v.intvalue, !impossible); } else if (Token::simpleMatch(tok, "!")) { @@ -326,14 +326,13 @@ static void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, con if (endTok && findExpressionChanged(tok, tok->next(), endTok, settings)) return; pm.setIntValue(tok, 0, then); - assert(settings); - const Token* containerTok = settings->library.getContainerFromYield(tok, Library::Container::Yield::EMPTY); + const Token* containerTok = settings.library.getContainerFromYield(tok, Library::Container::Yield::EMPTY); if (containerTok) pm.setContainerSizeValue(containerTok, 0, then); } } -static void fillProgramMemoryFromConditions(ProgramMemory& pm, const Scope* scope, const Token* endTok, const Settings* settings) +static void fillProgramMemoryFromConditions(ProgramMemory& pm, const Scope* scope, const Token* endTok, const Settings& settings) { if (!scope) return; @@ -353,12 +352,12 @@ static void fillProgramMemoryFromConditions(ProgramMemory& pm, const Scope* scop } } -static void fillProgramMemoryFromConditions(ProgramMemory& pm, const Token* tok, const Settings* settings) +static void fillProgramMemoryFromConditions(ProgramMemory& pm, const Token* tok, const Settings& settings) { fillProgramMemoryFromConditions(pm, tok->scope(), tok, settings); } -static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok, const Settings* settings, const ProgramMemory& state, const ProgramMemory::Map& vars) +static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok, const Settings& settings, const ProgramMemory& state, const ProgramMemory::Map& vars) { int indentlevel = 0; for (const Token *tok2 = tok; tok2; tok2 = tok2->previous()) { @@ -418,10 +417,10 @@ static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok } } -static void removeModifiedVars(ProgramMemory& pm, const Token* tok, const Token* origin) +static void removeModifiedVars(ProgramMemory& pm, const Token* tok, const Token* origin, const Settings& settings) { pm.erase_if([&](const ExprIdToken& e) { - return isVariableChanged(origin, tok, e.getExpressionId(), false, nullptr); + return isVariableChanged(origin, tok, e.getExpressionId(), false, settings); }); } @@ -432,15 +431,18 @@ static ProgramMemory getInitialProgramState(const Token* tok, { ProgramMemory pm; if (origin) { - fillProgramMemoryFromConditions(pm, origin, nullptr); + fillProgramMemoryFromConditions(pm, origin, settings); const ProgramMemory state = pm; - fillProgramMemoryFromAssignments(pm, tok, &settings, state, vars); - removeModifiedVars(pm, tok, origin); + fillProgramMemoryFromAssignments(pm, tok, settings, state, vars); + removeModifiedVars(pm, tok, origin, settings); } return pm; } -ProgramMemoryState::ProgramMemoryState(const Settings* s) : settings(s) {} +ProgramMemoryState::ProgramMemoryState(const Settings* s) : settings(s) +{ + assert(settings != nullptr); +} void ProgramMemoryState::insert(const ProgramMemory &pm, const Token* origin) { @@ -470,9 +472,9 @@ void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& va { ProgramMemory pm = state; addVars(pm, vars); - fillProgramMemoryFromConditions(pm, tok, settings); + fillProgramMemoryFromConditions(pm, tok, *settings); ProgramMemory local = pm; - fillProgramMemoryFromAssignments(pm, tok, settings, local, vars); + fillProgramMemoryFromAssignments(pm, tok, *settings, local, vars); addVars(pm, vars); replace(std::move(pm), tok); } @@ -483,7 +485,7 @@ void ProgramMemoryState::assume(const Token* tok, bool b, bool isEmpty) if (isEmpty) pm.setContainerSizeValue(tok, 0, b); else - programMemoryParseCondition(pm, tok, nullptr, settings, b); + programMemoryParseCondition(pm, tok, nullptr, *settings, b); const Token* origin = tok; const Token* top = tok->astTop(); if (top && Token::Match(top->previous(), "for|while|if (") && !Token::simpleMatch(tok->astParent(), "?")) { @@ -499,16 +501,16 @@ void ProgramMemoryState::removeModifiedVars(const Token* tok) { const ProgramMemory& pm = state; auto eval = [&](const Token* cond) -> std::vector { - if (conditionIsTrue(cond, pm, settings)) + if (conditionIsTrue(cond, pm, *settings)) return {1}; - if (conditionIsFalse(cond, pm, settings)) + if (conditionIsFalse(cond, pm, *settings)) return {0}; return {}; }; state.erase_if([&](const ExprIdToken& e) { const Token* start = origins[e.getExpressionId()]; const Token* expr = e.tok; - if (!expr || findExpressionChangedSkipDeadCode(expr, start, tok, settings, eval)) { + if (!expr || findExpressionChangedSkipDeadCode(expr, start, tok, *settings, eval)) { origins.erase(e.getExpressionId()); return true; } @@ -539,10 +541,10 @@ ProgramMemory getProgramMemory(const Token* tok, const Token* expr, const ValueF ProgramMemory programMemory; programMemory.replace(getInitialProgramState(tok, value.tokvalue, settings)); programMemory.replace(getInitialProgramState(tok, value.condition, settings)); - fillProgramMemoryFromConditions(programMemory, tok, &settings); + fillProgramMemoryFromConditions(programMemory, tok, settings); programMemory.setValue(expr, value); const ProgramMemory state = programMemory; - fillProgramMemoryFromAssignments(programMemory, tok, &settings, state, {{expr, value}}); + fillProgramMemoryFromAssignments(programMemory, tok, settings, state, {{expr, value}}); return programMemory; } @@ -1222,7 +1224,7 @@ static std::vector setDifference(const std::vector& static bool evalSameCondition(const ProgramMemory& state, const Token* storedValue, const Token* cond, - const Settings* settings) + const Settings& settings) { assert(!conditionIsTrue(cond, state, settings)); ProgramMemory pm = state; @@ -1257,7 +1259,10 @@ namespace { int fdepth = 4; int depth = 10; - Executor(ProgramMemory* pm, const Settings* settings) : pm(pm), settings(settings) {} + Executor(ProgramMemory* pm, const Settings* settings) : pm(pm), settings(settings) + { + assert(settings != nullptr); + } static ValueFlow::Value unknown() { return ValueFlow::Value::unknown(); @@ -1368,7 +1373,7 @@ namespace { continue; for (const Token* cond1 : diffConditions1) { auto it = std::find_if(diffConditions2.begin(), diffConditions2.end(), [&](const Token* cond2) { - return evalSameCondition(*pm, cond2, cond1, settings); + return evalSameCondition(*pm, cond2, cond1, *settings); }); if (it == diffConditions2.end()) break; @@ -1550,7 +1555,7 @@ namespace { } if (expr->exprId() > 0 && pm->hasValue(expr->exprId())) { ValueFlow::Value result = pm->at(expr->exprId()); - if (result.isImpossible() && result.isIntValue() && result.intvalue == 0 && isUsedAsBool(expr)) { + if (result.isImpossible() && result.isIntValue() && result.intvalue == 0 && isUsedAsBool(expr, *settings)) { result.intvalue = !result.intvalue; result.setKnown(); } @@ -1598,7 +1603,7 @@ namespace { arg_map[argn] = v; argn++; } - return evaluateLibraryFunction(arg_map, returnValue, settings, ftok->isCpp()); + return evaluateLibraryFunction(arg_map, returnValue, *settings, ftok->isCpp()); } } } @@ -1606,11 +1611,12 @@ namespace { visitAstNodes(expr->astOperand2(), [&](const Token* child) { if (child->exprId() > 0 && pm->hasValue(child->exprId())) { ValueFlow::Value& v = pm->at(child->exprId()); + assert(settings != nullptr); if (v.valueType == ValueFlow::Value::ValueType::CONTAINER_SIZE) { if (ValueFlow::isContainerSizeChanged(child, v.indirect, *settings)) v = unknown(); } else if (v.valueType != ValueFlow::Value::ValueType::UNINIT) { - if (isVariableChanged(child, v.indirect, settings)) + if (isVariableChanged(child, v.indirect, *settings)) v = unknown(); } } @@ -1742,9 +1748,9 @@ namespace { }; } // namespace -static ValueFlow::Value execute(const Token* expr, ProgramMemory& pm, const Settings* settings) +static ValueFlow::Value execute(const Token* expr, ProgramMemory& pm, const Settings& settings) { - Executor ex{&pm, settings}; + Executor ex{&pm, &settings}; return ex.execute(expr); } @@ -1756,7 +1762,7 @@ std::vector execute(const Scope* scope, ProgramMemory& pm, con ValueFlow::Value evaluateLibraryFunction(const std::unordered_map& args, const std::string& returnValue, - const Settings* settings, + const Settings& settings, bool cpp) { thread_local static std::unordered_map& args, const std::string& returnValue, - const Settings* settings, + const Settings& settings, bool cpp); #endif diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index b6caf5b598b..14b220e5661 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -443,7 +443,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() scope->definedTypesMap[new_type->name()] = new_type; } - scope->addVariable(varNameTok, tok, tok, access[scope], new_scope->definedType, scope, &mSettings); + scope->addVariable(varNameTok, tok, tok, access[scope], new_scope->definedType, scope, mSettings); const Token *tok2 = tok->next(); @@ -2294,7 +2294,7 @@ const Token * Variable::declEndToken() const return declEnd; } -void Variable::evaluate(const Settings* settings) +void Variable::evaluate(const Settings& settings) { // Is there initialization in variable declaration const Token *initTok = mNameToken ? mNameToken->next() : nullptr; @@ -2306,18 +2306,15 @@ void Variable::evaluate(const Settings* settings) if (Token::Match(initTok, "[={(]") || (initTok && initTok->isSplittedVarDeclEq())) setFlag(fIsInit, true); - if (!settings) - return; - - const Library & lib = settings->library; + const Library & lib = settings.library; // TODO: ValueType::parseDecl() is also performing a container lookup bool isContainer = false; if (mNameToken) - setFlag(fIsArray, arrayDimensions(*settings, isContainer)); + setFlag(fIsArray, arrayDimensions(settings, isContainer)); if (mTypeStartToken) - setValueType(ValueType::parseDecl(mTypeStartToken,*settings)); + setValueType(ValueType::parseDecl(mTypeStartToken,settings)); const Token* tok = mTypeStartToken; while (tok && tok->previous() && tok->previous()->isName()) @@ -2385,7 +2382,7 @@ void Variable::evaluate(const Settings* settings) tok = tok->link()->previous(); // add array dimensions if present if (tok && tok->next()->str() == "[") - setFlag(fIsArray, arrayDimensions(*settings, isContainer)); + setFlag(fIsArray, arrayDimensions(settings, isContainer)); } if (!tok) return; @@ -4520,7 +4517,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s if (startTok == nameTok) break; - argumentList.emplace_back(nameTok, startTok, endTok, count++, AccessControl::Argument, argType, functionScope, &symbolDatabase->mSettings); + argumentList.emplace_back(nameTok, startTok, endTok, count++, AccessControl::Argument, argType, functionScope, symbolDatabase->mSettings); if (tok->str() == ")") { // check for a variadic function or a variadic template function @@ -4759,7 +4756,7 @@ AccessControl Scope::defaultAccess() const } void Scope::addVariable(const Token *token_, const Token *start_, const Token *end_, - AccessControl access_, const Type *type_, const Scope *scope_, const Settings* settings) + AccessControl access_, const Type *type_, const Scope *scope_, const Settings& settings) { // keep possible size_t -> int truncation outside emplace_back() to have a single line // C4267 VC++ warning instead of several dozens lines @@ -4926,7 +4923,7 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess, con const Token *typeend = Token::findsimplematch(typestart, "[")->previous(); for (tok = typeend->tokAt(2); Token::Match(tok, "%name%|,"); tok = tok->next()) { if (tok->varId()) - addVariable(tok, typestart, typeend, varaccess, nullptr, this, &settings); + addVariable(tok, typestart, typeend, varaccess, nullptr, this, settings); } return typeend->linkAt(1); } @@ -4963,7 +4960,7 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess, con if (Token::Match(typestart, "enum|struct")) typestart = typestart->next(); - addVariable(vartok, typestart, vartok->previous(), varaccess, vType, this, &settings); + addVariable(vartok, typestart, vartok->previous(), varaccess, vType, this, settings); } return tok; diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 0dfebdbedb6..0d15d82a081 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -213,7 +213,7 @@ class CPPCHECKLIB Variable { public: Variable(const Token *name_, const Token *start_, const Token *end_, nonneg int index_, AccessControl access_, const Type *type_, - const Scope *scope_, const Settings* settings) + const Scope *scope_, const Settings& settings) : mNameToken(name_), mTypeStartToken(start_), mTypeEndToken(end_), @@ -692,7 +692,7 @@ class CPPCHECKLIB Variable { std::vector mDimensions; /** @brief fill in information, depending on Tokens given at instantiation */ - void evaluate(const Settings* settings); + void evaluate(const Settings& settings); }; class CPPCHECKLIB Function { @@ -1143,7 +1143,7 @@ class CPPCHECKLIB Scope { void addVariable(const Token *token_, const Token *start_, const Token *end_, AccessControl access_, const Type *type_, - const Scope *scope_, const Settings* settings); + const Scope *scope_, const Settings& settings); /** @brief initialize varlist */ void getVariableList(const Settings& settings); diff --git a/lib/token.cpp b/lib/token.cpp index c169577106b..b1ab02c61a4 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -1976,7 +1976,7 @@ void Token::printValueFlow(bool xml, std::ostream &out) const out << outs; } -const ValueFlow::Value * Token::getValueLE(const MathLib::bigint val, const Settings *settings) const +const ValueFlow::Value * Token::getValueLE(const MathLib::bigint val, const Settings &settings) const { if (!mImpl->mValues) return nullptr; @@ -1985,7 +1985,7 @@ const ValueFlow::Value * Token::getValueLE(const MathLib::bigint val, const Sett }); } -const ValueFlow::Value * Token::getValueGE(const MathLib::bigint val, const Settings *settings) const +const ValueFlow::Value * Token::getValueGE(const MathLib::bigint val, const Settings &settings) const { if (!mImpl->mValues) return nullptr; @@ -1994,16 +1994,16 @@ const ValueFlow::Value * Token::getValueGE(const MathLib::bigint val, const Sett }); } -const ValueFlow::Value * Token::getInvalidValue(const Token *ftok, nonneg int argnr, const Settings *settings) const +const ValueFlow::Value * Token::getInvalidValue(const Token *ftok, nonneg int argnr, const Settings &settings) const { - if (!mImpl->mValues || !settings) + if (!mImpl->mValues) return nullptr; const ValueFlow::Value *ret = nullptr; for (std::list::const_iterator it = mImpl->mValues->begin(); it != mImpl->mValues->end(); ++it) { if (it->isImpossible()) continue; - if ((it->isIntValue() && !settings->library.isIntArgValid(ftok, argnr, it->intvalue)) || - (it->isFloatValue() && !settings->library.isFloatArgValid(ftok, argnr, it->floatValue))) { + if ((it->isIntValue() && !settings.library.isIntArgValid(ftok, argnr, it->intvalue)) || + (it->isFloatValue() && !settings.library.isFloatArgValid(ftok, argnr, it->floatValue))) { if (!ret || ret->isInconclusive() || (ret->condition && !it->isInconclusive())) ret = &(*it); if (!ret->isInconclusive() && !ret->condition) @@ -2011,9 +2011,9 @@ const ValueFlow::Value * Token::getInvalidValue(const Token *ftok, nonneg int ar } } if (ret) { - if (ret->isInconclusive() && !settings->certainty.isEnabled(Certainty::inconclusive)) + if (ret->isInconclusive() && !settings.certainty.isEnabled(Certainty::inconclusive)) return nullptr; - if (ret->condition && !settings->severity.isEnabled(Severity::warning)) + if (ret->condition && !settings.severity.isEnabled(Severity::warning)) return nullptr; } return ret; diff --git a/lib/token.h b/lib/token.h index 4c5ceaba111..59d75c72035 100644 --- a/lib/token.h +++ b/lib/token.h @@ -1226,10 +1226,10 @@ class CPPCHECKLIB Token { const ValueFlow::Value* getMovedValue() const; - const ValueFlow::Value * getValueLE(const MathLib::bigint val, const Settings *settings) const; - const ValueFlow::Value * getValueGE(const MathLib::bigint val, const Settings *settings) const; + const ValueFlow::Value * getValueLE(const MathLib::bigint val, const Settings &settings) const; + const ValueFlow::Value * getValueGE(const MathLib::bigint val, const Settings &settings) const; - const ValueFlow::Value * getInvalidValue(const Token *ftok, nonneg int argnr, const Settings *settings) const; + const ValueFlow::Value * getInvalidValue(const Token *ftok, nonneg int argnr, const Settings &settings) const; const ValueFlow::Value* getContainerSizeValue(const MathLib::bigint val) const; diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 6e7e79c4c1b..0975a0186d5 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1766,7 +1766,7 @@ static void valueFlowSameExpressions(TokenList &tokenlist, const Settings& setti if (!val.isKnown()) continue; - if (isSameExpression(false, tok->astOperand1(), tok->astOperand2(), settings.library, true, true, &val.errorPath)) { + if (isSameExpression(false, tok->astOperand1(), tok->astOperand2(), settings, true, true, &val.errorPath)) { setTokenValue(tok, std::move(val), settings); } } @@ -1901,7 +1901,7 @@ static bool isConvertedToIntegral(const Token* tok, const Settings& settings) { if (!tok) return false; - std::vector parentTypes = getParentValueTypes(tok, &settings); + std::vector parentTypes = getParentValueTypes(tok, settings); if (parentTypes.empty()) return false; const ValueType& vt = parentTypes.front(); @@ -2441,7 +2441,7 @@ static bool bifurcateVariableChanged(const Variable* var, bool result = false; const Token* tok = start; while ((tok = findVariableChanged( - tok->next(), end, var->isPointer(), var->declarationId(), var->isGlobal(), &settings))) { + tok->next(), end, var->isPointer(), var->declarationId(), var->isGlobal(), settings))) { if (Token::Match(tok->astParent(), "%assign%")) { if (!bifurcate(tok->astParent()->astOperand2(), varids, settings, depth - 1)) return true; @@ -2663,11 +2663,11 @@ struct ValueFlowAnalyzer : Analyzer { return read; } bool inconclusive = false; - if (isVariableChangedByFunctionCall(tok, getIndirect(tok), &getSettings(), &inconclusive)) + if (isVariableChangedByFunctionCall(tok, getIndirect(tok), getSettings(), &inconclusive)) return read | Action::Invalid; if (inconclusive) return read | Action::Inconclusive; - if (isVariableChanged(tok, getIndirect(tok), &getSettings())) { + if (isVariableChanged(tok, getIndirect(tok), getSettings())) { if (Token::Match(tok->astParent(), "*|[|.|++|--")) return read | Action::Invalid; // Check if its assigned to the same value @@ -2696,13 +2696,13 @@ struct ValueFlowAnalyzer : Analyzer { } } for (int i = 0; i <= indirect; ++i) - if (isVariableChanged(tok, i, &getSettings())) + if (isVariableChanged(tok, i, getSettings())) return Action::Invalid; return Action::None; } virtual Action isThisModified(const Token* tok) const { - if (isThisChanged(tok, 0, &getSettings())) + if (isThisChanged(tok, 0, getSettings())) return Action::Invalid; return Action::None; } @@ -2987,14 +2987,14 @@ struct ValueFlowAnalyzer : Analyzer { std::vector result; ProgramMemory pm = getProgramMemory(); if (Token::Match(tok, "&&|%oror%")) { - if (conditionIsTrue(tok, pm, &getSettings())) + if (conditionIsTrue(tok, pm, getSettings())) result.push_back(1); - if (conditionIsFalse(tok, std::move(pm), &getSettings())) + if (conditionIsFalse(tok, std::move(pm), getSettings())) result.push_back(0); } 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); } @@ -3015,7 +3015,7 @@ struct ValueFlowAnalyzer : Analyzer { }); } if (e == Evaluate::ContainerEmpty) { - const ValueFlow::Value* value = ValueFlow::findValue(tok->values(), nullptr, [](const ValueFlow::Value& v) { + const ValueFlow::Value* value = ValueFlow::findValue(tok->values(), settings, [](const ValueFlow::Value& v) { return v.isKnown() && v.isContainerSizeValue(); }); if (value) @@ -3261,7 +3261,7 @@ struct ExpressionAnalyzer : SingleValueFlowAnalyzer { setupExprVarIds(value.tokvalue); } uniqueExprId = - expr->isUniqueExprId() && (Token::Match(expr, "%cop%") || !isVariableChanged(expr, 0, &s)); + expr->isUniqueExprId() && (Token::Match(expr, "%cop%") || !isVariableChanged(expr, 0, s)); } static bool nonLocal(const Variable* var, bool deref) { @@ -3361,7 +3361,7 @@ struct SameExpressionAnalyzer : ExpressionAnalyzer { bool match(const Token* tok) const override { - return isSameExpression(true, expr, tok, getSettings().library, true, true); + return isSameExpression(true, expr, tok, getSettings(), true, true); } }; @@ -3377,7 +3377,7 @@ struct OppositeExpressionAnalyzer : ExpressionAnalyzer { } bool match(const Token* tok) const override { - return isOppositeCond(isNot, expr, tok, getSettings().library, true, true); + return isOppositeCond(isNot, expr, tok, getSettings(), true, true); } }; @@ -3562,6 +3562,7 @@ static std::vector getLifetimeTokens(const Token* tok, bool escape, ValueFlow::Value::ErrorPath errorPath, Predicate pred, + const Settings& settings, int depth = 20) { if (!tok) @@ -3591,7 +3592,7 @@ static std::vector getLifetimeTokens(const Token* tok, (!escape && (var->isConst() || var->isRValueReference()) && temporary)) return {{tok, true, std::move(errorPath)}}; if (vartok) - return getLifetimeTokens(vartok, escape, std::move(errorPath), pred, depth - 1); + return getLifetimeTokens(vartok, escape, std::move(errorPath), pred, settings, depth - 1); } else if (Token::simpleMatch(var->nameToken()->astParent(), ":") && var->nameToken()->astParent()->astParent() && Token::simpleMatch(var->nameToken()->astParent()->astParent()->previous(), "for (")) { @@ -3601,7 +3602,7 @@ static std::vector getLifetimeTokens(const Token* tok, return {{tok, true, std::move(errorPath)}}; const Token* contok = var->nameToken()->astParent()->astOperand2(); if (astIsContainer(contok)) - return getLifetimeTokens(contok, escape, std::move(errorPath), pred, depth - 1); + return getLifetimeTokens(contok, escape, std::move(errorPath), pred, settings, depth - 1); return std::vector{}; } else { return std::vector {}; @@ -3617,7 +3618,7 @@ static std::vector getLifetimeTokens(const Token* tok, for (const Token* returnTok : returns) { if (returnTok == tok) continue; - for (ValueFlow::LifetimeToken& lt : getLifetimeTokens(returnTok, escape, errorPath, pred, depth - returns.size())) { + for (ValueFlow::LifetimeToken& lt : getLifetimeTokens(returnTok, escape, errorPath, pred, settings, depth - returns.size())) { const Token* argvarTok = lt.token; const Variable* argvar = argvarTok->variable(); if (!argvar) @@ -3643,7 +3644,7 @@ static std::vector getLifetimeTokens(const Token* tok, } if (argTok) { std::vector arglts = ValueFlow::LifetimeToken::setInconclusive( - getLifetimeTokens(argTok, escape, std::move(lt.errorPath), pred, depth - returns.size()), + getLifetimeTokens(argTok, escape, std::move(lt.errorPath), pred, settings, depth - returns.size()), returns.size() > 1); result.insert(result.end(), arglts.cbegin(), arglts.cend()); } @@ -3657,7 +3658,7 @@ static std::vector getLifetimeTokens(const Token* tok, if (y == Library::Container::Yield::AT_INDEX || y == Library::Container::Yield::ITEM) { errorPath.emplace_back(tok->previous(), "Accessing container."); return ValueFlow::LifetimeToken::setAddressOf( - getLifetimeTokens(tok->tokAt(-2)->astOperand1(), escape, std::move(errorPath), pred, depth - 1), + getLifetimeTokens(tok->tokAt(-2)->astOperand1(), escape, std::move(errorPath), pred, settings, depth - 1), false); } } @@ -3688,45 +3689,45 @@ static std::vector getLifetimeTokens(const Token* tok, if (v.tokvalue == tok) continue; errorPath.insert(errorPath.end(), v.errorPath.cbegin(), v.errorPath.cend()); - return getLifetimeTokens(v.tokvalue, escape, std::move(errorPath), pred, depth - 1); + return getLifetimeTokens(v.tokvalue, escape, std::move(errorPath), pred, settings, depth - 1); } } else { - return ValueFlow::LifetimeToken::setAddressOf(getLifetimeTokens(vartok, escape, std::move(errorPath), pred, depth - 1), + return ValueFlow::LifetimeToken::setAddressOf(getLifetimeTokens(vartok, escape, std::move(errorPath), pred, settings, depth - 1), !(astIsContainer(vartok) && Token::simpleMatch(vartok->astParent(), "["))); } } else if (Token::simpleMatch(tok, "{") && getArgumentStart(tok) && !Token::simpleMatch(getArgumentStart(tok), ",") && getArgumentStart(tok)->valueType()) { const Token* vartok = getArgumentStart(tok); - auto vts = getParentValueTypes(tok); + auto vts = getParentValueTypes(tok, settings); auto it = std::find_if(vts.cbegin(), vts.cend(), [&](const ValueType& vt) { return vt.isTypeEqual(vartok->valueType()); }); if (it != vts.end()) - return getLifetimeTokens(vartok, escape, std::move(errorPath), pred, depth - 1); + return getLifetimeTokens(vartok, escape, std::move(errorPath), pred, settings, depth - 1); } return {{tok, std::move(errorPath)}}; } -std::vector ValueFlow::getLifetimeTokens(const Token* tok, bool escape, ValueFlow::Value::ErrorPath errorPath) +std::vector ValueFlow::getLifetimeTokens(const Token* tok, const Settings& settings, bool escape, ValueFlow::Value::ErrorPath errorPath) { return getLifetimeTokens(tok, escape, std::move(errorPath), [](const Token*) { return false; - }); + }, settings); } -bool ValueFlow::hasLifetimeToken(const Token* tok, const Token* lifetime) +bool ValueFlow::hasLifetimeToken(const Token* tok, const Token* lifetime, const Settings& settings) { bool result = false; getLifetimeTokens(tok, false, ValueFlow::Value::ErrorPath{}, [&](const Token* tok2) { result = tok2->exprId() == lifetime->exprId(); return result; - }); + }, settings); return result; } -static const Token* getLifetimeToken(const Token* tok, ValueFlow::Value::ErrorPath& errorPath, bool* addressOf = nullptr) +static const Token* getLifetimeToken(const Token* tok, ValueFlow::Value::ErrorPath& errorPath, const Settings& settings, bool* addressOf = nullptr) { - std::vector lts = ValueFlow::getLifetimeTokens(tok); + std::vector lts = ValueFlow::getLifetimeTokens(tok, settings); if (lts.size() != 1) return nullptr; if (lts.front().inconclusive) @@ -3737,18 +3738,18 @@ static const Token* getLifetimeToken(const Token* tok, ValueFlow::Value::ErrorPa return lts.front().token; } -const Variable* ValueFlow::getLifetimeVariable(const Token* tok, ValueFlow::Value::ErrorPath& errorPath, bool* addressOf) +const Variable* ValueFlow::getLifetimeVariable(const Token* tok, ValueFlow::Value::ErrorPath& errorPath, const Settings& settings, bool* addressOf) { - const Token* tok2 = getLifetimeToken(tok, errorPath, addressOf); + const Token* tok2 = getLifetimeToken(tok, errorPath, settings, addressOf); if (tok2 && tok2->variable()) return tok2->variable(); return nullptr; } -const Variable* ValueFlow::getLifetimeVariable(const Token* tok) +const Variable* ValueFlow::getLifetimeVariable(const Token* tok, const Settings& settings) { ValueFlow::Value::ErrorPath errorPath; - return getLifetimeVariable(tok, errorPath, nullptr); + return getLifetimeVariable(tok, errorPath, settings, nullptr); } static bool isNotLifetimeValue(const ValueFlow::Value& val) @@ -3889,7 +3890,7 @@ bool ValueFlow::isLifetimeBorrowed(const Token *tok, const Settings &settings) return true; const Token* parent = nullptr; const ValueType* vt = tok->valueType(); - std::vector vtParents = getParentValueTypes(tok, &settings, &parent); + std::vector vtParents = getParentValueTypes(tok, settings, &parent); for (const ValueType& vtParent : vtParents) { if (isLifetimeBorrowed(vt, &vtParent)) return true; @@ -4150,7 +4151,7 @@ struct LifetimeStore { if (!argtok) return false; bool update = false; - for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(argtok)) { + for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(argtok, settings)) { if (!settings.certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive) continue; ErrorPath er = errorPath; @@ -4212,7 +4213,7 @@ struct LifetimeStore { if (argtok->values().empty()) { ErrorPath er; er.emplace_back(argtok, message); - for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(argtok)) { + for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(argtok, settings)) { if (!settings.certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive) continue; ValueFlow::Value value; @@ -4241,7 +4242,7 @@ struct LifetimeStore { if (!v.isLifetimeValue()) continue; const Token *tok3 = v.tokvalue; - for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(tok3)) { + for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(tok3, settings)) { if (!settings.certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive) continue; ErrorPath er = v.errorPath; @@ -4313,7 +4314,7 @@ struct LifetimeStore { continue; const Token *tok2 = v.tokvalue; ErrorPath er = v.errorPath; - const Variable *var = ValueFlow::getLifetimeVariable(tok2, er); + const Variable *var = ValueFlow::getLifetimeVariable(tok2, er, settings); // TODO: the inserted data is never used er.insert(er.end(), errorPath.cbegin(), errorPath.cend()); if (!var) @@ -4413,7 +4414,7 @@ static void valueFlowLifetimeUserConstructor(Token* tok, continue; if (!ValueFlow::isLifetimeBorrowed(expr, settings)) continue; - const Variable* argvar = ValueFlow::getLifetimeVariable(expr); + const Variable* argvar = ValueFlow::getLifetimeVariable(expr, settings); if (var->isReference() || var->isRValueReference()) { if (argvar && argvar->isArgument() && (argvar->isReference() || argvar->isRValueReference())) { paramCapture[argvar] = LifetimeCapture::ByReference; @@ -4549,8 +4550,8 @@ static void valueFlowLifetimeFunction(Token *tok, TokenList &tokenlist, ErrorLog for (const Token* returnTok : returns) { if (returnTok == tok) continue; - const Variable *returnVar = ValueFlow::getLifetimeVariable(returnTok); - if (returnVar && returnVar->isArgument() && (returnVar->isConst() || !isVariableChanged(returnVar, &settings))) { + const Variable *returnVar = ValueFlow::getLifetimeVariable(returnTok, settings); + if (returnVar && returnVar->isArgument() && (returnVar->isConst() || !isVariableChanged(returnVar, settings))) { LifetimeStore ls = LifetimeStore::fromFunctionArg(f, tok, returnVar, tokenlist, settings, errorLogger); ls.inconclusive = inconclusive; ls.forward = false; @@ -4748,7 +4749,7 @@ static void valueFlowLifetimeConstructor(Token* tok, TokenList& tokenlist, Error tok->previous()->valueType()) { vts = {*tok->previous()->valueType()}; } else if (Token::simpleMatch(tok, "{") && !Token::Match(tok->previous(), "%name%")) { - vts = getParentValueTypes(tok, &settings); + vts = getParentValueTypes(tok, settings); } for (const ValueType& vt : vts) { @@ -4871,7 +4872,7 @@ static bool isDecayedPointer(const Token *tok) static bool isConvertedToView(const Token* tok, const Settings& settings) { - std::vector vtParents = getParentValueTypes(tok, &settings); + std::vector vtParents = getParentValueTypes(tok, settings); return std::any_of(vtParents.cbegin(), vtParents.cend(), [&](const ValueType& vt) { if (!vt.container) return false; @@ -5012,7 +5013,7 @@ static void valueFlowLifetime(TokenList &tokenlist, ErrorLogger &errorLogger, co else if (tok->isUnaryOp("&")) { if (Token::simpleMatch(tok->astParent(), "*")) continue; - for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(tok->astOperand1())) { + for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(tok->astOperand1(), settings)) { if (!settings.certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive) continue; ErrorPath errorPath = lt.errorPath; @@ -5141,7 +5142,7 @@ static void valueFlowLifetime(TokenList &tokenlist, ErrorLogger &errorLogger, co // Check variables else if (tok->variable()) { ErrorPath errorPath; - const Variable * var = ValueFlow::getLifetimeVariable(tok, errorPath); + const Variable * var = ValueFlow::getLifetimeVariable(tok, errorPath, settings); if (!var) continue; if (var->nameToken() == tok) @@ -5316,8 +5317,8 @@ static const Token* findIncompleteVar(const Token* start, const Token* end) static ValueFlow::Value makeConditionValue(long long val, const Token* condTok, bool assume, - bool impossible = false, - const Settings* settings = nullptr, + bool impossible, + const Settings& settings, SourceLocation loc = SourceLocation::current()) { ValueFlow::Value v(val); @@ -5331,7 +5332,7 @@ static ValueFlow::Value makeConditionValue(long long val, v.errorPath.emplace_back(condTok, "Assuming condition '" + condTok->expressionString() + "' is true"); else v.errorPath.emplace_back(condTok, "Assuming condition '" + condTok->expressionString() + "' is false"); - if (settings && settings->debugnormal) + if (settings.debugnormal) setSourceLocation(v, loc, condTok); return v; } @@ -5409,11 +5410,11 @@ static void valueFlowConditionExpressions(const TokenList &tokenlist, const Symb for (const Token* condTok2 : getConditions(condTok, "&&")) { if (is1) { const bool isBool = astIsBool(condTok2) || Token::Match(condTok2, "%comp%|%oror%|&&"); - SameExpressionAnalyzer a1(condTok2, makeConditionValue(1, condTok2, /*assume*/ true, !isBool), tokenlist, settings); // don't set '1' for non-boolean expressions + SameExpressionAnalyzer a1(condTok2, makeConditionValue(1, condTok2, /*assume*/ true, !isBool, settings), tokenlist, settings); // don't set '1' for non-boolean expressions valueFlowGenericForward(startTok, startTok->link(), a1, tokenlist, errorLogger, settings); } - OppositeExpressionAnalyzer a2(true, condTok2, makeConditionValue(0, condTok2, true), tokenlist, settings); + OppositeExpressionAnalyzer a2(true, condTok2, makeConditionValue(0, condTok2, true, false, settings), tokenlist, settings); valueFlowGenericForward(startTok, startTok->link(), a2, tokenlist, errorLogger, settings); } } @@ -5424,11 +5425,11 @@ static void valueFlowConditionExpressions(const TokenList &tokenlist, const Symb if (Token::simpleMatch(startTok->link(), "} else {")) { startTok = startTok->link()->tokAt(2); for (const Token* condTok2:conds) { - SameExpressionAnalyzer a1(condTok2, makeConditionValue(0, condTok2, false), tokenlist, settings); + SameExpressionAnalyzer a1(condTok2, makeConditionValue(0, condTok2, false, false, settings), tokenlist, settings); valueFlowGenericForward(startTok, startTok->link(), a1, tokenlist, errorLogger, settings); if (is1) { - OppositeExpressionAnalyzer a2(true, condTok2, makeConditionValue(1, condTok2, false), tokenlist, settings); + OppositeExpressionAnalyzer a2(true, condTok2, makeConditionValue(1, condTok2, false, false, settings), tokenlist, settings); valueFlowGenericForward(startTok, startTok->link(), a2, tokenlist, errorLogger, settings); } } @@ -5444,11 +5445,11 @@ static void valueFlowConditionExpressions(const TokenList &tokenlist, const Symb continue; } for (const Token* condTok2:conds) { - SameExpressionAnalyzer a1(condTok2, makeConditionValue(0, condTok2, false), tokenlist, settings); + SameExpressionAnalyzer a1(condTok2, makeConditionValue(0, condTok2, false, false, settings), tokenlist, settings); valueFlowGenericForward(startTok->link()->next(), scope2->bodyEnd, a1, tokenlist, errorLogger, settings); if (is1) { - OppositeExpressionAnalyzer a2(true, condTok2, makeConditionValue(1, condTok2, false), tokenlist, settings); + OppositeExpressionAnalyzer a2(true, condTok2, makeConditionValue(1, condTok2, false, false, settings), tokenlist, settings); valueFlowGenericForward(startTok->link()->next(), scope2->bodyEnd, a2, tokenlist, errorLogger, settings); } } @@ -5825,7 +5826,7 @@ static ValueFlow::Value::Bound findVarBound(const Variable* var, ValueFlow::Value::Bound result = ValueFlow::Value::Bound::Point; const Token* next = start; while ((next = findExpressionChangedSkipDeadCode( - var->nameToken(), next->next(), end, &settings, &evaluateKnownValues))) { + var->nameToken(), next->next(), end, settings, &evaluateKnownValues))) { ValueFlow::Value::Bound b = ValueFlow::Value::Bound::Point; if (next->varId() != var->declarationId()) return ValueFlow::Value::Bound::Point; @@ -6465,7 +6466,7 @@ struct ConditionHandler { if (Token::simpleMatch(top->previous(), "for (")) { if (top->astOperand2() && top->astOperand2()->astOperand2() && findExpressionChanged( - cond.vartok, top->astOperand2()->astOperand2(), top->link(), &settings)) { + cond.vartok, top->astOperand2()->astOperand2(), top->link(), settings)) { if (settings.debugwarnings) bailout(tokenlist, errorLogger, @@ -6480,7 +6481,7 @@ struct ConditionHandler { const Token* const block = top->link()->next(); const Token* const end = block->link(); - if (findExpressionChanged(cond.vartok, start, end, &settings)) { + if (findExpressionChanged(cond.vartok, start, end, settings)) { // If its reassigned in loop then analyze from the end if (!Token::Match(tok, "%assign%|++|--") && findExpression(cond.vartok->exprId(), start, end, [&](const Token* tok2) { @@ -6535,12 +6536,12 @@ struct ConditionHandler { return tok; } - static void fillFromPath(ProgramMemory& pm, const Token* top, MathLib::bigint path) + static void fillFromPath(ProgramMemory& pm, const Token* top, MathLib::bigint path, const Settings& settings) { if (path < 1) return; visitAstNodes(top, [&](const Token* tok) { - const ValueFlow::Value* v = ValueFlow::findValue(tok->values(), nullptr, [&](const ValueFlow::Value& v) { + const ValueFlow::Value* v = ValueFlow::findValue(tok->values(), settings, [&](const ValueFlow::Value& v) { return v.path == path && isNonConditionalPossibleIntValue(v); }); if (v == nullptr) @@ -6706,16 +6707,16 @@ struct ConditionHandler { startBlock->link(), cond.vartok->varId(), cond.vartok->variable()->isGlobal(), - &settings)) + settings)) return; // Check if condition in for loop is always false const Token* initTok = getInitTok(top); ProgramMemory pm; - fillFromPath(pm, initTok, path); - fillFromPath(pm, condTok, path); - execute(initTok, pm, nullptr, nullptr, nullptr); + fillFromPath(pm, initTok, path, settings); + fillFromPath(pm, condTok, path, settings); + execute(initTok, pm, nullptr, nullptr, settings); MathLib::bigint result = 1; - execute(condTok, pm, &result, nullptr, nullptr); + execute(condTok, pm, &result, nullptr, settings); if (result == 0) return; // Remove condition since for condition is not redundant @@ -7044,7 +7045,7 @@ static void valueFlowInferCondition(TokenList& tokenlist, } } else if (Token::Match(tok->astParent(), "?|&&|!|%oror%") || Token::Match(tok->astParent()->previous(), "if|while (") || - (astIsPointer(tok) && isUsedAsBool(tok, &settings))) { + (astIsPointer(tok) && isUsedAsBool(tok, settings))) { std::vector result = infer(IntegralInferModel{}, "!=", tok->values(), 0); if (result.size() != 1) continue; @@ -7122,7 +7123,8 @@ struct SymbolicConditionHandler : SimpleConditionHandler { static bool valueFlowForLoop2(const Token *tok, ProgramMemory *memory1, ProgramMemory *memory2, - ProgramMemory *memoryAfter) + ProgramMemory *memoryAfter, + const Settings& settings) { // for ( firstExpression ; secondExpression ; thirdExpression ) const Token *firstExpression = tok->next()->astOperand2()->astOperand1(); @@ -7132,10 +7134,10 @@ static bool valueFlowForLoop2(const Token *tok, ProgramMemory programMemory; MathLib::bigint result(0); bool error = false; - execute(firstExpression, programMemory, &result, &error, nullptr); + execute(firstExpression, programMemory, &result, &error, settings); if (error) return false; - execute(secondExpression, programMemory, &result, &error, nullptr); + execute(secondExpression, programMemory, &result, &error, settings); if (result == 0) // 2nd expression is false => no looping return false; if (error) { @@ -7158,9 +7160,9 @@ static bool valueFlowForLoop2(const Token *tok, int maxcount = 10000; while (result != 0 && !error && --maxcount > 0) { endMemory = programMemory; - execute(thirdExpression, programMemory, &result, &error, nullptr); + execute(thirdExpression, programMemory, &result, &error, settings); if (!error) - execute(secondExpression, programMemory, &result, &error, nullptr); + execute(secondExpression, programMemory, &result, &error, settings); } if (memory1) @@ -7188,7 +7190,7 @@ static void valueFlowForLoopSimplify(Token* const bodyStart, const Token * const bodyEnd = bodyStart->link(); // Is variable modified inside for loop - if (isVariableChanged(bodyStart, bodyEnd, expr->varId(), globalvar, &settings)) + if (isVariableChanged(bodyStart, bodyEnd, expr->varId(), globalvar, settings)) return; for (Token *tok2 = bodyStart->next(); tok2 != bodyEnd; tok2 = tok2->next()) { @@ -7218,8 +7220,8 @@ static void valueFlowForLoopSimplify(Token* const bodyStart, if (Token::Match(tok2, "%oror%|&&")) { const ProgramMemory programMemory(getProgramMemory(tok2->astTop(), expr, ValueFlow::Value(value), settings)); - if ((tok2->str() == "&&" && !conditionIsTrue(tok2->astOperand1(), programMemory, &settings)) || - (tok2->str() == "||" && !conditionIsFalse(tok2->astOperand1(), programMemory, &settings))) { + if ((tok2->str() == "&&" && !conditionIsTrue(tok2->astOperand1(), programMemory, settings)) || + (tok2->str() == "||" && !conditionIsFalse(tok2->astOperand1(), programMemory, settings))) { // Skip second expression.. Token *parent = tok2; while (parent && parent->str() == tok2->str()) @@ -7243,11 +7245,11 @@ static void valueFlowForLoopSimplify(Token* const bodyStart, if ((tok2->str() == "&&" && conditionIsFalse(tok2->astOperand1(), getProgramMemory(tok2->astTop(), expr, ValueFlow::Value(value), settings), - &settings)) || + settings)) || (tok2->str() == "||" && conditionIsTrue(tok2->astOperand1(), getProgramMemory(tok2->astTop(), expr, ValueFlow::Value(value), settings), - &settings))) + settings))) break; if (Token::simpleMatch(tok2, ") {")) { @@ -7348,7 +7350,7 @@ static void valueFlowForLoop(TokenList &tokenlist, const SymbolDatabase& symbold valueFlowForLoopSimplifyAfter(tok, varid, afterValue, tokenlist, errorLogger, settings); } else { ProgramMemory mem1, mem2, memAfter; - if (valueFlowForLoop2(tok, &mem1, &mem2, &memAfter)) { + if (valueFlowForLoop2(tok, &mem1, &mem2, &memAfter, settings)) { for (const auto& p : mem1) { if (!p.second.isIntValue()) continue; @@ -7725,7 +7727,7 @@ static void valueFlowLibraryFunction(Token *tok, const std::string &returnValue, if (returnValue.find("arg") != std::string::npos && argValues.empty()) return; productParams(settings, argValues, [&](const std::unordered_map& arg) { - ValueFlow::Value value = evaluateLibraryFunction(arg, returnValue, &settings, tok->isCpp()); + ValueFlow::Value value = evaluateLibraryFunction(arg, returnValue, settings, tok->isCpp()); if (value.isUninitValue()) return; ValueFlow::Value::ValueKind kind = ValueFlow::Value::ValueKind::Known; @@ -8225,7 +8227,7 @@ static bool isContainerSizeChangedByFunction(const Token* tok, } bool inconclusive = false; - const bool isChanged = isVariableChangedByFunctionCall(tok, indirect, &settings, &inconclusive); + const bool isChanged = isVariableChangedByFunctionCall(tok, indirect, settings, &inconclusive); return (isChanged || inconclusive); } @@ -8885,7 +8887,7 @@ static void valueFlowContainerSize(TokenList& tokenlist, continue; } if (nameToken->astTop() && Token::Match(nameToken->astTop()->previous(), "for|while")) - known = !isVariableChanged(var, &settings); + known = !isVariableChanged(var, settings); std::vector values{ValueFlow::Value{size}}; values.back().valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; if (known) @@ -9667,7 +9669,7 @@ std::string ValueFlow::eitherTheConditionIsRedundant(const Token *condition) } const ValueFlow::Value* ValueFlow::findValue(const std::list& values, - const Settings* settings, + const Settings& settings, const std::function &pred) { const ValueFlow::Value* ret = nullptr; @@ -9679,10 +9681,10 @@ const ValueFlow::Value* ValueFlow::findValue(const std::list& break; } } - if (settings && ret) { - if (ret->isInconclusive() && !settings->certainty.isEnabled(Certainty::inconclusive)) + if (ret) { + if (ret->isInconclusive() && !settings.certainty.isEnabled(Certainty::inconclusive)) return nullptr; - if (ret->condition && !settings->severity.isEnabled(Severity::warning)) + if (ret->condition && !settings.severity.isEnabled(Severity::warning)) return nullptr; } return ret; diff --git a/lib/valueflow.h b/lib/valueflow.h index acd785a3432..25a266b1aca 100644 --- a/lib/valueflow.h +++ b/lib/valueflow.h @@ -62,7 +62,7 @@ namespace ValueFlow { size_t getSizeOf(const ValueType &vt, const Settings &settings); const Value* findValue(const std::list& values, - const Settings* settings, + const Settings& settings, const std::function &pred); std::vector isOutOfBounds(const Value& size, const Token* indexTok, bool possible = true); @@ -110,14 +110,15 @@ namespace ValueFlow { Value& value); std::vector getLifetimeTokens(const Token* tok, + const Settings& settings, bool escape = false, Value::ErrorPath errorPath = Value::ErrorPath{}); - bool hasLifetimeToken(const Token* tok, const Token* lifetime); + bool hasLifetimeToken(const Token* tok, const Token* lifetime, const Settings& settings); - const Variable* getLifetimeVariable(const Token* tok, Value::ErrorPath& errorPath, bool* addressOf = nullptr); + const Variable* getLifetimeVariable(const Token* tok, Value::ErrorPath& errorPath, const Settings& settings, bool* addressOf = nullptr); - const Variable* getLifetimeVariable(const Token* tok); + const Variable* getLifetimeVariable(const Token* tok, const Settings& settings); bool isLifetimeBorrowed(const Token *tok, const Settings &settings); diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index 6bfad47f6a1..67bc8eb8b24 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -262,7 +262,7 @@ $(libcppdir)/errortypes.o: ../lib/errortypes.cpp ../lib/config.h ../lib/errortyp $(libcppdir)/forwardanalyzer.o: ../lib/forwardanalyzer.cpp ../lib/addoninfo.h ../lib/analyzer.h ../lib/astutils.h ../lib/color.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/forwardanalyzer.cpp -$(libcppdir)/fwdanalysis.o: ../lib/fwdanalysis.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/fwdanalysis.o: ../lib/fwdanalysis.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/fwdanalysis.cpp $(libcppdir)/importproject.o: ../lib/importproject.cpp ../externals/picojson/picojson.h ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/config.h ../lib/errortypes.h ../lib/filesettings.h ../lib/importproject.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h diff --git a/test/testastutils.cpp b/test/testastutils.cpp index 869e991ed54..3ac3df64071 100644 --- a/test/testastutils.cpp +++ b/test/testastutils.cpp @@ -169,12 +169,11 @@ class TestAstUtils : public TestFixture { #define isSameExpression(...) isSameExpression_(__FILE__, __LINE__, __VA_ARGS__) bool isSameExpression_(const char* file, int line, const char code[], const char tokStr1[], const char tokStr2[], bool cpp) { - Library library; SimpleTokenizer tokenizer(settingsDefault, *this); ASSERT_LOC(tokenizer.tokenize(code, cpp), file, line); const Token * const tok1 = Token::findsimplematch(tokenizer.tokens(), tokStr1, strlen(tokStr1)); const Token * const tok2 = Token::findsimplematch(tok1->next(), tokStr2, strlen(tokStr2)); - return (isSameExpression)(false, tok1, tok2, library, false, true, nullptr); + return (isSameExpression)(false, tok1, tok2, settingsDefault, false, true); } void isSameExpressionTestInternal(bool cpp) { @@ -221,7 +220,7 @@ class TestAstUtils : public TestFixture { ASSERT_LOC(tokenizer.tokenize(code), file, line); const Token * const tok1 = Token::findsimplematch(tokenizer.tokens(), startPattern, strlen(startPattern)); const Token * const tok2 = Token::findsimplematch(tokenizer.tokens(), endPattern, strlen(endPattern)); - return (isVariableChanged)(tok1, tok2, 1, false, &settingsDefault); + return (isVariableChanged)(tok1, tok2, 1, false, settingsDefault); } void isVariableChangedTest() { @@ -255,7 +254,7 @@ class TestAstUtils : public TestFixture { const Token * const argtok = Token::findmatch(tokenizer.tokens(), pattern); ASSERT_LOC(argtok, file, line); int indirect = (argtok->variable() && argtok->variable()->isArray()); - return (isVariableChangedByFunctionCall)(argtok, indirect, &settingsDefault, inconclusive); + return (isVariableChangedByFunctionCall)(argtok, indirect, settingsDefault, inconclusive); } void isVariableChangedByFunctionCallTest() { @@ -397,7 +396,7 @@ class TestAstUtils : public TestFixture { const Token* const start = Token::findsimplematch(tokenizer.tokens(), startPattern, strlen(startPattern)); const Token* const end = Token::findsimplematch(start, endPattern, strlen(endPattern)); const Token* const expr = Token::findsimplematch(tokenizer.tokens(), var, strlen(var)); - return (findExpressionChanged)(expr, start, end, &settings); + return (findExpressionChanged)(expr, start, end, settings); } void isExpressionChangedTest() @@ -451,7 +450,7 @@ class TestAstUtils : public TestFixture { const Token * const argtok = Token::findmatch(tokenizer.tokens(), pattern); if (!argtok) return Result::Fail; - return ::isUsedAsBool(argtok) ? Result::True : Result::False; + return ::isUsedAsBool(argtok, settingsDefault) ? Result::True : Result::False; } void isUsedAsBool() { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 7e44bf56a21..b01d5f8800f 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -707,7 +707,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(false, result); ASSERT(nullptr == vartok); ASSERT(nullptr == typetok); - Variable v(nullptr, nullptr, nullptr, 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(nullptr, nullptr, nullptr, 0, AccessControl::Public, nullptr, nullptr, settings1); } void test_isVariableDeclarationIdentifiesSimpleDeclaration() { @@ -717,7 +717,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("int", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(false == v.isPointer()); ASSERT(false == v.isReference()); @@ -730,7 +730,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("int", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(false == v.isPointer()); ASSERT(false == v.isReference()); @@ -743,7 +743,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("int", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(false == v.isPointer()); ASSERT(false == v.isReference()); @@ -756,7 +756,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("int", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(false == v.isPointer()); ASSERT(false == v.isReference()); @@ -769,7 +769,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("string", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(false == v.isPointer()); ASSERT(false == v.isReference()); @@ -782,7 +782,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("string", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(false == v.isPointer()); ASSERT(false == v.isReference()); @@ -795,7 +795,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("EE", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(false == v.isPointer()); ASSERT(false == v.isReference()); @@ -809,7 +809,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result1); ASSERT_EQUALS("p", vartok->str()); ASSERT_EQUALS("int", typetok->str()); - Variable v1(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v1(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v1.isArray()); ASSERT(true == v1.isPointer()); ASSERT(false == v1.isReference()); @@ -817,7 +817,7 @@ class TestSymbolDatabase : public TestFixture { { reset(); const SimpleTokenizer constpointer(*this, "const int* p;"); - Variable v2(constpointer.tokens()->tokAt(3), constpointer.tokens()->next(), constpointer.tokens()->tokAt(2), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v2(constpointer.tokens()->tokAt(3), constpointer.tokens()->next(), constpointer.tokens()->tokAt(2), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v2.isArray()); ASSERT(true == v2.isPointer()); ASSERT(false == v2.isConst()); @@ -830,7 +830,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result2); ASSERT_EQUALS("p", vartok->str()); ASSERT_EQUALS("int", typetok->str()); - Variable v3(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v3(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v3.isArray()); ASSERT(true == v3.isPointer()); ASSERT(true == v3.isConst()); @@ -866,7 +866,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("first", vartok->str()); ASSERT_EQUALS("int", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(false == v.isPointer()); ASSERT(false == v.isReference()); @@ -879,7 +879,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("p", vartok->str()); ASSERT_EQUALS("EE", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(true == v.isPointer()); ASSERT(false == v.isReference()); @@ -892,7 +892,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("pp", vartok->str()); ASSERT_EQUALS("int", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(true == v.isPointer()); ASSERT(false == v.isReference()); @@ -905,7 +905,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("p", vartok->str()); ASSERT_EQUALS("int", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(true == v.isPointer()); ASSERT(false == v.isReference()); @@ -918,7 +918,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("v", vartok->str()); ASSERT_EQUALS("string", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(true == v.isArray()); ASSERT(false == v.isPointer()); ASSERT(false == v.isPointerArray()); @@ -932,7 +932,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("a", vartok->str()); ASSERT_EQUALS("A", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isPointer()); ASSERT(true == v.isArray()); ASSERT(false == v.isPointerToArray()); @@ -947,7 +947,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("a", vartok->str()); ASSERT_EQUALS("A", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(true == v.isPointer()); ASSERT(false == v.isArray()); ASSERT(true == v.isPointerToArray()); @@ -962,7 +962,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("a", vartok->str()); ASSERT_EQUALS("A", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(true == v.isPointer()); ASSERT(false == v.isArray()); ASSERT(true == v.isPointerToArray()); @@ -977,7 +977,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("a", vartok->str()); ASSERT_EQUALS("A", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(true == v.isPointer()); ASSERT(false == v.isArray()); ASSERT(true == v.isPointerToArray()); @@ -992,7 +992,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("a", vartok->str()); ASSERT_EQUALS("int", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isPointer()); ASSERT(true == v.isArray()); ASSERT(false == v.isPointerToArray()); @@ -1008,7 +1008,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("chars", vartok->str()); ASSERT_EQUALS("set", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(true == v.isPointer()); ASSERT(false == v.isReference()); @@ -1021,7 +1021,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("ints", vartok->str()); ASSERT_EQUALS("deque", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(true == v.isPointer()); ASSERT(false == v.isReference()); @@ -1034,7 +1034,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("ints", vartok->str()); ASSERT_EQUALS("deque", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(true == v.isArray()); ASSERT(false == v.isPointer()); ASSERT(false == v.isReference()); @@ -1047,7 +1047,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("ints", vartok->str()); ASSERT_EQUALS("vector", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(false == v.isPointer()); ASSERT(false == v.isReference()); @@ -1060,7 +1060,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("floats", vartok->str()); ASSERT_EQUALS("const_iterator", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(false == v.isPointer()); ASSERT(false == v.isReference()); @@ -1073,7 +1073,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS(true, result); ASSERT_EQUALS("intsets", vartok->str()); ASSERT_EQUALS("deque", typetok->str()); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(false == v.isPointer()); ASSERT(false == v.isReference()); @@ -1085,7 +1085,7 @@ class TestSymbolDatabase : public TestFixture { GET_SYMBOL_DB("int& foo;"); const bool result1 = db->scopeList.front().isVariableDeclaration(tokenizer.tokens(), vartok, typetok); ASSERT_EQUALS(true, result1); - Variable v1(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v1(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v1.isArray()); ASSERT(false == v1.isPointer()); ASSERT(true == v1.isReference()); @@ -1095,7 +1095,7 @@ class TestSymbolDatabase : public TestFixture { GET_SYMBOL_DB("foo*& bar;"); const bool result2 = db->scopeList.front().isVariableDeclaration(tokenizer.tokens(), vartok, typetok); ASSERT_EQUALS(true, result2); - Variable v2(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v2(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v2.isArray()); ASSERT(true == v2.isPointer()); ASSERT(true == v2.isReference()); @@ -1105,7 +1105,7 @@ class TestSymbolDatabase : public TestFixture { GET_SYMBOL_DB("std::vector& foo;"); const bool result3 = db->scopeList.front().isVariableDeclaration(tokenizer.tokens(), vartok, typetok); ASSERT_EQUALS(true, result3); - Variable v3(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v3(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v3.isArray()); ASSERT(false == v3.isPointer()); ASSERT(true == v3.isReference()); @@ -1131,7 +1131,7 @@ class TestSymbolDatabase : public TestFixture { GET_SYMBOL_DB("std::string const* s;"); const bool result = db->scopeList.front().isVariableDeclaration(tokenizer.tokens()->next(), vartok, typetok); ASSERT_EQUALS(true, result); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(true == v.isPointer()); ASSERT(false == v.isReference()); @@ -1142,7 +1142,7 @@ class TestSymbolDatabase : public TestFixture { GET_SYMBOL_DB("int&& i;"); const bool result = db->scopeList.front().isVariableDeclaration(tokenizer.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(false == v.isPointer()); ASSERT(true == v.isReference()); @@ -1575,7 +1575,7 @@ class TestSymbolDatabase : public TestFixture { GET_SYMBOL_DB("std::string s;"); const bool result = db->scopeList.front().isVariableDeclaration(tokenizer.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); - Variable v(vartok, tokenizer.tokens(), tokenizer.list.back(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, tokenizer.tokens(), tokenizer.list.back(), 0, AccessControl::Public, nullptr, nullptr, settings1); static const std::set types = { "string", "wstring" }; static const std::set no_types = { "set" }; ASSERT_EQUALS(true, v.isStlType()); @@ -1588,7 +1588,7 @@ class TestSymbolDatabase : public TestFixture { GET_SYMBOL_DB("std::vector v;"); const bool result = db->scopeList.front().isVariableDeclaration(tokenizer.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); - Variable v(vartok, tokenizer.tokens(), tokenizer.list.back(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, tokenizer.tokens(), tokenizer.list.back(), 0, AccessControl::Public, nullptr, nullptr, settings1); static const std::set types = { "bitset", "set", "vector", "wstring" }; static const std::set no_types = { "bitset", "map", "set" }; ASSERT_EQUALS(true, v.isStlType()); @@ -1601,7 +1601,7 @@ class TestSymbolDatabase : public TestFixture { GET_SYMBOL_DB("SomeClass s;"); const bool result = db->scopeList.front().isVariableDeclaration(tokenizer.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); - Variable v(vartok, tokenizer.tokens(), tokenizer.list.back(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, tokenizer.tokens(), tokenizer.list.back(), 0, AccessControl::Public, nullptr, nullptr, settings1); static const std::set types = { "bitset", "set", "vector" }; ASSERT_EQUALS(false, v.isStlType()); ASSERT_EQUALS(false, v.isStlType(types)); @@ -1614,7 +1614,7 @@ class TestSymbolDatabase : public TestFixture { GET_SYMBOL_DB("char* const * s;"); const bool result = db->scopeList.front().isVariableDeclaration(tokenizer.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(true == v.isPointer()); ASSERT(false == v.isReference()); @@ -1625,7 +1625,7 @@ class TestSymbolDatabase : public TestFixture { GET_SYMBOL_DB("char* volatile * s;"); const bool result = db->scopeList.front().isVariableDeclaration(tokenizer.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(true == v.isPointer()); ASSERT(false == v.isReference()); @@ -1636,7 +1636,7 @@ class TestSymbolDatabase : public TestFixture { GET_SYMBOL_DB("char* const volatile * s;"); const bool result = db->scopeList.front().isVariableDeclaration(tokenizer.tokens(), vartok, typetok); ASSERT_EQUALS(true, result); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(true == v.isPointer()); ASSERT(false == v.isReference()); @@ -1647,7 +1647,7 @@ class TestSymbolDatabase : public TestFixture { GET_SYMBOL_DB("const char* const volatile * const volatile * const volatile * const volatile s;"); const bool result = db->scopeList.front().isVariableDeclaration(tokenizer.tokens()->next(), vartok, typetok); ASSERT_EQUALS(true, result); - Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, &settings1); + Variable v(vartok, typetok, vartok->previous(), 0, AccessControl::Public, nullptr, nullptr, settings1); ASSERT(false == v.isArray()); ASSERT(true == v.isPointer()); ASSERT(false == v.isReference());