From 0011fb5a365f4b3b1b660f65d1ed62b18d5d1d91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 24 Sep 2019 22:22:16 +0200 Subject: [PATCH] ExprEngine: Temporary hardcoding for calloc --- lib/exprengine.cpp | 27 +++++++++++++++++++++++++-- lib/exprengine.h | 17 +++++++++++++---- test/testexprengine.cpp | 6 ++++++ 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/lib/exprengine.cpp b/lib/exprengine.cpp index 7ef2416a8..fc1dc847c 100644 --- a/lib/exprengine.cpp +++ b/lib/exprengine.cpp @@ -191,7 +191,7 @@ namespace { unsigned int size = 1; for (const auto &dim : tok->variable()->dimensions()) size *= dim.num; - auto val = std::make_shared(getNewSymbolName(), size); + auto val = std::make_shared(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("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(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 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(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("*", argValues[0], argValues[1]); + ExprEngine::BinOpResult::IntOrFloatValue minValue, maxValue; + bufferSize->getRange(&minValue, &maxValue); + if (!minValue.isFloat()) { + auto buffer = std::make_shared(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(data.getNewSymbolName(), tok->variable()->dimension(0)); + data.memory[tok->varId()] = std::make_shared(data.getNewSymbolName(), tok->variable()->dimension(0), tok->variable()->dimension(0)); } if (Token::Match(tok, "%name% [")) tok = tok->linkAt(1); diff --git a/lib/exprengine.h b/lib/exprengine.h index d4fbfb8b4..e46aedc4a 100644 --- a/lib/exprengine.h +++ b/lib/exprengine.h @@ -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()); + 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()); } 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 data; + int minSize; + int maxSize; }; class StringLiteralValue: public Value { diff --git a/test/testexprengine.cpp b/test/testexprengine.cpp index 028cfa1b4..3a948d900 100644 --- a/test/testexprengine.cpp +++ b/test/testexprengine.cpp @@ -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")); }