Clang import; Better array handling in sizeof()

This commit is contained in:
Daniel Marjamäki 2020-01-18 11:55:50 +01:00
parent b905547c76
commit 269d21e972
3 changed files with 37 additions and 7 deletions

View File

@ -976,14 +976,19 @@ static void setValues(Tokenizer *tokenizer, SymbolDatabase *symbolDatabase)
for (Token *tok = const_cast<Token*>(tokenizer->tokens()); tok; tok = tok->next()) {
if (Token::simpleMatch(tok, "sizeof (")) {
int sz = 0;
for (Token *typeToken = tok->tokAt(2); typeToken->str() != ")"; typeToken = typeToken->next()) {
if (typeToken->type())
sz = typeToken->type()->sizeOf;
}
ValueType vt = ValueType::parseDecl(tok->tokAt(2), settings);
int sz = vt.typeSize(*settings);
if (sz <= 0)
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();
tok->next()->addValue(v);
}

View File

@ -6129,6 +6129,12 @@ std::string ValueType::dump() 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) {
case ValueType::Type::BOOL:
return platform.sizeof_bool;
@ -6151,9 +6157,11 @@ MathLib::bigint ValueType::typeSize(const cppcheck::Platform &platform) const
case ValueType::Type::LONGDOUBLE:
return platform.sizeof_long_double;
default:
return 0;
break;
};
// Unknown invalid size
return 0;
}
std::string ValueType::str() const

View File

@ -80,6 +80,7 @@ private:
TEST_CASE(symbolDatabaseNodeType1);
TEST_CASE(valueFlow1);
TEST_CASE(valueFlow2);
}
std::string parse(const char clang[]) {
@ -663,6 +664,22 @@ private:
ASSERT(tok->hasKnownIntValue());
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)