diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 4476814fcbb..9d592acc26d 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -3345,6 +3345,9 @@ bool CheckOtherImpl::comparisonNonZeroExpressionLessThanZero(const Token *tok, c return suppress; const ValueType* vt = nonZeroExpr->valueType(); + const ValueType* vtZero = nonZeroExpr->astSibling()->valueType(); + if (vt && vt->typeScope && vt->typeScope->type == ScopeType::eEnum && (!vtZero || vt->typeScope == vtZero->typeScope)) + return suppress; return vt && (vt->pointer || vt->sign == ValueType::UNSIGNED); } diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index c2ce2db812b..eb7b081c6a0 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -7554,8 +7554,13 @@ static const Token* parsedecl(const Token* type, valuetype->sign = ValueType::Sign::SIGNED; else if (enum_type->isUnsigned()) valuetype->sign = ValueType::Sign::UNSIGNED; - else - valuetype->sign = defaultSignedness; // TODO: this is implementation-dependent might be separate from char + else if (!enum_type->isStandardType()) { + ValueType evt; + if (parsedecl(enum_type, &evt, defaultSignedness, settings)) + *valuetype = evt; + else + valuetype->sign = defaultSignedness; // TODO: this is implementation-dependent might be separate from char + } const ValueType::Type t = ValueType::typeFromString(enum_type->str(), enum_type->isLong()); if (t != ValueType::Type::UNKNOWN_TYPE) valuetype->type = t; @@ -7728,13 +7733,15 @@ static const Token* parsedecl(const Token* type, valuetype->type = type->str() == "struct" ? ValueType::Type::RECORD : ValueType::Type::NONSTD; else if (!valuetype->typeScope && type->type() && type->type()->classScope && valuetype->type != ValueType::Type::SMART_POINTER) { if (type->type()->classScope->type == ScopeType::eEnum) { - valuetype->sign = ValueType::Sign::SIGNED; - valuetype->type = getEnumType(type->type()->classScope, settings.platform); + if (valuetype->type == ValueType::Type::UNKNOWN_TYPE) { + valuetype->sign = ValueType::Sign::SIGNED; + valuetype->type = getEnumType(type->type()->classScope, settings.platform); + } } else { valuetype->type = ValueType::Type::RECORD; } valuetype->typeScope = type->type()->classScope; - } else if (type->isName() && valuetype->sign != ValueType::Sign::UNKNOWN_SIGN && valuetype->pointer == 0U) + } else if (type->isNameOnly() && valuetype->sign != ValueType::Sign::UNKNOWN_SIGN && valuetype->pointer == 0U) return nullptr; else if (Token::Match(type->previous(), "!!:: %name% !!::")) { if (!type->isKeyword()) diff --git a/test/testcondition.cpp b/test/testcondition.cpp index b23bcc2e20b..2970f46a163 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -6658,6 +6658,14 @@ class TestCondition : public TestFixture { "}\n", settingsUnix64); ASSERT_EQUALS("[test.cpp:2:14]: (style) Comparing expression of type 'char' against value 128. Condition is always false. [compareValueOutOfTypeRangeError]\n", errout_str()); + + check("enum E : std::uint8_t { X };\n" // #11243 + "void f(E e) {\n" + " if (e == 256) {}\n" + " if (e <= X) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3:14]: (style) Comparing expression of type 'unsigned char' against value 256. Condition is always false. [compareValueOutOfTypeRangeError]\n", + errout_str()); } void knownConditionCast() { diff --git a/test/testio.cpp b/test/testio.cpp index ad95345e1fd..6e96d075320 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -3497,9 +3497,8 @@ class TestIO : public TestFixture { "void f(E e) {\n" " printf(\"%lu\", e);\n" "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:3]: (warning) %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'uint8_t'.\n", - "", - errout_str()); + ASSERT_EQUALS("[test.cpp:3]: (warning) %lu in format string (no. 1) requires 'unsigned long' but the argument type is 'unsigned char'.\n", + errout_str()); check("void f() {\n" " printf(\"%lu\", sizeof(char));\n" diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 93bc8861e3e..3508592eea9 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -9910,6 +9910,8 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS("unsigned long", typeOf("enum E : unsigned long { }; void foo() { E e[3]; bar(e[0]); }\n", "[ 0")); ASSERT_EQUALS("signed long long", typeOf("enum E : long long { }; void foo() { E e[3]; bar(e[0]); }\n", "[ 0")); ASSERT_EQUALS("unsigned long long", typeOf("enum E : unsigned long long { }; void foo() { E e[3]; bar(e[0]); }\n", "[ 0")); + ASSERT_EQUALS("unsigned char", typeOf("enum E : std::uint8_t {}; E e;\n", "e", /*cpp*/ true, &settings1)); + ASSERT_EQUALS("bool", typeOf("enum E : bool {}; E e;\n", "e")); #define CHECK_LIBRARY_FUNCTION_RETURN_TYPE(type) do { \ const char xmldata[] = "\n" \