Skip to content

Commit

Permalink
pass Settings by reference into ProgramMemoryState (#6977)
Browse files Browse the repository at this point in the history
  • Loading branch information
firewave authored Nov 14, 2024
1 parent 648d1c8 commit bce5666
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 26 deletions.
43 changes: 20 additions & 23 deletions lib/programmemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,10 +468,8 @@ static ProgramMemory getInitialProgramState(const Token* tok,
return pm;
}

ProgramMemoryState::ProgramMemoryState(const Settings* s) : settings(s)
{
assert(settings != nullptr);
}
ProgramMemoryState::ProgramMemoryState(const Settings& s) : settings(s)
{}

void ProgramMemoryState::replace(ProgramMemory pm, const Token* origin)
{
Expand All @@ -493,9 +491,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);
}
Expand All @@ -506,7 +504,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 (Token::Match(top->previous(), "for|while|if (") && !Token::simpleMatch(tok->astParent(), "?")) {
Expand All @@ -523,7 +521,7 @@ void ProgramMemoryState::removeModifiedVars(const Token* tok)
const ProgramMemory& pm = state;
auto eval = [&](const Token* cond) -> std::vector<MathLib::bigint> {
ProgramMemory pm2 = pm;
auto result = execute(cond, pm2, *settings);
auto result = execute(cond, pm2, settings);
if (isTrue(result))
return {1};
if (isFalse(result))
Expand All @@ -533,7 +531,7 @@ void ProgramMemoryState::removeModifiedVars(const Token* tok)
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;
}
Expand Down Expand Up @@ -1276,14 +1274,14 @@ static void pruneConditions(std::vector<const Token*>& conds,

namespace {
struct Executor {
ProgramMemory* pm = nullptr;
const Settings* settings = nullptr;
ProgramMemory* pm;
const Settings& settings;
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);
assert(pm != nullptr);
}

static ValueFlow::Value unknown() {
Expand Down Expand Up @@ -1395,7 +1393,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;
Expand Down Expand Up @@ -1580,7 +1578,7 @@ namespace {
}
if (expr->exprId() > 0 && pm->hasValue(expr->exprId())) {
ValueFlow::Value result = utils::as_const(*pm).at(expr->exprId());
if (result.isImpossible() && result.isIntValue() && result.intvalue == 0 && isUsedAsBool(expr, *settings)) {
if (result.isImpossible() && result.isIntValue() && result.intvalue == 0 && isUsedAsBool(expr, settings)) {
result.intvalue = !result.intvalue;
result.setKnown();
}
Expand All @@ -1591,7 +1589,7 @@ namespace {
const Token* ftok = expr->previous();
const Function* f = ftok->function();
ValueFlow::Value result = unknown();
if (settings && expr->str() == "(") {
if (expr->str() == "(") {
std::vector<const Token*> tokArgs = getArguments(expr);
std::vector<ValueFlow::Value> args(tokArgs.size());
std::transform(
Expand Down Expand Up @@ -1619,7 +1617,7 @@ namespace {
BuiltinLibraryFunction lf = getBuiltinLibraryFunction(ftok->str());
if (lf)
return lf(args);
const std::string& returnValue = settings->library.returnValue(ftok);
const std::string& returnValue = settings.library.returnValue(ftok);
if (!returnValue.empty()) {
std::unordered_map<nonneg int, ValueFlow::Value> arg_map;
int argn = 0;
Expand All @@ -1628,20 +1626,19 @@ namespace {
arg_map[argn] = v;
argn++;
}
return evaluateLibraryFunction(arg_map, returnValue, *settings, ftok->isCpp());
return evaluateLibraryFunction(arg_map, returnValue, settings, ftok->isCpp());
}
}
}
// Check if function modifies argument
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))
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();
}
}
Expand Down Expand Up @@ -1773,13 +1770,13 @@ namespace {

static ValueFlow::Value execute(const Token* expr, ProgramMemory& pm, const Settings& settings)
{
Executor ex{&pm, &settings};
Executor ex{&pm, settings};
return ex.execute(expr);
}

std::vector<ValueFlow::Value> execute(const Scope* scope, ProgramMemory& pm, const Settings& settings)
{
Executor ex{&pm, &settings};
Executor ex{&pm, settings};
return ex.execute(scope);
}

Expand Down
4 changes: 2 additions & 2 deletions lib/programmemory.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,9 @@ struct CPPCHECKLIB ProgramMemory {
struct ProgramMemoryState {
ProgramMemory state;
std::map<nonneg int, const Token*> origins;
const Settings* settings;
const Settings& settings;

explicit ProgramMemoryState(const Settings* s);
explicit ProgramMemoryState(const Settings& s);

void replace(ProgramMemory pm, const Token* origin = nullptr);

Expand Down
2 changes: 1 addition & 1 deletion lib/vf_analyzers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ struct ValueFlowAnalyzer : Analyzer {
const Settings& settings;
ProgramMemoryState pms;

explicit ValueFlowAnalyzer(const Settings& s) : settings(s), pms(&settings) {}
explicit ValueFlowAnalyzer(const Settings& s) : settings(s), pms(settings) {}

virtual const ValueFlow::Value* getValue(const Token* tok) const = 0;
virtual ValueFlow::Value* getValue(const Token* tok) = 0;
Expand Down

0 comments on commit bce5666

Please sign in to comment.