Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion addons/test/misra/misra-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
57 changes: 57 additions & 0 deletions lib/symboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
10 changes: 10 additions & 0 deletions test/testsymboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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)