Clang import; Better array handling in sizeof()
This commit is contained in:
parent
b905547c76
commit
269d21e972
|
@ -976,14 +976,19 @@ static void setValues(Tokenizer *tokenizer, SymbolDatabase *symbolDatabase)
|
||||||
|
|
||||||
for (Token *tok = const_cast<Token*>(tokenizer->tokens()); tok; tok = tok->next()) {
|
for (Token *tok = const_cast<Token*>(tokenizer->tokens()); tok; tok = tok->next()) {
|
||||||
if (Token::simpleMatch(tok, "sizeof (")) {
|
if (Token::simpleMatch(tok, "sizeof (")) {
|
||||||
int sz = 0;
|
ValueType vt = ValueType::parseDecl(tok->tokAt(2), settings);
|
||||||
for (Token *typeToken = tok->tokAt(2); typeToken->str() != ")"; typeToken = typeToken->next()) {
|
int sz = vt.typeSize(*settings);
|
||||||
if (typeToken->type())
|
|
||||||
sz = typeToken->type()->sizeOf;
|
|
||||||
}
|
|
||||||
if (sz <= 0)
|
if (sz <= 0)
|
||||||
continue;
|
continue;
|
||||||
ValueFlow::Value v(sz);
|
int mul = 1;
|
||||||
|
for (Token *arrtok = tok->linkAt(1)->previous(); arrtok; arrtok = arrtok->previous()) {
|
||||||
|
const std::string &a = arrtok->str();
|
||||||
|
if (a.size() > 2 && a[0] == '[' && a.back() == ']')
|
||||||
|
mul *= std::atoi(a.substr(1).c_str());
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ValueFlow::Value v(mul * sz);
|
||||||
v.setKnown();
|
v.setKnown();
|
||||||
tok->next()->addValue(v);
|
tok->next()->addValue(v);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6129,6 +6129,12 @@ std::string ValueType::dump() const
|
||||||
|
|
||||||
MathLib::bigint ValueType::typeSize(const cppcheck::Platform &platform) const
|
MathLib::bigint ValueType::typeSize(const cppcheck::Platform &platform) const
|
||||||
{
|
{
|
||||||
|
if (pointer)
|
||||||
|
return platform.sizeof_pointer;
|
||||||
|
|
||||||
|
if (typeScope && typeScope->definedType)
|
||||||
|
return typeScope->definedType->sizeOf;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ValueType::Type::BOOL:
|
case ValueType::Type::BOOL:
|
||||||
return platform.sizeof_bool;
|
return platform.sizeof_bool;
|
||||||
|
@ -6151,9 +6157,11 @@ MathLib::bigint ValueType::typeSize(const cppcheck::Platform &platform) const
|
||||||
case ValueType::Type::LONGDOUBLE:
|
case ValueType::Type::LONGDOUBLE:
|
||||||
return platform.sizeof_long_double;
|
return platform.sizeof_long_double;
|
||||||
default:
|
default:
|
||||||
return 0;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Unknown invalid size
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ValueType::str() const
|
std::string ValueType::str() const
|
||||||
|
|
|
@ -80,6 +80,7 @@ private:
|
||||||
TEST_CASE(symbolDatabaseNodeType1);
|
TEST_CASE(symbolDatabaseNodeType1);
|
||||||
|
|
||||||
TEST_CASE(valueFlow1);
|
TEST_CASE(valueFlow1);
|
||||||
|
TEST_CASE(valueFlow2);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string parse(const char clang[]) {
|
std::string parse(const char clang[]) {
|
||||||
|
@ -663,6 +664,22 @@ private:
|
||||||
ASSERT(tok->hasKnownIntValue());
|
ASSERT(tok->hasKnownIntValue());
|
||||||
ASSERT_EQUALS(44, tok->getKnownIntValue());
|
ASSERT_EQUALS(44, tok->getKnownIntValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void valueFlow2() {
|
||||||
|
const char clang[] = "`-VarDecl 0x4145bc0 <line:2:1, col:20> col:5 sz 'int' cinit\n"
|
||||||
|
" `-ImplicitCastExpr 0x4145c88 <col:10, col:20> 'int' <IntegralCast>\n"
|
||||||
|
" `-UnaryExprOrTypeTraitExpr 0x4145c68 <col:10, col:20> 'unsigned long' sizeof\n"
|
||||||
|
" `-ParenExpr 0x4145c48 <col:16, col:20> 'char [10]' lvalue\n"
|
||||||
|
" `-DeclRefExpr 0x4145c20 <col:17> 'char [10]' lvalue Var 0x4145b08 'buf' 'char [10]'";
|
||||||
|
|
||||||
|
GET_SYMBOL_DB(clang);
|
||||||
|
|
||||||
|
const Token *tok = Token::findsimplematch(tokenizer.tokens(), "sizeof (");
|
||||||
|
ASSERT(!!tok);
|
||||||
|
tok = tok->next();
|
||||||
|
ASSERT(tok->hasKnownIntValue());
|
||||||
|
ASSERT_EQUALS(10, tok->getKnownIntValue());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestClangImport)
|
REGISTER_TEST(TestClangImport)
|
||||||
|
|
Loading…
Reference in New Issue