ExprEngine: Temporary hardcoding for calloc
This commit is contained in:
parent
7cf8327b31
commit
0011fb5a36
|
@ -191,7 +191,7 @@ namespace {
|
|||
unsigned int size = 1;
|
||||
for (const auto &dim : tok->variable()->dimensions())
|
||||
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;
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
std::vector<ExprEngine::ValuePtr> argValues;
|
||||
for (const Token *argtok : getArguments(tok)) {
|
||||
auto val = executeExpression(argtok, data);
|
||||
argValues.push_back(val);
|
||||
if (!argtok->valueType() || (argtok->valueType()->constness & 1) == 1)
|
||||
continue;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
call(data.callbacks, tok, val);
|
||||
return val;
|
||||
|
@ -764,7 +787,7 @@ static void execute(const Token *start, const Token *end, Data &data)
|
|||
data.trackProgramState(tok);
|
||||
if (tok->variable() && tok->variable()->nameToken() == tok) {
|
||||
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% ["))
|
||||
tok = tok->linkAt(1);
|
||||
|
|
|
@ -158,10 +158,16 @@ namespace ExprEngine {
|
|||
public:
|
||||
const int MAXSIZE = 0x100000;
|
||||
|
||||
ArrayValue(const std::string &name, size_t size)
|
||||
: Value(name) {
|
||||
data.resize((size < MAXSIZE) ? size : MAXSIZE,
|
||||
std::make_shared<UninitValue>());
|
||||
ArrayValue(const std::string &name, int minSize, int maxSize)
|
||||
: Value(name)
|
||||
, minSize(minSize)
|
||||
, 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 {
|
||||
|
@ -170,9 +176,12 @@ namespace ExprEngine {
|
|||
std::string getRange() const override;
|
||||
|
||||
void assign(ValuePtr index, ValuePtr value);
|
||||
void clear();
|
||||
ValuePtr read(ValuePtr index);
|
||||
|
||||
std::vector<ValuePtr> data;
|
||||
int minSize;
|
||||
int maxSize;
|
||||
};
|
||||
|
||||
class StringLiteralValue: public Value {
|
||||
|
|
|
@ -36,6 +36,8 @@ private:
|
|||
TEST_CASE(argSmartPointer);
|
||||
TEST_CASE(argStruct);
|
||||
|
||||
TEST_CASE(dynamicAllocation1);
|
||||
|
||||
TEST_CASE(expr1);
|
||||
TEST_CASE(expr2);
|
||||
TEST_CASE(expr3);
|
||||
|
@ -110,6 +112,10 @@ private:
|
|||
"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() {
|
||||
ASSERT_EQUALS("-32768:32767", getRange("void f(short x) { a = x; }", "x"));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue