ExprEngine: Fix output for arrays

This commit is contained in:
Daniel Marjamäki 2019-09-21 14:17:16 +02:00
parent 860339d8b4
commit b2cab003ff
3 changed files with 47 additions and 24 deletions

View File

@ -185,7 +185,14 @@ namespace {
const Memory::iterator it = memory.find(tok->varId());
if (it != memory.end())
return std::dynamic_pointer_cast<ExprEngine::ArrayValue>(it->second);
return std::shared_ptr<ExprEngine::ArrayValue>();
if (tok->varId() == 0)
return std::shared_ptr<ExprEngine::ArrayValue>();
unsigned int size = 1;
for (const auto &dim : tok->variable()->dimensions())
size *= dim.num;
auto val = std::make_shared<ExprEngine::ArrayValue>(getNewSymbolName(), size);
memory[tok->varId()] = val;
return val;
}
ExprEngine::ValuePtr getValue(unsigned int varId, const ValueType *valueType, const Token *tok) {
@ -251,11 +258,24 @@ ExprEngine::ValuePtr ExprEngine::ArrayValue::read(ExprEngine::ValuePtr index)
return ExprEngine::ValuePtr();
}
std::string ExprEngine::ArrayValue::getRange() const
{
std::ostringstream r;
r << "[";
for (size_t i = 0; i < data.size(); ++i) {
r << (i==0?"":",") << data[i]->getRange();
}
r << "]";
return r.str();
}
std::string ExprEngine::BinOpResult::getRange() const
{
int128_t minValue, maxValue;
getRange(&minValue, &maxValue);
return "[" + str(minValue) + ":" + str(maxValue) + "]";
if (minValue == maxValue)
return str(minValue);
return str(minValue) + ":" + str(maxValue);
}
void ExprEngine::BinOpResult::getRange(int128_t *minValue, int128_t *maxValue) const

View File

