Skip to content

Commit 0561877

Browse files
pfultz2danmar
authored andcommitted
Fix false positive with negative array index in issue 8536 (danmar#1202)
* Fix FP with negative array index in valueflow * Remove values when valueflow fails * Add valueflow test
1 parent 5d417bb commit 0561877

3 files changed

Lines changed: 33 additions & 4 deletions

File tree

lib/valueflow.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1722,7 +1722,7 @@ static bool valueFlowForward(Token * const startToken,
17221722
// '{'
17231723
Token * const startToken1 = tok2->linkAt(1)->next();
17241724

1725-
valueFlowForward(startToken1->next(),
1725+
bool vfresult = valueFlowForward(startToken1->next(),
17261726
startToken1->link(),
17271727
var,
17281728
varid,
@@ -1741,7 +1741,7 @@ static bool valueFlowForward(Token * const startToken,
17411741
// goto '}'
17421742
tok2 = startToken1->link();
17431743

1744-
if (isReturnScope(tok2)) {
1744+
if (isReturnScope(tok2) || !vfresult) {
17451745
if (condAlwaysTrue)
17461746
return false;
17471747
removeValues(values, truevalues);
@@ -1750,7 +1750,7 @@ static bool valueFlowForward(Token * const startToken,
17501750
if (Token::simpleMatch(tok2, "} else {")) {
17511751
Token * const startTokenElse = tok2->tokAt(2);
17521752

1753-
valueFlowForward(startTokenElse->next(),
1753+
vfresult = valueFlowForward(startTokenElse->next(),
17541754
startTokenElse->link(),
17551755
var,
17561756
varid,
@@ -1769,7 +1769,7 @@ static bool valueFlowForward(Token * const startToken,
17691769
// goto '}'
17701770
tok2 = startTokenElse->link();
17711771

1772-
if (isReturnScope(tok2)) {
1772+
if (isReturnScope(tok2) || !vfresult) {
17731773
if (condAlwaysFalse)
17741774
return false;
17751775
removeValues(values, falsevalues);

test/testbufferoverrun.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ class TestBufferOverrun : public TestFixture {
134134
TEST_CASE(array_index_calculation);
135135
TEST_CASE(array_index_negative1);
136136
TEST_CASE(array_index_negative2); // ticket #3063
137+
TEST_CASE(array_index_negative3);
137138
TEST_CASE(array_index_for_decr);
138139
TEST_CASE(array_index_varnames); // FP: struct member. #1576
139140
TEST_CASE(array_index_for_continue); // for,continue
@@ -1778,6 +1779,22 @@ class TestBufferOverrun : public TestFixture {
17781779
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'test.a[10]' accessed at index -1, which is out of bounds.\n", errout.str());
17791780
}
17801781

1782+
void array_index_negative3() {
1783+
check("int f(int i) {\n"
1784+
" int p[2] = {0, 0};\n"
1785+
" if(i >= 2)\n"
1786+
" return 0;\n"
1787+
" else if(i == 0)\n"
1788+
" return 0;\n"
1789+
" return p[i - 1];\n"
1790+
"}\n"
1791+
"void g(int i) {\n"
1792+
" if( i == 0 )\n"
1793+
" return f(i);\n"
1794+
"}");
1795+
ASSERT_EQUALS("", errout.str());
1796+
}
1797+
17811798
void array_index_for_decr() {
17821799
check("void f()\n"
17831800
"{\n"

test/testvalueflow.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2455,6 +2455,18 @@ class TestValueFlow : public TestFixture {
24552455
ASSERT_EQUALS(false, testValueOfX(code, 3U, 0));
24562456
ASSERT_EQUALS(true, testValueOfX(code, 3U, 4));
24572457

2458+
code = "int f(int i) {\n"
2459+
" if(i >= 2)\n"
2460+
" return 0;\n"
2461+
" else if(i == 0)\n"
2462+
" return 0;\n"
2463+
" int a = i;\n"
2464+
"}\n"
2465+
"void g(int i) {\n"
2466+
" return f(0);\n"
2467+
"}";
2468+
ASSERT_EQUALS(false, testValueOfX(code, 6U, 0));
2469+
24582470
code = "void f1(int x) { a=x; }\n"
24592471
"void f2(int y) { f1(y<123); }\n";
24602472
ASSERT_EQUALS(true, testValueOfX(code, 1U, 0));

0 commit comments

Comments
 (0)