From 62c30ad4a337e63f99f9b555ca8065e218e2e186 Mon Sep 17 00:00:00 2001 From: swasti16 Date: Fri, 3 Oct 2025 16:49:35 +0530 Subject: [PATCH] Add Valuetype type and sign for stdint macros --- addons/test/misra/misra-test.c | 2 +- lib/symboldatabase.cpp | 57 ++++++++++++++++++++++++++++++++++ test/testsymboldatabase.cpp | 10 ++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/addons/test/misra/misra-test.c b/addons/test/misra/misra-test.c index 2435dcf253a..743637117a5 100644 --- a/addons/test/misra/misra-test.c +++ b/addons/test/misra/misra-test.c @@ -725,7 +725,7 @@ static void misra_10_3(uint32_t u32a, uint32_t u32b) { res = 0.1f; // 10.3 const char c = '0'; // no-warning bool b = true; // no-warning - uint32_t u = UINT32_C(10); // 17.3 no-warning + uint32_t u = UINT32_C(10); // no-warning } static void misra_10_4(u32 x, s32 y) { diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 55145f1207c..e7ddae6659d 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -7531,6 +7531,40 @@ static const Function* getFunction(const Token* tok) { return nullptr; } +static int getIntegerConstantMacroWidth(const Token* tok) { + if (!Token::Match(tok, "%name% (") || Token::simpleMatch(tok->next()->astOperand2(), ",")) + return 0; + const std::string &name = tok->str(); + if (name.back() != 'C') + return 0; + size_t pos = (name[0] == 'U') ? 1 : 0; + if (name[pos] != 'I' || name[pos + 1] != 'N' || name[pos + 2] != 'T') + return 0; + pos += 3; + int intnum = 0; + if (name[pos] == '8') { + ++pos; + intnum = 8; + } + else if (name[pos] == '1' && name[pos + 1] == '6') { + pos += 2; + intnum = 16; + } + else if (name[pos] == '3' && name[pos + 1] == '2') { + pos += 2; + intnum = 32; + } + else if (name[pos] == '6' && name[pos + 1] == '4') { + pos += 2; + intnum = 64; + } + else + return 0; + if (pos + 2 != name.size() || name[pos] != '_') + return 0; + return intnum; +} + void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *tokens) { if (!tokens) @@ -7672,6 +7706,29 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to } } + // functions from stdint.h + else if (const int macroWidth = getIntegerConstantMacroWidth(tok->previous())) { + ValueType valuetype; + if (macroWidth == mSettings.platform.char_bit) + valuetype.type = ValueType::Type::CHAR; + else if (macroWidth == mSettings.platform.short_bit) + valuetype.type = ValueType::Type::SHORT; + else if (macroWidth == mSettings.platform.int_bit) + valuetype.type = ValueType::Type::INT; + else if (macroWidth == mSettings.platform.long_bit) + valuetype.type = ValueType::Type::LONG; + else if (macroWidth == mSettings.platform.long_long_bit) + valuetype.type = ValueType::Type::LONGLONG; + else + valuetype.type = ValueType::Type::INT; + + if (tok->strAt(-1)[0] == 'U') + valuetype.sign = ValueType::Sign::UNSIGNED; + else + valuetype.sign = ValueType::Sign::SIGNED; + setValueType(tok, valuetype); + } + // function style cast else if (tok->previous() && tok->previous()->isStandardType()) { ValueType valuetype; diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 9aaa7359abf..d49b3fb5d97 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -622,6 +622,8 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(dumpFriend); // Check if isFriend added to dump file TEST_CASE(smartPointerLookupCtor); // #13719); + + TEST_CASE(stdintFunction); } void array() { @@ -11317,6 +11319,14 @@ class TestSymbolDatabase : public TestFixture { ASSERT(db); } + + void stdintFunction() { + GET_SYMBOL_DB("a = UINT32_C(60);"); + const Token* tok = Token::findsimplematch(tokenizer.tokens(), "UINT32_C ("); + ASSERT(tok != nullptr); + ASSERT_EQUALS(tok->next()->valueType()->sign, ValueType::Sign::UNSIGNED); + ASSERT_EQUALS(tok->next()->valueType()->type, ValueType::Type::INT); + } }; REGISTER_TEST(TestSymbolDatabase)