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()); const Memory::iterator it = memory.find(tok->varId());
if (it != memory.end()) if (it != memory.end())
return std::dynamic_pointer_cast<ExprEngine::ArrayValue>(it->second); 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) { 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(); 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 std::string ExprEngine::BinOpResult::getRange() const
{ {
int128_t minValue, maxValue; int128_t minValue, maxValue;
getRange(&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 void ExprEngine::BinOpResult::getRange(int128_t *minValue, int128_t *maxValue) const

View File

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

View File

@ -64,8 +64,11 @@ private:
tokenizer.tokenize(istr, "test.cpp"); tokenizer.tokenize(istr, "test.cpp");
std::string ret; std::string ret;
std::function<void(const Token *, const ExprEngine::Value &)> f = [&](const Token *tok, const ExprEngine::Value &value) { 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(); ret += value.getRange();
}
}; };
std::vector<ExprEngine::Callback> callbacks; std::vector<ExprEngine::Callback> callbacks;
callbacks.push_back(f); callbacks.push_back(f);
@ -78,7 +81,7 @@ private:
} }
void argStruct() { void argStruct() {
ASSERT_EQUALS("[0:510]", ASSERT_EQUALS("0:510",
getRange("struct S {\n" getRange("struct S {\n"
" unsigned char a;\n" " unsigned char a;\n"
" unsigned char b;\n" " unsigned char b;\n"
@ -87,59 +90,59 @@ private:
} }
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"));
} }
void expr2() { 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() { 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() { 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() { 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() { 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() { 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() { 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() { 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() { 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() { 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() { 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() { 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() { 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() { void localArrayUninit() {
@ -147,11 +150,11 @@ private:
} }
void pointerAlias1() { 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() { 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"));
} }
}; };