FIx issue 9895: ValueFlow: Wrong known value below function call with reference parameter
This commit is contained in:
parent
e03a8e1dc1
commit
be900873cc
|
@ -5,19 +5,30 @@
|
|||
#include "symboldatabase.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
|
||||
void ProgramMemory::setValue(nonneg int varid, const ValueFlow::Value &value)
|
||||
{
|
||||
values[varid] = value;
|
||||
}
|
||||
const ValueFlow::Value* ProgramMemory::getValue(nonneg int varid) const
|
||||
{
|
||||
const ProgramMemory::Map::const_iterator it = values.find(varid);
|
||||
const bool found = it != values.end() && !it->second.isImpossible();
|
||||
if (found)
|
||||
return &it->second;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ProgramMemory::getIntValue(nonneg int varid, MathLib::bigint* result) const
|
||||
{
|
||||
const ProgramMemory::Map::const_iterator it = values.find(varid);
|
||||
const bool found = it != values.end() && it->second.isIntValue();
|
||||
if (found)
|
||||
*result = it->second.intvalue;
|
||||
return found;
|
||||
const ValueFlow::Value* value = getValue(varid);
|
||||
if (value && value->isIntValue()) {
|
||||
*result = value->intvalue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ProgramMemory::setIntValue(nonneg int varid, MathLib::bigint value)
|
||||
|
@ -27,20 +38,22 @@ void ProgramMemory::setIntValue(nonneg int varid, MathLib::bigint value)
|
|||
|
||||
bool ProgramMemory::getTokValue(nonneg int varid, const Token** result) const
|
||||
{
|
||||
const ProgramMemory::Map::const_iterator it = values.find(varid);
|
||||
const bool found = it != values.end() && it->second.isTokValue();
|
||||
if (found)
|
||||
*result = it->second.tokvalue;
|
||||
return found;
|
||||
const ValueFlow::Value* value = getValue(varid);
|
||||
if (value && value->isTokValue()) {
|
||||
*result = value->tokvalue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProgramMemory::getContainerSizeValue(nonneg int varid, MathLib::bigint* result) const
|
||||
{
|
||||
const ProgramMemory::Map::const_iterator it = values.find(varid);
|
||||
const bool found = it != values.end() && it->second.isContainerSizeValue();
|
||||
if (found)
|
||||
*result = it->second.intvalue;
|
||||
return found;
|
||||
const ValueFlow::Value* value = getValue(varid);
|
||||
if (value && value->isContainerSizeValue()) {
|
||||
*result = value->intvalue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ProgramMemory::setUnknown(nonneg int varid)
|
||||
|
|
|
@ -15,6 +15,7 @@ struct ProgramMemory {
|
|||
Map values;
|
||||
|
||||
void setValue(nonneg int varid, const ValueFlow::Value &value);
|
||||
const ValueFlow::Value* getValue(nonneg int varid) const;
|
||||
|
||||
bool getIntValue(nonneg int varid, MathLib::bigint* result) const;
|
||||
void setIntValue(nonneg int varid, MathLib::bigint value);
|
||||
|
|
|
@ -164,6 +164,24 @@ private:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool testValueOfXImpossible(const char code[], unsigned int linenr, int value) {
|
||||
// Tokenize..
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
|
||||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
|
||||
if (tok->str() == "x" && tok->linenr() == linenr) {
|
||||
for (const ValueFlow::Value& val:tok->values()) {
|
||||
if (val.isImpossible() && val.intvalue == value)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool testValueOfX(const char code[], unsigned int linenr, int value) {
|
||||
// Tokenize..
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
|
@ -2449,6 +2467,17 @@ private:
|
|||
" return x;\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 9U, 0));
|
||||
|
||||
code = "void g(long& a);\n"
|
||||
"void f(long a) {\n"
|
||||
" if (a == 0)\n"
|
||||
" return;\n"
|
||||
" if (a > 1)\n"
|
||||
" g(a);\n"
|
||||
" int x = a;\n"
|
||||
" return x;\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS(false, testValueOfXImpossible(code, 8U, 0));
|
||||
}
|
||||
|
||||
void valueFlowAfterConditionExpr() {
|
||||
|
|
Loading…
Reference in New Issue