@ -94,7 +94,9 @@ namespace ExprEngine {
return ValueType::IntRange;
}
std::string getRange() const override {
return "[" + str(minValue) + ":" + str(maxValue) + "]";
if (minValue == maxValue)
return str(minValue);
return str(minValue) + ":" + str(maxValue);
}
bool isIntValueInRange(int value) const override {
return value >= minValue && value <= maxValue;
@ -129,9 +131,7 @@ namespace ExprEngine {
ValueType type() const override {
return ValueType::ArrayValue;
}
std::string getRange() const override {
return "[" + std::to_string(data.size()) + "]";
}
std::string getRange() const override;
void assign(ValuePtr index, ValuePtr value);
ValuePtr read(ValuePtr index);

View File

@ -64,8 +64,11 @@ private:
tokenizer.tokenize(istr, "test.cpp");
std::string ret;
std::function<void(const Token *, const ExprEngine::Value &)> f = [&](const Token *tok, const ExprEngine::Value &value) {
if (tok->expressionString() == str)
if (tok->expressionString() == str) {
if (!ret.empty())
ret += ",";
ret += value.getRange();
}
};
std::vector<ExprEngine::Callback> callbacks;
callbacks.push_back(f);
@ -78,7 +81,7 @@ private:
}
void argStruct() {
ASSERT_EQUALS("[0:510]",
ASSERT_EQUALS("0:510",
getRange("struct S {\n"
" unsigned char a;\n"
" unsigned char b;\n"
@ -87,59 +90,59 @@ private:
}
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"));
}
void expr2() {
ASSERT_EQUALS("[-65536:65534]", getRange("void f(short x) { a = x + x; }", "x+x"));
ASSERT_EQUALS("-65536:65534", getRange("void f(short x) { a = x + x; }", "x+x"));
}
void expr3() {
ASSERT_EQUALS("[-65536:65534]", getRange("int f(short x) { int a = x + x; return a; }", "return a"));
ASSERT_EQUALS("-65536:65534", getRange("int f(short x) { int a = x + x; return a; }", "return a"));
}
void expr4() {
ASSERT_EQUALS("[0:0]", getRange("int f(short x) { int a = x - x; return a; }", "return a"));
ASSERT_EQUALS("0", getRange("int f(short x) { int a = x - x; return a; }", "return a"));
}
void expr5() {
ASSERT_EQUALS("[-65536:65534]", getRange("void f(short a, short b, short c, short d) { if (a+b<c+d) {} }", "a+b"));
ASSERT_EQUALS("-65536:65534", getRange("void f(short a, short b, short c, short d) { if (a+b<c+d) {} }", "a+b"));
}
void functionCall1() {
ASSERT_EQUALS("[-2147483648:2147483647]", getRange("int atoi(const char *p); void f() { int x = atoi(a); x = x; }", "x=x"));
ASSERT_EQUALS("-2147483648:2147483647", getRange("int atoi(const char *p); void f() { int x = atoi(a); x = x; }", "x=x"));
}
void if1() {
ASSERT_EQUALS("[7:32768]", getRange("inf f(short x) { if (x > 5) a = x + 1; }", "x+1"));
ASSERT_EQUALS("7:32768", getRange("inf f(short x) { if (x > 5) a = x + 1; }", "x+1"));
}
void if2() {
ASSERT_EQUALS("[7:32768][-32767:6]", getRange("inf f(short x) { if (x > 5) {} a = x + 1; }", "x+1"));
ASSERT_EQUALS("7:32768,-32767:6", getRange("inf f(short x) { if (x > 5) {} a = x + 1; }", "x+1"));
}
void if3() {
ASSERT_EQUALS("[1:1][-2147483648:2147483647][-2147483648:2147483647]", getRange("void f() { int x; if (a) { if (b) x=1; } a=x; }", "a=x"));
ASSERT_EQUALS("1,-2147483648:2147483647,-2147483648:2147483647", getRange("void f() { int x; if (a) { if (b) x=1; } a=x; }", "a=x"));
}
void if4() {
ASSERT_EQUALS("[1:2147483647][-2147483648:-1]", getRange("int x; void f() { if (x) { a=x; }}", "a=x"));
ASSERT_EQUALS("1:2147483647,-2147483648:-1", getRange("int x; void f() { if (x) { a=x; }}", "a=x"));
}
void if5() {
ASSERT_EQUALS("[0:0]", getRange("int x; void f() { if (x) {} else { a=x; }}", "a=x"));
ASSERT_EQUALS("0", getRange("int x; void f() { if (x) {} else { a=x; }}", "a=x"));
}
void ifelse1() {
ASSERT_EQUALS("[-32767:6]", getRange("inf f(short x) { if (x > 5) ; else a = x + 1; }", "x+1"));
ASSERT_EQUALS("-32767:6", getRange("inf f(short x) { if (x > 5) ; else a = x + 1; }", "x+1"));
}
void localArray1() {
ASSERT_EQUALS("[5:5]", getRange("inf f() { int arr[10]; arr[4] = 5; return arr[4]; }", "arr[4]"));
ASSERT_EQUALS("5", getRange("inf f() { int arr[10]; arr[4] = 5; return arr[4]; }", "arr[4]"));
}
void localArray2() {
ASSERT_EQUALS("[0:0]", getRange("inf f() { char arr[10] = \"\"; return arr[4]; }", "arr[4]"));
ASSERT_EQUALS("0", getRange("inf f() { char arr[10] = \"\"; return arr[4]; }", "arr[4]"));
}
void localArrayUninit() {
@ -147,11 +150,11 @@ private:
}
void pointerAlias1() {
ASSERT_EQUALS("[3:3]", getRange("inf f() { int x; int *p = &x; x = 3; return *p; }", "return*p"));
ASSERT_EQUALS("3", getRange("inf f() { int x; int *p = &x; x = 3; return *p; }", "return*p"));
}
void pointerAlias2() {
ASSERT_EQUALS("[1:1]", getRange("inf f() { int x; int *p = &x; *p = 1; return *p; }", "return*p"));
ASSERT_EQUALS("1", getRange("inf f() { int x; int *p = &x; *p = 1; return *p; }", "return*p"));
}
};