ExprEngine: Temporary hardcoding for calloc
This commit is contained in:
parent
7cf8327b31
commit
0011fb5a36
|
@ -191,7 +191,7 @@ namespace {
|
||||||
unsigned int size = 1;
|
unsigned int size = 1;
|
||||||
for (const auto &dim : tok->variable()->dimensions())
|
for (const auto &dim : tok->variable()->dimensions())
|
||||||
size *= dim.num;
|
size *= dim.num;
|
||||||
auto val = std::make_shared<ExprEngine::ArrayValue>(getNewSymbolName(), size);
|
auto val = std::make_shared<ExprEngine::ArrayValue>(getNewSymbolName(), size, size);
|
||||||
memory[tok->varId()] = val;
|
memory[tok->varId()] = val;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
@ -249,6 +249,13 @@ void ExprEngine::ArrayValue::assign(ExprEngine::ValuePtr index, ExprEngine::Valu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExprEngine::ArrayValue::clear()
|
||||||
|
{
|
||||||
|
auto zero = std::make_shared<ExprEngine::IntRange>("0", 0, 0);
|
||||||
|
for (int i = 0; i < data.size(); ++i)
|
||||||
|
data[i] = zero;
|
||||||
|
}
|
||||||
|
|
||||||
ExprEngine::ValuePtr ExprEngine::ArrayValue::read(ExprEngine::ValuePtr index)
|
ExprEngine::ValuePtr ExprEngine::ArrayValue::read(ExprEngine::ValuePtr index)
|
||||||
{
|
{
|
||||||
auto i1 = std::dynamic_pointer_cast<ExprEngine::IntRange>(index);
|
auto i1 = std::dynamic_pointer_cast<ExprEngine::IntRange>(index);
|
||||||
|
@ -602,8 +609,10 @@ static ExprEngine::ValuePtr executeAssign(const Token *tok, Data &data)
|
||||||
|
|
||||||
static ExprEngine::ValuePtr executeFunctionCall(const Token *tok, Data &data)
|
static ExprEngine::ValuePtr executeFunctionCall(const Token *tok, Data &data)
|
||||||
{
|
{
|
||||||
|
std::vector<ExprEngine::ValuePtr> argValues;
|
||||||
for (const Token *argtok : getArguments(tok)) {
|
for (const Token *argtok : getArguments(tok)) {
|
||||||
auto val = executeExpression(argtok, data);
|
auto val = executeExpression(argtok, data);
|
||||||
|
argValues.push_back(val);
|
||||||
if (!argtok->valueType() || (argtok->valueType()->constness & 1) == 1)
|
if (!argtok->valueType() || (argtok->valueType()->constness & 1) == 1)
|
||||||
continue;
|
continue;
|
||||||
if (auto arrayValue = std::dynamic_pointer_cast<ExprEngine::ArrayValue>(val)) {
|
if (auto arrayValue = std::dynamic_pointer_cast<ExprEngine::ArrayValue>(val)) {
|
||||||
|
@ -619,6 +628,20 @@ static ExprEngine::ValuePtr executeFunctionCall(const Token *tok, Data &data)
|
||||||
data.memory[addressOf->varId] = getValueRangeFromValueType(data.getNewSymbolName(), &vt, *data.settings);
|
data.memory[addressOf->varId] = getValueRangeFromValueType(data.getNewSymbolName(), &vt, *data.settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Fix this hardcoding..
|
||||||
|
if (Token::simpleMatch(tok->astOperand1(), "calloc (") && argValues.size() == 2 && argValues[0] && argValues[1]) {
|
||||||
|
auto bufferSize = std::make_shared<ExprEngine::BinOpResult>("*", argValues[0], argValues[1]);
|
||||||
|
ExprEngine::BinOpResult::IntOrFloatValue minValue, maxValue;
|
||||||
|
bufferSize->getRange(&minValue, &maxValue);
|
||||||
|
if (!minValue.isFloat()) {
|
||||||
|
auto buffer = std::make_shared<ExprEngine::ArrayValue>(data.getNewSymbolName(), minValue.intValue, maxValue.intValue);
|
||||||
|
buffer->clear();
|
||||||
|
call(data.callbacks, tok, buffer);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto val = getValueRangeFromValueType(data.getNewSymbolName(), tok->valueType(), *data.settings);
|
auto val = getValueRangeFromValueType(data.getNewSymbolName(), tok->valueType(), *data.settings);
|
||||||
call(data.callbacks, tok, val);
|
call(data.callbacks, tok, val);
|
||||||
return val;
|
return val;
|
||||||
|
@ -764,7 +787,7 @@ static void execute(const Token *start, const Token *end, Data &data)
|
||||||
data.trackProgramState(tok);
|
data.trackProgramState(tok);
|
||||||
if (tok->variable() && tok->variable()->nameToken() == tok) {
|
if (tok->variable() && tok->variable()->nameToken() == tok) {
|
||||||
if (tok->variable()->isArray() && tok->variable()->dimensions().size() == 1 && tok->variable()->dimensions()[0].known) {
|
if (tok->variable()->isArray() && tok->variable()->dimensions().size() == 1 && tok->variable()->dimensions()[0].known) {
|
||||||
data.memory[tok->varId()] = std::make_shared<ExprEngine::ArrayValue>(data.getNewSymbolName(), tok->variable()->dimension(0));
|
data.memory[tok->varId()] = std::make_shared<ExprEngine::ArrayValue>(data.getNewSymbolName(), tok->variable()->dimension(0), tok->variable()->dimension(0));
|
||||||
}
|
}
|
||||||
if (Token::Match(tok, "%name% ["))
|
if (Token::Match(tok, "%name% ["))
|
||||||
tok = tok->linkAt(1);
|
tok = tok->linkAt(1);
|
||||||
|
|
|
@ -158,10 +158,16 @@ namespace ExprEngine {
|
||||||
public:
|
public:
|
||||||
const int MAXSIZE = 0x100000;
|
const int MAXSIZE = 0x100000;
|
||||||
|
|
||||||
ArrayValue(const std::string &name, size_t size)
|
ArrayValue(const std::string &name, int minSize, int maxSize)
|
||||||
: Value(name) {
|
: Value(name)
|
||||||
data.resize((size < MAXSIZE) ? size : MAXSIZE,
|
, minSize(minSize)
|
||||||
std::make_shared<UninitValue>());
|
, maxSize(maxSize) {
|
||||||
|
if (minSize < 1)
|
||||||
|
minSize = 1;
|
||||||
|
// Known size..
|
||||||
|
if (minSize == maxSize)
|
||||||
|
data.resize((minSize < MAXSIZE) ? minSize : MAXSIZE,
|
||||||
|
std::make_shared<UninitValue>());
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType type() const override {
|
ValueType type() const override {
|
||||||
|
@ -170,9 +176,12 @@ namespace ExprEngine {
|
||||||
std::string getRange() const override;
|
std::string getRange() const override;
|
||||||
|
|
||||||
void assign(ValuePtr index, ValuePtr value);
|
void assign(ValuePtr index, ValuePtr value);
|
||||||
|
void clear();
|
||||||
ValuePtr read(ValuePtr index);
|
ValuePtr read(ValuePtr index);
|
||||||
|
|
||||||
std::vector<ValuePtr> data;
|
std::vector<ValuePtr> data;
|
||||||
|
int minSize;
|
||||||
|
int maxSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StringLiteralValue: public Value {
|
class StringLiteralValue: public Value {
|
||||||
|
|
|
@ -36,6 +36,8 @@ private:
|
||||||
TEST_CASE(argSmartPointer);
|
TEST_CASE(argSmartPointer);
|
||||||
TEST_CASE(argStruct);
|
TEST_CASE(argStruct);
|
||||||
|
|
||||||
|
TEST_CASE(dynamicAllocation1);
|
||||||
|
|
||||||
TEST_CASE(expr1);
|
TEST_CASE(expr1);
|
||||||
TEST_CASE(expr2);
|
TEST_CASE(expr2);
|
||||||
TEST_CASE(expr3);
|
TEST_CASE(expr3);
|
||||||
|
@ -110,6 +112,10 @@ private:
|
||||||
"void f(struct S s) { return s.a + s.b; }", "s.a+s.b"));
|
"void f(struct S s) { return s.a + s.b; }", "s.a+s.b"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dynamicAllocation1() {
|
||||||
|
ASSERT_EQUALS("[0]", getRange("char *f() { char *p = calloc(1,1); return p; }", "p"));
|
||||||
|
}
|
||||||
|
|
||||||
void expr1() {
|
void expr1() {
|
||||||
ASSERT_EQUALS("-32768:32767", getRange("void f(short x) { a = x; }", "x"));
|
ASSERT_EQUALS("-32768:32767", getRange("void f(short x) { a = x; }", "x"));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue