Fixed #7513 (value flow of array dimension with enum doesn't always work)
This commit is contained in:
parent
50352c8d69
commit
66cacde3db
|
@ -1284,12 +1284,6 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
|||
}
|
||||
// check for qualified enumerator
|
||||
else if (dimension.end) {
|
||||
if (dimension.end->enumerator()) {
|
||||
if (dimension.end->enumerator()->value_known) {
|
||||
dimension.num = dimension.end->enumerator()->value;
|
||||
dimension.known = true;
|
||||
}
|
||||
} else {
|
||||
// rhs of [
|
||||
const Token *rhs = dimension.start->previous()->astOperand2();
|
||||
|
||||
|
@ -1309,7 +1303,6 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SymbolDatabase::~SymbolDatabase()
|
||||
{
|
||||
|
|
|
@ -578,9 +578,7 @@ static void valueFlowSetConstantValue(const Token *tok)
|
|||
ValueFlow::Value value(MathLib::toLongNumber(tok->str()));
|
||||
value.setKnown();
|
||||
setTokenValue(const_cast<Token *>(tok), value);
|
||||
}
|
||||
|
||||
if (tok->enumerator() && tok->enumerator()->value_known) {
|
||||
} else if (tok->enumerator() && tok->enumerator()->value_known) {
|
||||
ValueFlow::Value value(tok->enumerator()->value);
|
||||
value.setKnown();
|
||||
setTokenValue(const_cast<Token *>(tok), value);
|
||||
|
|
|
@ -246,6 +246,7 @@ private:
|
|||
TEST_CASE(enum2);
|
||||
TEST_CASE(enum3);
|
||||
TEST_CASE(enum4);
|
||||
TEST_CASE(enum5);
|
||||
|
||||
TEST_CASE(isImplicitlyVirtual);
|
||||
TEST_CASE(isPure);
|
||||
|
@ -288,15 +289,19 @@ private:
|
|||
TEST_CASE(valuetype);
|
||||
}
|
||||
|
||||
void array() const {
|
||||
std::istringstream code("int a[10+2];");
|
||||
TokenList list(nullptr);
|
||||
list.createTokens(code, "test.c");
|
||||
list.front()->tokAt(2)->link(list.front()->tokAt(6));
|
||||
Variable v(list.front()->next(), list.front(), list.back(), 0, Public, nullptr, nullptr, &settings.library);
|
||||
ASSERT(v.isArray());
|
||||
ASSERT_EQUALS(1U, v.dimensions().size());
|
||||
ASSERT_EQUALS(0U, v.dimension(0));
|
||||
void array() {
|
||||
GET_SYMBOL_DB_C("int a[10+2];");
|
||||
ASSERT(db != nullptr);
|
||||
if (!db)
|
||||
return;
|
||||
ASSERT(db->getVariableListSize() == 2); // the first one is not used
|
||||
const Variable * v = db->getVariableFromVarId(1);
|
||||
ASSERT(v != nullptr);
|
||||
if (!v)
|
||||
return;
|
||||
ASSERT(v->isArray());
|
||||
ASSERT_EQUALS(1U, v->dimensions().size());
|
||||
ASSERT_EQUALS(12U, v->dimension(0));
|
||||
}
|
||||
|
||||
void stlarray() const {
|
||||
|
@ -2322,6 +2327,67 @@ private:
|
|||
TODO_ASSERT_EQUALS(true, false, scope->enumeratorList[2].value_known);
|
||||
}
|
||||
|
||||
void enum5() {
|
||||
GET_SYMBOL_DB("enum { A = 10, B = 2 };\n"
|
||||
"int a[10 + 2];\n"
|
||||
"int b[A];\n"
|
||||
"int c[A + 2];\n"
|
||||
"int d[10 + B];\n"
|
||||
"int e[A + B];\n");
|
||||
ASSERT(db);
|
||||
if (!db)
|
||||
return;
|
||||
ASSERT_EQUALS(2U, db->scopeList.size());
|
||||
|
||||
// Assert that all enum values are known
|
||||
std::list<Scope>::const_iterator scope = db->scopeList.begin();
|
||||
|
||||
++scope;
|
||||
ASSERT_EQUALS((unsigned int)Scope::eEnum, (unsigned int)scope->type);
|
||||
ASSERT_EQUALS(2U, scope->enumeratorList.size());
|
||||
ASSERT_EQUALS(true, scope->enumeratorList[0].value_known);
|
||||
ASSERT_EQUALS(10, scope->enumeratorList[0].value);
|
||||
ASSERT_EQUALS(true, scope->enumeratorList[1].value_known);
|
||||
ASSERT_EQUALS(2, scope->enumeratorList[1].value);
|
||||
|
||||
ASSERT(db->getVariableListSize() == 6); // the first one is not used
|
||||
const Variable * v = db->getVariableFromVarId(1);
|
||||
ASSERT(v != nullptr);
|
||||
if (!v)
|
||||
return;
|
||||
ASSERT(v->isArray());
|
||||
ASSERT_EQUALS(1U, v->dimensions().size());
|
||||
ASSERT_EQUALS(12U, v->dimension(0));
|
||||
v = db->getVariableFromVarId(2);
|
||||
ASSERT(v != nullptr);
|
||||
if (!v)
|
||||
return;
|
||||
ASSERT(v->isArray());
|
||||
ASSERT_EQUALS(1U, v->dimensions().size());
|
||||
ASSERT_EQUALS(10U, v->dimension(0));
|
||||
v = db->getVariableFromVarId(3);
|
||||
ASSERT(v != nullptr);
|
||||
if (!v)
|
||||
return;
|
||||
ASSERT(v->isArray());
|
||||
ASSERT_EQUALS(1U, v->dimensions().size());
|
||||
ASSERT_EQUALS(12U, v->dimension(0));
|
||||
v = db->getVariableFromVarId(4);
|
||||
ASSERT(v != nullptr);
|
||||
if (!v)
|
||||
return;
|
||||
ASSERT(v->isArray());
|
||||
ASSERT_EQUALS(1U, v->dimensions().size());
|
||||
ASSERT_EQUALS(12U, v->dimension(0));
|
||||
v = db->getVariableFromVarId(5);
|
||||
ASSERT(v != nullptr);
|
||||
if (!v)
|
||||
return;
|
||||
ASSERT(v->isArray());
|
||||
ASSERT_EQUALS(1U, v->dimensions().size());
|
||||
ASSERT_EQUALS(12U, v->dimension(0));
|
||||
}
|
||||
|
||||
void isImplicitlyVirtual() {
|
||||
{
|
||||
GET_SYMBOL_DB("class Base {\n"
|
||||
|
|
Loading…
Reference in New Issue