parent
7d1423c5fb
commit
844ed2bf22
|
@ -6281,6 +6281,8 @@ void SymbolDatabase::setValueType(Token* tok, const Variable& var, SourceLocatio
|
|||
}
|
||||
}
|
||||
|
||||
static ValueType::Type getEnumType(const Scope* scope, const cppcheck::Platform& platform);
|
||||
|
||||
void SymbolDatabase::setValueType(Token* tok, const Enumerator& enumerator, SourceLocation loc)
|
||||
{
|
||||
ValueType valuetype;
|
||||
|
@ -6307,7 +6309,7 @@ void SymbolDatabase::setValueType(Token* tok, const Enumerator& enumerator, Sour
|
|||
setValueType(tok, valuetype);
|
||||
} else {
|
||||
valuetype.sign = ValueType::SIGNED;
|
||||
valuetype.type = ValueType::INT;
|
||||
valuetype.type = getEnumType(enumerator.scope, mSettings.platform);
|
||||
setValueType(tok, valuetype);
|
||||
}
|
||||
}
|
||||
|
@ -6796,6 +6798,32 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
|
|||
}
|
||||
}
|
||||
|
||||
static ValueType::Type getEnumType(const Scope* scope, const cppcheck::Platform& platform) // TODO: also determine sign?
|
||||
{
|
||||
ValueType::Type type = ValueType::Type::INT;
|
||||
for (const Token* tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) {
|
||||
if (!tok->isAssignmentOp())
|
||||
continue;
|
||||
const Token* vTok = tok->astOperand2();
|
||||
if (!vTok->hasKnownIntValue()) {
|
||||
if (!vTok->isLiteral())
|
||||
continue;
|
||||
if (const ValueType* vt = vTok->valueType()) {
|
||||
if ((vt->type > type && (vt->type == ValueType::Type::LONG || vt->type == ValueType::Type::LONGLONG)))
|
||||
type = vt->type;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const MathLib::bigint value = vTok->getKnownIntValue();
|
||||
if (!platform.isIntValue(value)) {
|
||||
type = ValueType::Type::LONG;
|
||||
if (!platform.isLongValue(value))
|
||||
type = ValueType::Type::LONGLONG;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
static const Token* parsedecl(const Token* type,
|
||||
ValueType* const valuetype,
|
||||
ValueType::Sign defaultSignedness,
|
||||
|
@ -6829,7 +6857,7 @@ static const Token* parsedecl(const Token* type,
|
|||
else if (enum_type->isStandardType())
|
||||
valuetype->fromLibraryType(enum_type->str(), settings);
|
||||
} else
|
||||
valuetype->type = ValueType::Type::INT;
|
||||
valuetype->type = getEnumType(valuetype->typeScope, settings.platform);
|
||||
} else
|
||||
valuetype->type = ValueType::Type::RECORD;
|
||||
bool par = false;
|
||||
|
@ -6976,8 +7004,8 @@ static const Token* parsedecl(const Token* type,
|
|||
valuetype->type = type->str() == "struct" ? ValueType::Type::RECORD : ValueType::Type::NONSTD;
|
||||
else if (!valuetype->typeScope && type->type() && type->type()->classScope) {
|
||||
if (type->type()->classScope->type == Scope::ScopeType::eEnum) {
|
||||
valuetype->type = ValueType::Type::INT;
|
||||
valuetype->sign = ValueType::Sign::SIGNED;
|
||||
valuetype->type = getEnumType(type->type()->classScope, settings.platform);
|
||||
} else {
|
||||
valuetype->type = ValueType::Type::RECORD;
|
||||
}
|
||||
|
|
|
@ -388,6 +388,7 @@ private:
|
|||
TEST_CASE(enum11);
|
||||
TEST_CASE(enum12);
|
||||
TEST_CASE(enum13);
|
||||
TEST_CASE(enum14);
|
||||
|
||||
TEST_CASE(sizeOfType);
|
||||
|
||||
|
@ -5771,6 +5772,37 @@ private:
|
|||
ASSERT(E1->scope == a->valueType()->typeScope);
|
||||
}
|
||||
|
||||
void enum14() {
|
||||
GET_SYMBOL_DB("void f() {\n" // #11421
|
||||
" enum E { A = 0, B = 0xFFFFFFFFFFFFFFFFull, C = 0x7FFFFFFFFFFFFFFF };\n"
|
||||
" E e = B;\n"
|
||||
" auto s1 = e >> 32;\n"
|
||||
" auto s2 = B >> 32;\n"
|
||||
" enum F { F0 = sizeof(int) };\n"
|
||||
" F f = F0;\n"
|
||||
"}\n");
|
||||
ASSERT(db != nullptr);
|
||||
auto it = db->scopeList.begin();
|
||||
std::advance(it, 2);
|
||||
const Enumerator* B = it->findEnumerator("B");
|
||||
ASSERT(B);
|
||||
TODO_ASSERT(B->value_known);
|
||||
const Enumerator* C = it->findEnumerator("C");
|
||||
ASSERT(C && C->value_known);
|
||||
const Token* const s1 = Token::findsimplematch(tokenizer.tokens(), "s1 =");
|
||||
ASSERT(s1 && s1->valueType());
|
||||
ASSERT_EQUALS(s1->valueType()->type, ValueType::Type::LONGLONG);
|
||||
const Token* const s2 = Token::findsimplematch(s1, "s2 =");
|
||||
ASSERT(s2 && s2->valueType());
|
||||
ASSERT_EQUALS(s2->valueType()->type, ValueType::Type::LONGLONG);
|
||||
++it;
|
||||
const Enumerator* F0 = it->findEnumerator("F0");
|
||||
ASSERT(F0 && F0->value_known);
|
||||
const Token* const f = Token::findsimplematch(s2, "f =");
|
||||
ASSERT(f && f->valueType());
|
||||
ASSERT_EQUALS(f->valueType()->type, ValueType::Type::INT);
|
||||
}
|
||||
|
||||
void sizeOfType() {
|
||||
// #7615 - crash in Symboldatabase::sizeOfType()
|
||||
GET_SYMBOL_DB("enum e;\n"
|
||||
|
|
Loading…
Reference in New Issue