feat: add modulo of one check (#9528) (#2650)

This commit is contained in:
miltolstoy 2020-05-21 00:01:32 +03:00 committed by GitHub
parent 9a5e53032d
commit a9d8b3495d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 1 deletions

View File

@ -3105,3 +3105,25 @@ void CheckOther::comparePointersError(const Token *tok, const ValueFlow::Value *
reportError(
errorPath, Severity::error, "comparePointers", verb + " pointers that point to different objects", CWE570, false);
}
void CheckOther::checkModuloOfOne()
{
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
if (!tok->astOperand2() || !tok->astOperand1())
continue;
if (tok->str() != "%")
continue;
if (!tok->valueType() || !tok->valueType()->isIntegral())
continue;
// Value flow..
const ValueFlow::Value *value = tok->astOperand2()->getValue(1LL);
if (value && value->isKnown())
checkModuloOfOneError(tok);
}
}
void CheckOther::checkModuloOfOneError(const Token *tok)
{
reportError(tok, Severity::style, "moduloofone", "Modulo of one is always equal to zero");
}

View File

@ -100,6 +100,7 @@ public:
checkOther.checkCastIntToCharAndBack();
checkOther.checkMisusedScopedObject();
checkOther.checkAccessOfMovedVariable();
checkOther.checkModuloOfOne();
}
/** @brief Clarify calculation for ".. a * b ? .." */
@ -215,6 +216,8 @@ public:
void checkComparePointers();
void checkModuloOfOne();
private:
// Error messages..
void checkComparisonFunctionIsAlwaysTrueOrFalseError(const Token* tok, const std::string &functionName, const std::string &varName, const bool result);
@ -271,6 +274,7 @@ private:
void shadowError(const Token *var, const Token *shadowed, std::string type);
void knownArgumentError(const Token *tok, const Token *ftok, const ValueFlow::Value *value);
void comparePointersError(const Token *tok, const ValueFlow::Value *v1, const ValueFlow::Value *v2);
void checkModuloOfOneError(const Token *tok);
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const OVERRIDE {
CheckOther c(nullptr, settings, errorLogger);
@ -342,6 +346,7 @@ private:
const std::vector<const Token *> nullvec;
c.funcArgOrderDifferent("function", nullptr, nullptr, nullvec, nullvec);
c.checkModuloOfOneError(nullptr);
}
static std::string myName() {
@ -402,7 +407,8 @@ private:
"- function declaration and definition argument names different.\n"
"- function declaration and definition argument order different.\n"
"- shadow variable.\n"
"- variable can be declared const.\n";
"- variable can be declared const.\n"
"- calculating modulo of one.\n";
}
};
/// @}

View File

@ -239,6 +239,8 @@ private:
TEST_CASE(checkComparePointers);
TEST_CASE(unusedVariableValueTemplate); // #8994
TEST_CASE(moduloOfOne);
}
void check(const char code[], const char *filename = nullptr, bool experimental = false, bool inconclusive = true, bool runSimpleChecks=true, bool verbose=false, Settings* settings = nullptr) {
@ -8565,6 +8567,20 @@ private:
ASSERT_EQUALS("", errout.str());
}
void moduloOfOne() {
check("void f(unsigned int x) {\n"
" int y = x % 1;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Modulo of one is always equal to zero\n", errout.str());
check("void f() {\n"
" for (int x = 1; x < 10; x++) {\n"
" int y = 100 % x;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
}
};
REGISTER_TEST(TestOther)