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