Fix FPs
This commit is contained in:
parent
bb9dbaa8f5
commit
4d1b3e06c7
|
@ -10,9 +10,19 @@
|
||||||
|
|
||||||
struct ForwardTraversal {
|
struct ForwardTraversal {
|
||||||
enum class Progress { Continue, Break, Skip };
|
enum class Progress { Continue, Break, Skip };
|
||||||
|
ForwardTraversal(const ValuePtr<ForwardAnalyzer>& analyzer, const Settings* settings)
|
||||||
|
: analyzer(analyzer), settings(settings), actions(ForwardAnalyzer::Action::None), analyzeOnly(false)
|
||||||
|
{}
|
||||||
ValuePtr<ForwardAnalyzer> analyzer;
|
ValuePtr<ForwardAnalyzer> analyzer;
|
||||||
const Settings* settings;
|
const Settings* settings;
|
||||||
ForwardAnalyzer::Action actions;
|
ForwardAnalyzer::Action actions;
|
||||||
|
bool analyzeOnly;
|
||||||
|
|
||||||
|
bool stopUpdates()
|
||||||
|
{
|
||||||
|
analyzeOnly = true;
|
||||||
|
return actions.isModified();
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<bool, bool> evalCond(const Token* tok) {
|
std::pair<bool, bool> evalCond(const Token* tok) {
|
||||||
std::vector<int> result = analyzer->evaluate(tok);
|
std::vector<int> result = analyzer->evaluate(tok);
|
||||||
|
@ -92,7 +102,7 @@ struct ForwardTraversal {
|
||||||
std::tie(checkThen, checkElse) = evalCond(condTok);
|
std::tie(checkThen, checkElse) = evalCond(condTok);
|
||||||
if (!checkThen && !checkElse) {
|
if (!checkThen && !checkElse) {
|
||||||
// Stop if the value is conditional
|
// Stop if the value is conditional
|
||||||
if (!traverseUnknown && analyzer->isConditional())
|
if (!traverseUnknown && analyzer->isConditional() && stopUpdates())
|
||||||
return Progress::Break;
|
return Progress::Break;
|
||||||
checkThen = true;
|
checkThen = true;
|
||||||
checkElse = true;
|
checkElse = true;
|
||||||
|
@ -117,7 +127,7 @@ struct ForwardTraversal {
|
||||||
Progress update(Token* tok) {
|
Progress update(Token* tok) {
|
||||||
ForwardAnalyzer::Action action = analyzer->analyze(tok);
|
ForwardAnalyzer::Action action = analyzer->analyze(tok);
|
||||||
actions |= action;
|
actions |= action;
|
||||||
if (!action.isNone())
|
if (!action.isNone() && !analyzeOnly)
|
||||||
analyzer->update(tok, action);
|
analyzer->update(tok, action);
|
||||||
if (action.isInconclusive() && !analyzer->lowerToInconclusive())
|
if (action.isInconclusive() && !analyzer->lowerToInconclusive())
|
||||||
return Progress::Break;
|
return Progress::Break;
|
||||||
|
@ -402,6 +412,7 @@ struct ForwardTraversal {
|
||||||
} else {
|
} else {
|
||||||
tok = endBlock;
|
tok = endBlock;
|
||||||
}
|
}
|
||||||
|
actions |= (thenAction | elseAction);
|
||||||
if (bail)
|
if (bail)
|
||||||
return Progress::Break;
|
return Progress::Break;
|
||||||
if (returnThen && returnElse)
|
if (returnThen && returnElse)
|
||||||
|
@ -415,7 +426,7 @@ struct ForwardTraversal {
|
||||||
if (checkThen) {
|
if (checkThen) {
|
||||||
return Progress::Break;
|
return Progress::Break;
|
||||||
} else {
|
} else {
|
||||||
if (analyzer->isConditional())
|
if (analyzer->isConditional() && stopUpdates())
|
||||||
return Progress::Break;
|
return Progress::Break;
|
||||||
analyzer->assume(condTok, false);
|
analyzer->assume(condTok, false);
|
||||||
}
|
}
|
||||||
|
@ -424,8 +435,8 @@ struct ForwardTraversal {
|
||||||
if (!analyzer->lowerToInconclusive())
|
if (!analyzer->lowerToInconclusive())
|
||||||
return Progress::Break;
|
return Progress::Break;
|
||||||
} else if (thenAction.isModified() || elseAction.isModified()) {
|
} else if (thenAction.isModified() || elseAction.isModified()) {
|
||||||
if (!hasElse && analyzer->isConditional())
|
if (!hasElse && analyzer->isConditional() && stopUpdates())
|
||||||
return Progress::Break;
|
return Progress::Break;
|
||||||
if (!analyzer->lowerToPossible())
|
if (!analyzer->lowerToPossible())
|
||||||
return Progress::Break;
|
return Progress::Break;
|
||||||
analyzer->assume(condTok, elseAction.isModified());
|
analyzer->assume(condTok, elseAction.isModified());
|
||||||
|
|
|
@ -2424,6 +2424,29 @@ private:
|
||||||
" }"
|
" }"
|
||||||
"}";
|
"}";
|
||||||
ASSERT_EQUALS(false, testValueOfXKnown(code, 3U, 2));
|
ASSERT_EQUALS(false, testValueOfXKnown(code, 3U, 2));
|
||||||
|
|
||||||
|
code = "int f(int i, int j) {\n"
|
||||||
|
" if (i == 0) {\n"
|
||||||
|
" if (j < 0)\n"
|
||||||
|
" return 0;\n"
|
||||||
|
" i = j+1;\n"
|
||||||
|
" }\n"
|
||||||
|
" int x = i;\n"
|
||||||
|
" return x;\n"
|
||||||
|
"}\n";
|
||||||
|
ASSERT_EQUALS(false, testValueOfX(code, 8U, 0));
|
||||||
|
|
||||||
|
code = "int f(int i, int j) {\n"
|
||||||
|
" if (i == 0) {\n"
|
||||||
|
" if (j < 0)\n"
|
||||||
|
" return 0;\n"
|
||||||
|
" if (j < 0)\n"
|
||||||
|
" i = j+1;\n"
|
||||||
|
" }\n"
|
||||||
|
" int x = i;\n"
|
||||||
|
" return x;\n"
|
||||||
|
"}\n";
|
||||||
|
ASSERT_EQUALS(true, testValueOfX(code, 9U, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void valueFlowAfterConditionExpr() {
|
void valueFlowAfterConditionExpr() {
|
||||||
|
|
Loading…
Reference in New Issue