diff --git a/lib/exprengine.cpp b/lib/exprengine.cpp index 74bd70609..d8766deb9 100644 --- a/lib/exprengine.cpp +++ b/lib/exprengine.cpp @@ -185,7 +185,14 @@ namespace { const Memory::iterator it = memory.find(tok->varId()); if (it != memory.end()) return std::dynamic_pointer_cast(it->second); - return std::shared_ptr(); + if (tok->varId() == 0) + return std::shared_ptr(); + unsigned int size = 1; + for (const auto &dim : tok->variable()->dimensions()) + size *= dim.num; + auto val = std::make_shared(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 diff --git a/lib/exprengine.h b/lib/exprengine.h index 359177b5a..32cd0d17d 100644 --- a/lib/exprengine.h +++ b/lib/exprengine.h @@ -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); diff --git a/test/testexprengine.cpp b/test/testexprengine.cpp index 8f6191fd8..5c1827f43 100644 --- a/test/testexprengine.cpp +++ b/test/testexprengine.cpp @@ -64,8 +64,11 @@ private: tokenizer.tokenize(istr, "test.cpp"); std::string ret; std::function 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 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 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")); } };