Removed enum mismatch checker. Ticket #6960.
This commit is contained in:
parent
f4dd43a71a
commit
c24a4b9189
|
@ -300,75 +300,3 @@ void CheckType::longCastReturnError(const Token *tok)
|
|||
"int result is returned as long value. If the return value is long to avoid loss of information, then you have loss of information.\n"
|
||||
"int result is returned as long value. If the return value is long to avoid loss of information, then there is loss of information. To avoid loss of information you must cast a calculation operand to long, for example 'return a*b;' => 'return (long)a*b'.");
|
||||
}
|
||||
|
||||
static const ValueFlow::Value *mismatchingValue(const ValueType *enumType, const std::list<ValueFlow::Value> &values)
|
||||
{
|
||||
if (!enumType || !enumType->typeScope || enumType->typeScope->type != Scope::eEnum)
|
||||
return nullptr;
|
||||
const Scope * const enumScope = enumType->typeScope;
|
||||
for (unsigned int i = 0; i < enumScope->enumeratorList.size(); ++i) {
|
||||
if (!enumScope->enumeratorList[i].value_known)
|
||||
return nullptr;
|
||||
}
|
||||
for (std::list<ValueFlow::Value>::const_iterator it = values.begin(); it != values.end(); ++it) {
|
||||
if (it->tokvalue)
|
||||
continue;
|
||||
bool found = false;
|
||||
for (unsigned int i = 0; i < enumScope->enumeratorList.size(); ++i) {
|
||||
if (enumScope->enumeratorList[i].value == it->intvalue) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
return &(*it);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CheckType::checkEnumMismatch()
|
||||
{
|
||||
if (!_settings->isEnabled("style"))
|
||||
return;
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||
// Assigning mismatching value to enum variable
|
||||
if (tok->str() == "=") {
|
||||
if (!tok->astOperand1() || !tok->astOperand2())
|
||||
continue;
|
||||
|
||||
const ValueFlow::Value *v = mismatchingValue(tok->astOperand1()->valueType(), tok->astOperand2()->values);
|
||||
if (v)
|
||||
enumMismatchAssignError(tok, *v);
|
||||
}
|
||||
|
||||
// Comparing enum variable against mismatching value
|
||||
else if (Token::Match(tok, "==|!=")) {
|
||||
if (!tok->astOperand1() || !tok->astOperand2())
|
||||
continue;
|
||||
|
||||
const ValueFlow::Value * const v1 = mismatchingValue(tok->astOperand1()->valueType(), tok->astOperand2()->values);
|
||||
if (v1 && v1->isKnown())
|
||||
enumMismatchCompareError(tok, *v1);
|
||||
|
||||
const ValueFlow::Value * const v2 = mismatchingValue(tok->astOperand2()->valueType(), tok->astOperand1()->values);
|
||||
if (v2 && v2->isKnown())
|
||||
enumMismatchCompareError(tok, *v2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckType::enumMismatchAssignError(const Token *tok, const ValueFlow::Value &value)
|
||||
{
|
||||
reportError(tok,
|
||||
Severity::style,
|
||||
"enumMismatch",
|
||||
"Assigning mismatching value " + MathLib::toString(value.intvalue) + " to enum variable.");
|
||||
}
|
||||
|
||||
void CheckType::enumMismatchCompareError(const Token *tok, const ValueFlow::Value &value)
|
||||
{
|
||||
reportError(tok,
|
||||
Severity::style,
|
||||
"enumMismatch",
|
||||
"Comparing mismatching value " + MathLib::toString(value.intvalue) + " with enum variable.");
|
||||
}
|
||||
|
|
|
@ -50,7 +50,6 @@ public:
|
|||
checkType.checkIntegerOverflow();
|
||||
checkType.checkSignConversion();
|
||||
checkType.checkLongCast();
|
||||
checkType.checkEnumMismatch();
|
||||
}
|
||||
|
||||
/** @brief Run checks against the simplified token list */
|
||||
|
@ -71,9 +70,6 @@ public:
|
|||
|
||||
/** @brief %Check for implicit long cast of int result */
|
||||
void checkLongCast();
|
||||
|
||||
/** @brief %Check for mismatching enum usage */
|
||||
void checkEnumMismatch();
|
||||
private:
|
||||
|
||||
// Error messages..
|
||||
|
@ -82,8 +78,6 @@ private:
|
|||
void signConversionError(const Token *tok, const bool constvalue);
|
||||
void longCastAssignError(const Token *tok);
|
||||
void longCastReturnError(const Token *tok);
|
||||
void enumMismatchAssignError(const Token *tok, const ValueFlow::Value &value);
|
||||
void enumMismatchCompareError(const Token *tok, const ValueFlow::Value &value);
|
||||
|
||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
|
||||
CheckType c(nullptr, settings, errorLogger);
|
||||
|
@ -92,7 +86,6 @@ private:
|
|||
c.signConversionError(nullptr, false);
|
||||
c.longCastAssignError(nullptr);
|
||||
c.longCastReturnError(nullptr);
|
||||
c.enumMismatchAssignError(nullptr, ValueFlow::Value(1000));
|
||||
}
|
||||
|
||||
static std::string myName() {
|
||||
|
@ -105,8 +98,7 @@ private:
|
|||
"- signed integer overflow (only enabled when --platform is used)\n"
|
||||
"- dangerous sign conversion, when signed value can be negative\n"
|
||||
"- possible loss of information when assigning int result to long variable\n"
|
||||
"- possible loss of information when returning int result as long return value\n"
|
||||
"- enum usage with mismatching values\n";
|
||||
"- possible loss of information when returning int result as long return value\n";
|
||||
}
|
||||
};
|
||||
/// @}
|
||||
|
|
|
@ -39,8 +39,6 @@ private:
|
|||
TEST_CASE(signConversion);
|
||||
TEST_CASE(longCastAssign);
|
||||
TEST_CASE(longCastReturn);
|
||||
TEST_CASE(enumMismatchAssign);
|
||||
TEST_CASE(enumMismatchCompare);
|
||||
}
|
||||
|
||||
void check(const char code[], Settings* settings = 0) {
|
||||
|
@ -201,48 +199,6 @@ private:
|
|||
"}\n", &settings);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void enumMismatchAssign() {
|
||||
Settings settings;
|
||||
settings.addEnabled("style");
|
||||
|
||||
check("enum ABC {A,B,C};\n"
|
||||
"void f() {\n"
|
||||
" enum ABC abc = 5;\n"
|
||||
"}", &settings);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (style) Assigning mismatching value 5 to enum variable.\n", errout.str());
|
||||
|
||||
check("enum ABC {A=X,B,C};\n" // #7493 => enum constants for ABC has unknown values
|
||||
"void f() {\n"
|
||||
" enum ABC abc = 5;\n"
|
||||
"}", &settings);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void enumMismatchCompare() {
|
||||
Settings settings;
|
||||
settings.addEnabled("style");
|
||||
|
||||
check("enum ABC {A,B,C};\n"
|
||||
"void f(enum ABC abc) {\n"
|
||||
" if (abc==5) {}\n"
|
||||
"}", &settings);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (style) Comparing mismatching value 5 with enum variable.\n", errout.str());
|
||||
|
||||
check("enum ABC {A,B,C};\n"
|
||||
"void f(enum ABC abc) {\n"
|
||||
" if (5==abc) {}\n"
|
||||
"}", &settings);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (style) Comparing mismatching value 5 with enum variable.\n", errout.str());
|
||||
|
||||
check("enum ABC {NEG1=-2,NEG2=-1,POS1=1,POS2=2};\n" // #7491
|
||||
"void f(enum ABC abc) {\n"
|
||||
" if (abc>0) {}\n"
|
||||
"}", &settings);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestType)
|
||||
|
|
Loading…
Reference in New Issue