From 269d21e972a798c04b8213fd740e6285fc74fa73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 18 Jan 2020 11:55:50 +0100 Subject: [PATCH] Clang import; Better array handling in sizeof() --- lib/clangimport.cpp | 17 +++++++++++------ lib/symboldatabase.cpp | 10 +++++++++- test/testclangimport.cpp | 17 +++++++++++++++++ 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp index de90db68b..2d4bb87aa 100644 --- a/lib/clangimport.cpp +++ b/lib/clangimport.cpp @@ -976,14 +976,19 @@ static void setValues(Tokenizer *tokenizer, SymbolDatabase *symbolDatabase) for (Token *tok = const_cast(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); } diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index c71466a03..e76d1a50c 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -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 diff --git a/test/testclangimport.cpp b/test/testclangimport.cpp index b4d5b88c1..a3e981188 100644 --- a/test/testclangimport.cpp +++ b/test/testclangimport.cpp @@ -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 col:5 sz 'int' cinit\n" + " `-ImplicitCastExpr 0x4145c88 'int' \n" + " `-UnaryExprOrTypeTraitExpr 0x4145c68 'unsigned long' sizeof\n" + " `-ParenExpr 0x4145c48 'char [10]' lvalue\n" + " `-DeclRefExpr 0x4145c20 '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)