Skip to content

Commit be90087

Browse files
committed
FIx issue 9895: ValueFlow: Wrong known value below function call with reference parameter
1 parent e03a8e1 commit be90087

3 files changed

Lines changed: 58 additions & 15 deletions

File tree

lib/programmemory.cpp

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,30 @@
55
#include "symboldatabase.h"
66
#include <algorithm>
77
#include <cassert>
8+
#include <memory>
89

910
void ProgramMemory::setValue(nonneg int varid, const ValueFlow::Value &value)
1011
{
1112
values[varid] = value;
1213
}
13-
14-
bool ProgramMemory::getIntValue(nonneg int varid, MathLib::bigint* result) const
14+
const ValueFlow::Value* ProgramMemory::getValue(nonneg int varid) const
1515
{
1616
const ProgramMemory::Map::const_iterator it = values.find(varid);
17-
const bool found = it != values.end() && it->second.isIntValue();
17+
const bool found = it != values.end() && !it->second.isImpossible();
1818
if (found)
19-
*result = it->second.intvalue;
20-
return found;
19+
return &it->second;
20+
else
21+
return nullptr;
22+
}
23+
24+
bool ProgramMemory::getIntValue(nonneg int varid, MathLib::bigint* result) const
25+
{
26+
const ValueFlow::Value* value = getValue(varid);
27+
if (value && value->isIntValue()) {
28+
*result = value->intvalue;
29+
return true;
30+
}
31+
return false;
2132
}
2233

2334
void ProgramMemory::setIntValue(nonneg int varid, MathLib::bigint value)
@@ -27,20 +38,22 @@ void ProgramMemory::setIntValue(nonneg int varid, MathLib::bigint value)
2738

2839
bool ProgramMemory::getTokValue(nonneg int varid, const Token** result) const
2940
{
30-
const ProgramMemory::Map::const_iterator it = values.find(varid);
31-
const bool found = it != values.end() && it->second.isTokValue();
32-
if (found)
33-
*result = it->second.tokvalue;
34-
return found;
41+
const ValueFlow::Value* value = getValue(varid);
42+
if (value && value->isTokValue()) {
43+
*result = value->tokvalue;
44+
return true;
45+
}
46+
return false;
3547
}
3648

3749
bool ProgramMemory::getContainerSizeValue(nonneg int varid, MathLib::bigint* result) const
3850
{
39-
const ProgramMemory::Map::const_iterator it = values.find(varid);
40-
const bool found = it != values.end() && it->second.isContainerSizeValue();
41-
if (found)
42-
*result = it->second.intvalue;
43-
return found;
51+
const ValueFlow::Value* value = getValue(varid);
52+
if (value && value->isContainerSizeValue()) {
53+
*result = value->intvalue;
54+
return true;
55+
}
56+
return false;
4457
}
4558

4659
void ProgramMemory::setUnknown(nonneg int varid)

lib/programmemory.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct ProgramMemory {
1515
Map values;
1616

1717
void setValue(nonneg int varid, const ValueFlow::Value &value);
18+
const ValueFlow::Value* getValue(nonneg int varid) const;
1819

1920
bool getIntValue(nonneg int varid, MathLib::bigint* result) const;
2021
void setIntValue(nonneg int varid, MathLib::bigint value);

test/testvalueflow.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,24 @@ class TestValueFlow : public TestFixture {
164164
return false;
165165
}
166166

167+
bool testValueOfXImpossible(const char code[], unsigned int linenr, int value) {
168+
// Tokenize..
169+
Tokenizer tokenizer(&settings, this);
170+
std::istringstream istr(code);
171+
tokenizer.tokenize(istr, "test.cpp");
172+
173+
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
174+
if (tok->str() == "x" && tok->linenr() == linenr) {
175+
for (const ValueFlow::Value& val:tok->values()) {
176+
if (val.isImpossible() && val.intvalue == value)
177+
return true;
178+
}
179+
}
180+
}
181+
182+
return false;
183+
}
184+
167185
bool testValueOfX(const char code[], unsigned int linenr, int value) {
168186
// Tokenize..
169187
Tokenizer tokenizer(&settings, this);
@@ -2449,6 +2467,17 @@ class TestValueFlow : public TestFixture {
24492467
" return x;\n"
24502468
"}\n";
24512469
ASSERT_EQUALS(true, testValueOfX(code, 9U, 0));
2470+
2471+
code = "void g(long& a);\n"
2472+
"void f(long a) {\n"
2473+
" if (a == 0)\n"
2474+
" return;\n"
2475+
" if (a > 1)\n"
2476+
" g(a);\n"
2477+
" int x = a;\n"
2478+
" return x;\n"
2479+
"}\n";
2480+
ASSERT_EQUALS(false, testValueOfXImpossible(code, 8U, 0));
24522481
}
24532482

24542483
void valueFlowAfterConditionExpr() {

0 commit comments

Comments
 (0)