diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 1c77a365a1b..4b3a67861e0 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -6852,7 +6852,7 @@ void SymbolDatabase::setValueType(Token* tok, const Enumerator& enumerator, cons if (valuetype.type == ValueType::Type::UNKNOWN_TYPE) valuetype.fromLibraryType(type->expressionString(), mSettings); - if (valuetype.isIntegral()) { + if (valuetype.sign == ValueType::UNKNOWN_SIGN && valuetype.isIntegral()) { if (type->isSigned()) valuetype.sign = ValueType::Sign::SIGNED; else if (type->isUnsigned()) diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 7fccbb89f1d..1138b410ddd 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1585,6 +1585,13 @@ static Token * createAstAtToken(Token *tok) if (Token::Match(tok2, "%var% [;,)]")) return tok2; } + if (Token::Match(tok, "enum class| %name%| :")) { + if (Token::simpleMatch(tok->next(), "class")) + tok = tok->next(); + if (Token::Match(tok->next(), "%name%")) + tok = tok->next(); + return tok->next(); + } if (Token *const endTok = skipMethodDeclEnding(tok)) { Token *tok2 = tok; do { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index b33dcdbc30a..cc7464c70fc 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -464,6 +464,7 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(enum17); TEST_CASE(enum18); TEST_CASE(enum19); + TEST_CASE(enum20); // #14419 TEST_CASE(struct1); @@ -6860,6 +6861,23 @@ class TestSymbolDatabase : public TestFixture { } } + void enum20() { // #14419 + { + GET_SYMBOL_DB("enum class myclass : uint8_t { A = 0U };\n"); + const Token *A = Token::findsimplematch(tokenizer.tokens(), "A"); + ASSERT(A && A->valueType() && A->valueType()->isEnum()); + ASSERT_EQUALS_ENUM(ValueType::CHAR, A->valueType()->type); + ASSERT_EQUALS_ENUM(ValueType::UNSIGNED, A->valueType()->sign); + } + { + GET_SYMBOL_DB("enum myclass : uint8_t { A = 0U };\n"); + const Token *A = Token::findsimplematch(tokenizer.tokens(), "A"); + ASSERT(A && A->valueType() && A->valueType()->isEnum()); + ASSERT_EQUALS_ENUM(ValueType::CHAR, A->valueType()->type); + ASSERT_EQUALS_ENUM(ValueType::UNSIGNED, A->valueType()->sign); + } + } + void struct1() { GET_SYMBOL_DB_C("struct deer {\n" " uint16_t a;\n" diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index b9978261914..38611c803e0 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -423,6 +423,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(astdesignatedinit); TEST_CASE(astrvaluedecl); TEST_CASE(astorkeyword); + TEST_CASE(astenumdecl); TEST_CASE(startOfExecutableScope); @@ -7389,6 +7390,11 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS("ifsp.\"\"==sp.0==||(", testAst("void f() { if (s.p == \"\" or s.p == 0) {} }")); } + void astenumdecl() { + ASSERT_EQUALS("A0U=", testAst("enum class myclass : unsigned char { A = 0U, };")); + ASSERT_EQUALS("A0U=", testAst("enum myclass : unsigned char { A = 0U, };")); + } + #define isStartOfExecutableScope(offset, code) isStartOfExecutableScope_(offset, code, __FILE__, __LINE__) template bool isStartOfExecutableScope_(int offset, const char (&code)[size], const char* file, int line) {