made `ForwardTraversal::mSettings` and `ReverseTraversal::mSettings` references / adjusted some calling code to use references as well (#4858)

This commit is contained in:
Oliver Stöneberg 2023-03-07 12:26:17 +01:00 committed by GitHub
parent 87d9c8fbc5
commit 00fd3d92c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 42 deletions

View File

@ -50,11 +50,11 @@ struct OnExit {
struct ForwardTraversal { struct ForwardTraversal {
enum class Progress { Continue, Break, Skip }; enum class Progress { Continue, Break, Skip };
enum class Terminate { None, Bail, Escape, Modified, Inconclusive, Conditional }; enum class Terminate { None, Bail, Escape, Modified, Inconclusive, Conditional };
ForwardTraversal(const ValuePtr<Analyzer>& analyzer, const Settings* settings) ForwardTraversal(const ValuePtr<Analyzer>& analyzer, const Settings& settings)
: analyzer(analyzer), settings(settings), actions(Analyzer::Action::None), analyzeOnly(false), analyzeTerminate(false) : analyzer(analyzer), settings(settings), actions(Analyzer::Action::None), analyzeOnly(false), analyzeTerminate(false)
{} {}
ValuePtr<Analyzer> analyzer; ValuePtr<Analyzer> analyzer;
const Settings* settings; const Settings& settings;
Analyzer::Action actions; Analyzer::Action actions;
bool analyzeOnly; bool analyzeOnly;
bool analyzeTerminate; bool analyzeTerminate;
@ -138,7 +138,7 @@ struct ForwardTraversal {
traverseRecursive(tok->astOperand2(), f, traverseUnknown); traverseRecursive(tok->astOperand2(), f, traverseUnknown);
traverseRecursive(tok->astOperand1(), f, traverseUnknown); traverseRecursive(tok->astOperand1(), f, traverseUnknown);
return Break(Analyzer::Terminate::Escape); return Break(Analyzer::Terminate::Escape);
} else if (Token::Match(tok, "%name% (") && isEscapeFunction(tok, &settings->library)) { } else if (Token::Match(tok, "%name% (") && isEscapeFunction(tok, &settings.library)) {
// Traverse the parameters of the function before escaping // Traverse the parameters of the function before escaping
traverseRecursive(tok->next()->astOperand2(), f, traverseUnknown); traverseRecursive(tok->next()->astOperand2(), f, traverseUnknown);
return Break(Analyzer::Terminate::Escape); return Break(Analyzer::Terminate::Escape);
@ -315,7 +315,7 @@ struct ForwardTraversal {
for (const Token* tok=start; tok != end; tok = tok->previous()) { for (const Token* tok=start; tok != end; tok = tok->previous()) {
if (Token::simpleMatch(tok, "}")) { if (Token::simpleMatch(tok, "}")) {
const Token* ftok = nullptr; const Token* ftok = nullptr;
const bool r = isReturnScope(tok, &settings->library, &ftok); const bool r = isReturnScope(tok, &settings.library, &ftok);
if (r) if (r)
return true; return true;
} }
@ -325,7 +325,7 @@ struct ForwardTraversal {
bool isEscapeScope(const Token* endBlock, bool& unknown) const { bool isEscapeScope(const Token* endBlock, bool& unknown) const {
const Token* ftok = nullptr; const Token* ftok = nullptr;
const bool r = isReturnScope(endBlock, &settings->library, &ftok); const bool r = isReturnScope(endBlock, &settings.library, &ftok);
if (!r && ftok) if (!r && ftok)
unknown = true; unknown = true;
return r; return r;
@ -388,13 +388,13 @@ struct ForwardTraversal {
if (stepTok) { if (stepTok) {
std::pair<const Token*, const Token*> exprToks = stepTok->findExpressionStartEndTokens(); std::pair<const Token*, const Token*> exprToks = stepTok->findExpressionStartEndTokens();
if (exprToks.first != nullptr && exprToks.second != nullptr) if (exprToks.first != nullptr && exprToks.second != nullptr)
stepChangesCond |= isExpressionChanged(condTok, exprToks.first, exprToks.second->next(), settings, true); stepChangesCond |= isExpressionChanged(condTok, exprToks.first, exprToks.second->next(), &settings, true);
} }
const bool bodyChangesCond = isExpressionChanged(condTok, endBlock->link(), endBlock, settings, true); const bool bodyChangesCond = isExpressionChanged(condTok, endBlock->link(), endBlock, &settings, true);
// Check for mutation in the condition // Check for mutation in the condition
const bool condChanged = const bool condChanged =
nullptr != findAstNode(condTok, [&](const Token* tok) { nullptr != findAstNode(condTok, [&](const Token* tok) {
return isVariableChanged(tok, 0, settings, true); return isVariableChanged(tok, 0, &settings, true);
}); });
const bool changed = stepChangesCond || bodyChangesCond || condChanged; const bool changed = stepChangesCond || bodyChangesCond || condChanged;
if (!changed) if (!changed)
@ -896,14 +896,14 @@ struct ForwardTraversal {
} }
}; };
Analyzer::Result valueFlowGenericForward(Token* start, const Token* end, const ValuePtr<Analyzer>& a, const Settings* settings) Analyzer::Result valueFlowGenericForward(Token* start, const Token* end, const ValuePtr<Analyzer>& a, const Settings& settings)
{ {
ForwardTraversal ft{a, settings}; ForwardTraversal ft{a, settings};
ft.updateRange(start, end); ft.updateRange(start, end);
return Analyzer::Result{ ft.actions, ft.terminate }; return Analyzer::Result{ ft.actions, ft.terminate };
} }
Analyzer::Result valueFlowGenericForward(Token* start, const ValuePtr<Analyzer>& a, const Settings* settings) Analyzer::Result valueFlowGenericForward(Token* start, const ValuePtr<Analyzer>& a, const Settings& settings)
{ {
if (Settings::terminated()) if (Settings::terminated())
throw TerminateException(); throw TerminateException();

View File

@ -28,8 +28,8 @@ template<class T> class ValuePtr;
Analyzer::Result valueFlowGenericForward(Token* start, Analyzer::Result valueFlowGenericForward(Token* start,
const Token* end, const Token* end,
const ValuePtr<Analyzer>& a, const ValuePtr<Analyzer>& a,
const Settings* settings); const Settings& settings);
Analyzer::Result valueFlowGenericForward(Token* start, const ValuePtr<Analyzer>& a, const Settings* settings); Analyzer::Result valueFlowGenericForward(Token* start, const ValuePtr<Analyzer>& a, const Settings& settings);
#endif #endif

View File

@ -36,11 +36,11 @@
#include <vector> #include <vector>
struct ReverseTraversal { struct ReverseTraversal {
ReverseTraversal(const ValuePtr<Analyzer>& analyzer, const Settings* settings) ReverseTraversal(const ValuePtr<Analyzer>& analyzer, const Settings& settings)
: analyzer(analyzer), settings(settings) : analyzer(analyzer), settings(settings)
{} {}
ValuePtr<Analyzer> analyzer; ValuePtr<Analyzer> analyzer;
const Settings* settings; const Settings& settings;
std::pair<bool, bool> evalCond(const Token* tok) const { std::pair<bool, bool> evalCond(const Token* tok) const {
std::vector<MathLib::bigint> result = analyzer->evaluate(tok); std::vector<MathLib::bigint> result = analyzer->evaluate(tok);
@ -244,7 +244,7 @@ struct ReverseTraversal {
// Assignment to // Assignment to
} else if (lhsAction.matches() && !assignTok->astOperand2()->hasKnownIntValue() && } else if (lhsAction.matches() && !assignTok->astOperand2()->hasKnownIntValue() &&
assignTok->astOperand2()->exprId() > 0 && assignTok->astOperand2()->exprId() > 0 &&
isConstExpression(assignTok->astOperand2(), settings->library, true)) { isConstExpression(assignTok->astOperand2(), settings.library, true)) {
const std::string info = "Assignment to '" + assignTok->expressionString() + "'"; const std::string info = "Assignment to '" + assignTok->expressionString() + "'";
ValuePtr<Analyzer> a = analyzer->reanalyze(assignTok->astOperand2(), info); ValuePtr<Analyzer> a = analyzer->reanalyze(assignTok->astOperand2(), info);
if (a) { if (a) {
@ -388,13 +388,13 @@ struct ReverseTraversal {
} }
}; };
void valueFlowGenericReverse(Token* start, const ValuePtr<Analyzer>& a, const Settings* settings) void valueFlowGenericReverse(Token* start, const ValuePtr<Analyzer>& a, const Settings& settings)
{ {
ReverseTraversal rt{a, settings}; ReverseTraversal rt{a, settings};
rt.traverse(start); rt.traverse(start);
} }
void valueFlowGenericReverse(Token* start, const Token* end, const ValuePtr<Analyzer>& a, const Settings* settings) void valueFlowGenericReverse(Token* start, const Token* end, const ValuePtr<Analyzer>& a, const Settings& settings)
{ {
ReverseTraversal rt{a, settings}; ReverseTraversal rt{a, settings};
rt.traverse(start, end); rt.traverse(start, end);

View File

@ -25,7 +25,7 @@ class Token;
template<class T> template<class T>
class ValuePtr; class ValuePtr;
void valueFlowGenericReverse(Token* start, const ValuePtr<Analyzer>& a, const Settings* settings); void valueFlowGenericReverse(Token* start, const ValuePtr<Analyzer>& a, const Settings& settings);
void valueFlowGenericReverse(Token* start, const Token* end, const ValuePtr<Analyzer>& a, const Settings* settings); void valueFlowGenericReverse(Token* start, const Token* end, const ValuePtr<Analyzer>& a, const Settings& settings);
#endif #endif

View File

@ -2000,7 +2000,7 @@ static Analyzer::Result valueFlowForward(Token* startToken,
return valueFlowGenericForward(startToken, return valueFlowGenericForward(startToken,
endToken, endToken,
makeAnalyzer(exprTok, std::move(value), tokenlist, settings), makeAnalyzer(exprTok, std::move(value), tokenlist, settings),
settings); *settings);
} }
static Analyzer::Result valueFlowForward(Token* startToken, static Analyzer::Result valueFlowForward(Token* startToken,
@ -2045,7 +2045,7 @@ static Analyzer::Result valueFlowForwardRecursive(Token* top,
if (settings->debugnormal) if (settings->debugnormal)
setSourceLocation(v, loc, top); setSourceLocation(v, loc, top);
result.update( result.update(
valueFlowGenericForward(top, makeAnalyzer(exprTok, std::move(v), tokenlist, settings), settings)); valueFlowGenericForward(top, makeAnalyzer(exprTok, std::move(v), tokenlist, settings), *settings));
} }
return result; return result;
} }
@ -2061,7 +2061,7 @@ static void valueFlowReverse(Token* tok,
for (ValueFlow::Value& v : values) { for (ValueFlow::Value& v : values) {
if (settings->debugnormal) if (settings->debugnormal)
setSourceLocation(v, loc, tok); setSourceLocation(v, loc, tok);
valueFlowGenericReverse(tok, endToken, makeReverseAnalyzer(varToken, std::move(v), tokenlist, settings), settings); valueFlowGenericReverse(tok, endToken, makeReverseAnalyzer(varToken, std::move(v), tokenlist, settings), *settings);
} }
} }
@ -5109,12 +5109,12 @@ static const Scope* getLoopScope(const Token* tok)
} }
// //
static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings) static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings &settings)
{ {
for (const Scope * scope : symboldatabase->functionScopes) { for (const Scope * scope : symboldatabase->functionScopes) {
if (const Token* incompleteTok = findIncompleteVar(scope->bodyStart, scope->bodyEnd)) { if (const Token* incompleteTok = findIncompleteVar(scope->bodyStart, scope->bodyEnd)) {
if (incompleteTok->isIncompleteVar()) { if (incompleteTok->isIncompleteVar()) {
if (settings->debugwarnings) if (settings.debugwarnings)
bailoutIncompleteVar(tokenlist, errorLogger, incompleteTok, "Skipping function due to incomplete variable " + incompleteTok->str()); bailoutIncompleteVar(tokenlist, errorLogger, incompleteTok, "Skipping function due to incomplete variable " + incompleteTok->str());
break; break;
} }
@ -5132,7 +5132,7 @@ static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase*
continue; continue;
if (condTok->hasKnownIntValue()) if (condTok->hasKnownIntValue())
continue; continue;
if (!isConstExpression(condTok, settings->library, tokenlist->isCPP())) if (!isConstExpression(condTok, settings.library, tokenlist->isCPP()))
continue; continue;
const bool is1 = (condTok->isComparisonOp() || condTok->tokType() == Token::eLogicalOp || astIsBool(condTok)); const bool is1 = (condTok->isComparisonOp() || condTok->tokType() == Token::eLogicalOp || astIsBool(condTok));
@ -5142,11 +5142,11 @@ static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase*
for (const Token* condTok2 : getConditions(condTok, "&&")) { for (const Token* condTok2 : getConditions(condTok, "&&")) {
if (is1) { if (is1) {
const bool isBool = astIsBool(condTok2) || Token::Match(condTok2, "%comp%|%oror%|&&"); 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), tokenlist, &settings); // don't set '1' for non-boolean expressions
valueFlowGenericForward(startTok, startTok->link(), a1, settings); valueFlowGenericForward(startTok, startTok->link(), a1, settings);
} }
OppositeExpressionAnalyzer a2(true, condTok2, makeConditionValue(0, condTok2, true), tokenlist, settings); OppositeExpressionAnalyzer a2(true, condTok2, makeConditionValue(0, condTok2, true), tokenlist, &settings);
valueFlowGenericForward(startTok, startTok->link(), a2, settings); valueFlowGenericForward(startTok, startTok->link(), a2, settings);
} }
} }
@ -5157,18 +5157,18 @@ static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase*
if (Token::simpleMatch(startTok->link(), "} else {")) { if (Token::simpleMatch(startTok->link(), "} else {")) {
startTok = startTok->link()->tokAt(2); startTok = startTok->link()->tokAt(2);
for (const Token* condTok2:conds) { for (const Token* condTok2:conds) {
SameExpressionAnalyzer a1(condTok2, makeConditionValue(0, condTok2, false), tokenlist, settings); SameExpressionAnalyzer a1(condTok2, makeConditionValue(0, condTok2, false), tokenlist, &settings);
valueFlowGenericForward(startTok, startTok->link(), a1, settings); valueFlowGenericForward(startTok, startTok->link(), a1, settings);
if (is1) { if (is1) {
OppositeExpressionAnalyzer a2(true, condTok2, makeConditionValue(1, condTok2, false), tokenlist, settings); OppositeExpressionAnalyzer a2(true, condTok2, makeConditionValue(1, condTok2, false), tokenlist, &settings);
valueFlowGenericForward(startTok, startTok->link(), a2, settings); valueFlowGenericForward(startTok, startTok->link(), a2, settings);
} }
} }
} }
// Check if the block terminates early // Check if the block terminates early
if (isEscapeScope(blockTok, tokenlist, settings)) { if (isEscapeScope(blockTok, tokenlist, &settings)) {
const Scope* scope2 = scope; const Scope* scope2 = scope;
// If escaping a loop then only use the loop scope // If escaping a loop then only use the loop scope
if (isBreakOrContinueScope(blockTok->link())) { if (isBreakOrContinueScope(blockTok->link())) {
@ -5177,11 +5177,11 @@ static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase*
continue; continue;
} }
for (const Token* condTok2:conds) { for (const Token* condTok2:conds) {
SameExpressionAnalyzer a1(condTok2, makeConditionValue(0, condTok2, false), tokenlist, settings); SameExpressionAnalyzer a1(condTok2, makeConditionValue(0, condTok2, false), tokenlist, &settings);
valueFlowGenericForward(startTok->link()->next(), scope2->bodyEnd, a1, settings); valueFlowGenericForward(startTok->link()->next(), scope2->bodyEnd, a1, settings);
if (is1) { if (is1) {
OppositeExpressionAnalyzer a2(true, condTok2, makeConditionValue(1, condTok2, false), tokenlist, settings); OppositeExpressionAnalyzer a2(true, condTok2, makeConditionValue(1, condTok2, false), tokenlist, &settings);
valueFlowGenericForward(startTok->link()->next(), scope2->bodyEnd, a2, settings); valueFlowGenericForward(startTok->link()->next(), scope2->bodyEnd, a2, settings);
} }
} }
@ -7210,12 +7210,12 @@ bool productParams(const std::unordered_map<Key, std::list<ValueFlow::Value>>& v
static void valueFlowInjectParameter(TokenList* tokenlist, static void valueFlowInjectParameter(TokenList* tokenlist,
SymbolDatabase* symboldatabase, SymbolDatabase* symboldatabase,
ErrorLogger* errorLogger, ErrorLogger* errorLogger,
const Settings* settings, const Settings& settings,
const Scope* functionScope, const Scope* functionScope,
const std::unordered_map<const Variable*, std::list<ValueFlow::Value>>& vars) const std::unordered_map<const Variable*, std::list<ValueFlow::Value>>& vars)
{ {
const bool r = productParams(vars, [&](const std::unordered_map<const Variable*, ValueFlow::Value>& arg) { const bool r = productParams(vars, [&](const std::unordered_map<const Variable*, ValueFlow::Value>& arg) {
MultiValueFlowAnalyzer a(arg, tokenlist, settings, symboldatabase); MultiValueFlowAnalyzer a(arg, tokenlist, &settings, symboldatabase);
valueFlowGenericForward(const_cast<Token*>(functionScope->bodyStart), functionScope->bodyEnd, a, settings); valueFlowGenericForward(const_cast<Token*>(functionScope->bodyStart), functionScope->bodyEnd, a, settings);
}); });
if (!r) { if (!r) {
@ -7223,7 +7223,7 @@ static void valueFlowInjectParameter(TokenList* tokenlist,
Function* f = functionScope->function; Function* f = functionScope->function;
if (f) if (f)
fname = f->name(); fname = f->name();
if (settings->debugwarnings) if (settings.debugwarnings)
bailout(tokenlist, errorLogger, functionScope->bodyStart, "Too many argument passed to " + fname); bailout(tokenlist, errorLogger, functionScope->bodyStart, "Too many argument passed to " + fname);
} }
} }
@ -7387,7 +7387,7 @@ IteratorRange<Iterator> MakeIteratorRange(Iterator start, Iterator last)
return {start, last}; return {start, last};
} }
static void valueFlowSubFunction(TokenList* tokenlist, SymbolDatabase* symboldatabase, ErrorLogger* errorLogger, const Settings* settings) static void valueFlowSubFunction(TokenList* tokenlist, SymbolDatabase* symboldatabase, ErrorLogger* errorLogger, const Settings& settings)
{ {
int id = 0; int id = 0;
for (const Scope* scope : MakeIteratorRange(symboldatabase->functionScopes.crbegin(), symboldatabase->functionScopes.crend())) { for (const Scope* scope : MakeIteratorRange(symboldatabase->functionScopes.crbegin(), symboldatabase->functionScopes.crend())) {
@ -7401,9 +7401,9 @@ static void valueFlowSubFunction(TokenList* tokenlist, SymbolDatabase* symboldat
const Function * const calledFunction = tok->function(); const Function * const calledFunction = tok->function();
if (!calledFunction) { if (!calledFunction) {
// library function? // library function?
const std::string& returnValue(settings->library.returnValue(tok)); const std::string& returnValue(settings.library.returnValue(tok));
if (!returnValue.empty()) if (!returnValue.empty())
valueFlowLibraryFunction(tok->next(), returnValue, settings); valueFlowLibraryFunction(tok->next(), returnValue, &settings);
continue; continue;
} }
@ -7433,7 +7433,7 @@ static void valueFlowSubFunction(TokenList* tokenlist, SymbolDatabase* symboldat
}); });
// Remove uninit values if argument is passed by value // Remove uninit values if argument is passed by value
if (argtok->variable() && !argtok->variable()->isPointer() && argvalues.size() == 1 && argvalues.front().isUninitValue()) { if (argtok->variable() && !argtok->variable()->isPointer() && argvalues.size() == 1 && argvalues.front().isUninitValue()) {
if (CheckUninitVar::isVariableUsage(tokenlist->isCPP(), argtok, settings->library, false, CheckUninitVar::Alloc::NO_ALLOC, 0)) if (CheckUninitVar::isVariableUsage(tokenlist->isCPP(), argtok, settings.library, false, CheckUninitVar::Alloc::NO_ALLOC, 0))
continue; continue;
} }
@ -7665,7 +7665,7 @@ static void valueFlowUninit(TokenList* tokenlist, SymbolDatabase* /*symbolDataba
continue; continue;
} }
MemberExpressionAnalyzer analyzer(memVar.nameToken()->str(), tok, uninitValue, tokenlist, settings); MemberExpressionAnalyzer analyzer(memVar.nameToken()->str(), tok, uninitValue, tokenlist, settings);
valueFlowGenericForward(tok->next(), tok->scope()->bodyEnd, analyzer, settings); valueFlowGenericForward(tok->next(), tok->scope()->bodyEnd, analyzer, *settings);
for (auto&& p : *analyzer.partialReads) { for (auto&& p : *analyzer.partialReads) {
Token* tok2 = p.first; Token* tok2 = p.first;
@ -8895,7 +8895,7 @@ void ValueFlow::setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase,
valueFlowSymbolic(tokenlist, symboldatabase, settings); valueFlowSymbolic(tokenlist, symboldatabase, settings);
valueFlowBitAnd(tokenlist, settings); valueFlowBitAnd(tokenlist, settings);
valueFlowSameExpressions(tokenlist, settings); valueFlowSameExpressions(tokenlist, settings);
valueFlowConditionExpressions(tokenlist, symboldatabase, errorLogger, settings); valueFlowConditionExpressions(tokenlist, symboldatabase, errorLogger, *settings);
const std::uint64_t stopTime = getValueFlowStopTime(settings); const std::uint64_t stopTime = getValueFlowStopTime(settings);
@ -8931,7 +8931,7 @@ void ValueFlow::setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase,
if (std::time(nullptr) < stopTime) if (std::time(nullptr) < stopTime)
valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings); valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings);
if (std::time(nullptr) < stopTime) if (std::time(nullptr) < stopTime)
valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, settings); valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, *settings);
if (std::time(nullptr) < stopTime) if (std::time(nullptr) < stopTime)
valueFlowFunctionReturn(tokenlist, errorLogger, settings); valueFlowFunctionReturn(tokenlist, errorLogger, settings);
if (std::time(nullptr) < stopTime) if (std::time(nullptr) < stopTime)