Dont stop analysis when an unrelated class variable is changed (#3518)
This commit is contained in:
parent
ca83222bae
commit
48fc70b810
|
@ -720,7 +720,7 @@ bool isAliased(const Variable *var)
|
||||||
return isAliased(start, var->scope()->bodyEnd, var->declarationId());
|
return isAliased(start, var->scope()->bodyEnd, var->declarationId());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool exprDependsOnThis(const Token* expr, nonneg int depth)
|
bool exprDependsOnThis(const Token* expr, bool onVar, nonneg int depth)
|
||||||
{
|
{
|
||||||
if (!expr)
|
if (!expr)
|
||||||
return false;
|
return false;
|
||||||
|
@ -743,13 +743,13 @@ bool exprDependsOnThis(const Token* expr, nonneg int depth)
|
||||||
nestedIn = nestedIn->nestedIn;
|
nestedIn = nestedIn->nestedIn;
|
||||||
}
|
}
|
||||||
return nestedIn == expr->function()->nestedIn;
|
return nestedIn == expr->function()->nestedIn;
|
||||||
} else if (Token::Match(expr, "%var%") && expr->variable()) {
|
} else if (onVar && Token::Match(expr, "%var%") && expr->variable()) {
|
||||||
const Variable* var = expr->variable();
|
const Variable* var = expr->variable();
|
||||||
return (var->isPrivate() || var->isPublic() || var->isProtected());
|
return (var->isPrivate() || var->isPublic() || var->isProtected());
|
||||||
}
|
}
|
||||||
if (Token::simpleMatch(expr, "."))
|
if (Token::simpleMatch(expr, "."))
|
||||||
return exprDependsOnThis(expr->astOperand1(), depth);
|
return exprDependsOnThis(expr->astOperand1(), onVar, depth);
|
||||||
return exprDependsOnThis(expr->astOperand1(), depth) || exprDependsOnThis(expr->astOperand2(), depth);
|
return exprDependsOnThis(expr->astOperand1(), onVar, depth) || exprDependsOnThis(expr->astOperand2(), onVar, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasUnknownVars(const Token* startTok)
|
static bool hasUnknownVars(const Token* startTok)
|
||||||
|
|
|
@ -144,7 +144,7 @@ bool extractForLoopValues(const Token *forToken,
|
||||||
|
|
||||||
bool precedes(const Token * tok1, const Token * tok2);
|
bool precedes(const Token * tok1, const Token * tok2);
|
||||||
|
|
||||||
bool exprDependsOnThis(const Token* expr, nonneg int depth = 0);
|
bool exprDependsOnThis(const Token* expr, bool onVar = true, nonneg int depth = 0);
|
||||||
|
|
||||||
struct ReferenceToken {
|
struct ReferenceToken {
|
||||||
const Token* token;
|
const Token* token;
|
||||||
|
|
|
@ -1938,6 +1938,8 @@ static bool bifurcate(const Token* tok, const std::set<nonneg int>& varids, cons
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isContainerSizeChanged(const Token* tok, const Settings* settings = nullptr, int depth = 20);
|
||||||
|
|
||||||
struct ValueFlowAnalyzer : Analyzer {
|
struct ValueFlowAnalyzer : Analyzer {
|
||||||
const TokenList* tokenlist;
|
const TokenList* tokenlist;
|
||||||
ProgramMemoryState pms;
|
ProgramMemoryState pms;
|
||||||
|
@ -1977,6 +1979,9 @@ struct ValueFlowAnalyzer : Analyzer {
|
||||||
virtual bool dependsOnThis() const {
|
virtual bool dependsOnThis() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
virtual bool isVariable() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool invalid() const {
|
virtual bool invalid() const {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2330,8 +2335,7 @@ struct ValueFlowAnalyzer : Analyzer {
|
||||||
if (a != Action::None)
|
if (a != Action::None)
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
if (dependsOnThis() && exprDependsOnThis(tok, !isVariable()))
|
||||||
if (dependsOnThis() && exprDependsOnThis(tok))
|
|
||||||
return isThisModified(tok);
|
return isThisModified(tok);
|
||||||
|
|
||||||
// bailout: global non-const variables
|
// bailout: global non-const variables
|
||||||
|
@ -2674,6 +2678,10 @@ struct ExpressionAnalyzer : SingleValueFlowAnalyzer {
|
||||||
virtual bool isGlobal() const OVERRIDE {
|
virtual bool isGlobal() const OVERRIDE {
|
||||||
return !local;
|
return !local;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool isVariable() const OVERRIDE {
|
||||||
|
return expr->varId() > 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OppositeExpressionAnalyzer : ExpressionAnalyzer {
|
struct OppositeExpressionAnalyzer : ExpressionAnalyzer {
|
||||||
|
@ -5910,7 +5918,7 @@ struct MultiValueFlowAnalyzer : ValueFlowAnalyzer {
|
||||||
// ProgramMemory pm = pms.get(endBlock->link()->next(), getProgramState());
|
// ProgramMemory pm = pms.get(endBlock->link()->next(), getProgramState());
|
||||||
for (const auto& p:pm.values) {
|
for (const auto& p:pm.values) {
|
||||||
nonneg int varid = p.first;
|
nonneg int varid = p.first;
|
||||||
if (!symboldatabase->isVarId(varid))
|
if (symboldatabase && !symboldatabase->isVarId(varid))
|
||||||
continue;
|
continue;
|
||||||
ValueFlow::Value value = p.second;
|
ValueFlow::Value value = p.second;
|
||||||
if (vars.count(varid) != 0)
|
if (vars.count(varid) != 0)
|
||||||
|
@ -6437,8 +6445,6 @@ static void valueFlowUninit(TokenList* tokenlist, SymbolDatabase* /*symbolDataba
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isContainerSizeChanged(const Token* tok, const Settings* settings = nullptr, int depth = 20);
|
|
||||||
|
|
||||||
static bool isContainerSizeChanged(nonneg int varId,
|
static bool isContainerSizeChanged(nonneg int varId,
|
||||||
const Token* start,
|
const Token* start,
|
||||||
const Token* end,
|
const Token* end,
|
||||||
|
|
|
@ -2464,6 +2464,17 @@ private:
|
||||||
ASSERT_EQUALS(false, testValueOfXKnown(code, 3U, 0));
|
ASSERT_EQUALS(false, testValueOfXKnown(code, 3U, 0));
|
||||||
ASSERT_EQUALS(false, testValueOfXImpossible(code, 3U, 0));
|
ASSERT_EQUALS(false, testValueOfXImpossible(code, 3U, 0));
|
||||||
ASSERT_EQUALS(false, testValueOfXImpossible(code, 3U, 1));
|
ASSERT_EQUALS(false, testValueOfXImpossible(code, 3U, 1));
|
||||||
|
|
||||||
|
code = "struct A {\n"
|
||||||
|
" int i, j;\n"
|
||||||
|
" int foo() {\n"
|
||||||
|
" i = 1;\n"
|
||||||
|
" j = 2;\n"
|
||||||
|
" int x = i;\n"
|
||||||
|
" return x;\n"
|
||||||
|
" }\n"
|
||||||
|
"};\n";
|
||||||
|
ASSERT_EQUALS(true, testValueOfXKnown(code, 7U, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void valueFlowAfterSwap()
|
void valueFlowAfterSwap()
|
||||||
|
|
Loading…
Reference in New Issue