ExprEngine: Fix output for arrays
This commit is contained in:
parent
860339d8b4
commit
b2cab003ff
|
@ -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);
|
||||||
|
if (tok->varId() == 0)
|
||||||
return std::shared_ptr<ExprEngine::ArrayValue>();
|
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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue