Skip to content

Commit d05acf3

Browse files
authored
Fix issue 10120: FP: containerOutOfBounds, regression (#3064)
1 parent 8b26ecb commit d05acf3

4 files changed

Lines changed: 30 additions & 6 deletions

File tree

lib/analyzer.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct Analyzer {
4242
Inconclusive = (1 << 3),
4343
Match = (1 << 4),
4444
Idempotent = (1 << 5),
45+
Incremental = (1 << 6),
4546
};
4647

4748
void set(unsigned int f, bool state = true) {
@@ -80,6 +81,10 @@ struct Analyzer {
8081
return get(Idempotent);
8182
}
8283

84+
bool isIncremental() const {
85+
return get(Incremental);
86+
}
87+
8388
bool matches() const {
8489
return get(Match);
8590
}

lib/forwardanalyzer.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,12 +320,14 @@ struct ForwardTraversal {
320320
Token* writeTok = findRange(endBlock->link(), endBlock, std::mem_fn(&Analyzer::Action::isModified));
321321
const Token* nextStatement = Token::findmatch(writeTok, ";|}", endBlock);
322322
if (!Token::Match(nextStatement, ";|} break ;")) {
323-
continueUpdateRangeAfterLoop(ftv, endBlock, endToken);
323+
if (!allAnalysis.isIncremental())
324+
continueUpdateRangeAfterLoop(ftv, endBlock, endToken);
324325
return Break(Terminate::Bail);
325326
}
326327
} else {
327328
if (stepTok && updateRecursive(stepTok) == Progress::Break) {
328-
continueUpdateRangeAfterLoop(ftv, endBlock, endToken);
329+
if (!allAnalysis.isIncremental())
330+
continueUpdateRangeAfterLoop(ftv, endBlock, endToken);
329331
return Break(Terminate::Bail);
330332
}
331333
}

lib/valueflow.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1893,13 +1893,14 @@ struct ValueFlowAnalyzer : Analyzer {
18931893
} else {
18941894
if (rhsValue && !value->isImpossible() && value->equalValue(*rhsValue))
18951895
a = Action::Idempotent;
1896+
a |= Action::Incremental;
18961897
}
18971898
return a;
18981899
}
18991900

19001901
// increment/decrement
19011902
if (Token::Match(tok->previous(), "++|-- %name%") || Token::Match(tok, "%name% ++|--")) {
1902-
return Action::Read | Action::Write;
1903+
return Action::Read | Action::Write | Action::Incremental;
19031904
}
19041905
return Action::None;
19051906
}
@@ -5706,17 +5707,17 @@ struct ContainerVariableAnalyzer : VariableAnalyzer {
57065707
if (tok->valueType()->container->stdStringLike && Token::simpleMatch(parent, "+=") && astIsLHS(tok) && parent->astOperand2()) {
57075708
const Token* rhs = parent->astOperand2();
57085709
if (rhs->tokType() == Token::eString)
5709-
return Action::Read | Action::Write;
5710+
return Action::Read | Action::Write | Action::Incremental;
57105711
if (rhs->valueType() && rhs->valueType()->container && rhs->valueType()->container->stdStringLike) {
57115712
if (std::any_of(rhs->values().begin(), rhs->values().end(), [&](const ValueFlow::Value &rhsval) {
57125713
return rhsval.isKnown() && rhsval.isContainerSizeValue();
57135714
}))
5714-
return Action::Read | Action::Write;
5715+
return Action::Read | Action::Write | Action::Incremental;
57155716
}
57165717
} else if (Token::Match(tok, "%name% . %name% (")) {
57175718
Library::Container::Action action = tok->valueType()->container->getAction(tok->strAt(2));
57185719
if (action == Library::Container::Action::PUSH || action == Library::Container::Action::POP)
5719-
return Action::Read | Action::Write;
5720+
return Action::Read | Action::Write | Action::Incremental;
57205721
}
57215722
return Action::None;
57225723
}

test/teststl.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,22 @@ class TestStl : public TestFixture {
380380
" return ArrS[0];\n"
381381
"}\n", true);
382382
ASSERT_EQUALS("", errout.str());
383+
384+
checkNormal("extern void Bar(const double, const double);\n"
385+
"void f(std::vector<double> &r, const double ) {\n"
386+
" std::vector<double> result;\n"
387+
" double d = 0.0;\n"
388+
" const double inc = 0.1;\n"
389+
" for(unsigned int i = 0; i < 10; ++i) {\n"
390+
" result.push_back(d);\n"
391+
" d = (i + 1) * inc;\n"
392+
" }\n"
393+
" Bar(1.0, d);\n"
394+
" Bar(10U, result.size());\n"
395+
" Bar(0.0, result[0]);\n"
396+
" Bar(0.34, result[1]);\n"
397+
"}\n");
398+
ASSERT_EQUALS("", errout.str());
383399
}
384400

385401
void outOfBoundsIndexExpression() {

0 commit comments

Comments
 (0)