Remove 'unsafeClassDivZero' warning. The software verification will cover this better.
This commit is contained in:
parent
fcc5fad3ed
commit
eaa5bfcadd
|
@ -2586,50 +2586,6 @@ void CheckClass::copyCtorAndEqOperatorError(const Token *tok, const std::string
|
||||||
reportError(tok, Severity::warning, "copyCtorAndEqOperator", message);
|
reportError(tok, Severity::warning, "copyCtorAndEqOperator", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckClass::checkUnsafeClassDivZero(bool test)
|
|
||||||
{
|
|
||||||
// style severity: it is a style decision if classes should be safe or
|
|
||||||
// if users should be required to be careful. I expect that many users
|
|
||||||
// will disagree about these reports.
|
|
||||||
if (!mSettings->isEnabled(Settings::STYLE))
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (const Scope * classScope : mSymbolDatabase->classAndStructScopes) {
|
|
||||||
if (!test && classScope->classDef->fileIndex() != 1)
|
|
||||||
continue;
|
|
||||||
for (const Function &func : classScope->functionList) {
|
|
||||||
if (func.access != AccessControl::Public)
|
|
||||||
continue;
|
|
||||||
if (!func.hasBody())
|
|
||||||
continue;
|
|
||||||
if (func.name().compare(0,8,"operator")==0)
|
|
||||||
continue;
|
|
||||||
for (const Token *tok = func.functionScope->bodyStart; tok; tok = tok->next()) {
|
|
||||||
if (Token::Match(tok, "if|switch|while|for|do|}"))
|
|
||||||
break;
|
|
||||||
if (tok->str() != "/")
|
|
||||||
continue;
|
|
||||||
if (!tok->valueType() || !tok->valueType()->isIntegral())
|
|
||||||
continue;
|
|
||||||
if (!tok->astOperand2())
|
|
||||||
continue;
|
|
||||||
const Variable *var = tok->astOperand2()->variable();
|
|
||||||
if (!var || !var->isArgument())
|
|
||||||
continue;
|
|
||||||
unsafeClassDivZeroError(tok, classScope->className, func.name(), var->name());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckClass::unsafeClassDivZeroError(const Token *tok, const std::string &className, const std::string &methodName, const std::string &varName)
|
|
||||||
{
|
|
||||||
const std::string symbols = "$symbol:" + className + "\n$symbol:" + methodName + "\n$symbol:" + varName + '\n';
|
|
||||||
const std::string s = className + "::" + methodName + "()";
|
|
||||||
reportError(tok, Severity::style, "unsafeClassDivZero", symbols + "Public interface of " + className + " is not safe. When calling " + s + ", if parameter " + varName + " is 0 that leads to division by zero.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckClass::checkOverride()
|
void CheckClass::checkOverride()
|
||||||
{
|
{
|
||||||
if (!mSettings->isEnabled(Settings::STYLE))
|
if (!mSettings->isEnabled(Settings::STYLE))
|
||||||
|
|
|
@ -61,7 +61,6 @@ public:
|
||||||
|
|
||||||
// can't be a simplified check .. the 'sizeof' is used.
|
// can't be a simplified check .. the 'sizeof' is used.
|
||||||
checkClass.checkMemset();
|
checkClass.checkMemset();
|
||||||
checkClass.checkUnsafeClassDivZero();
|
|
||||||
checkClass.constructors();
|
checkClass.constructors();
|
||||||
checkClass.operatorEq();
|
checkClass.operatorEq();
|
||||||
checkClass.privateFunctions();
|
checkClass.privateFunctions();
|
||||||
|
@ -141,9 +140,6 @@ public:
|
||||||
/** @brief Check that copy constructor and operator defined together */
|
/** @brief Check that copy constructor and operator defined together */
|
||||||
void checkCopyCtorAndEqOperator();
|
void checkCopyCtorAndEqOperator();
|
||||||
|
|
||||||
/** @brief Check that arbitrary usage of the public interface does not result in division by zero */
|
|
||||||
void checkUnsafeClassDivZero(bool test=false);
|
|
||||||
|
|
||||||
/** @brief Check that the override keyword is used when overriding virtual functions */
|
/** @brief Check that the override keyword is used when overriding virtual functions */
|
||||||
void checkOverride();
|
void checkOverride();
|
||||||
|
|
||||||
|
@ -185,7 +181,6 @@ private:
|
||||||
void virtualFunctionCallInConstructorError(const Function * scopeFunction, const std::list<const Token *> & tokStack, const std::string &funcname);
|
void virtualFunctionCallInConstructorError(const Function * scopeFunction, const std::list<const Token *> & tokStack, const std::string &funcname);
|
||||||
void duplInheritedMembersError(const Token* tok1, const Token* tok2, const std::string &derivedName, const std::string &baseName, const std::string &variableName, bool derivedIsStruct, bool baseIsStruct);
|
void duplInheritedMembersError(const Token* tok1, const Token* tok2, const std::string &derivedName, const std::string &baseName, const std::string &variableName, bool derivedIsStruct, bool baseIsStruct);
|
||||||
void copyCtorAndEqOperatorError(const Token *tok, const std::string &classname, bool isStruct, bool hasCopyCtor);
|
void copyCtorAndEqOperatorError(const Token *tok, const std::string &classname, bool isStruct, bool hasCopyCtor);
|
||||||
void unsafeClassDivZeroError(const Token *tok, const std::string &className, const std::string &methodName, const std::string &varName);
|
|
||||||
void overrideError(const Function *funcInBase, const Function *funcInDerived);
|
void overrideError(const Function *funcInBase, const Function *funcInDerived);
|
||||||
void unsafeClassRefMemberError(const Token *tok, const std::string &varname);
|
void unsafeClassRefMemberError(const Token *tok, const std::string &varname);
|
||||||
|
|
||||||
|
@ -221,7 +216,6 @@ private:
|
||||||
c.selfInitializationError(nullptr, "var");
|
c.selfInitializationError(nullptr, "var");
|
||||||
c.duplInheritedMembersError(nullptr, nullptr, "class", "class", "variable", false, false);
|
c.duplInheritedMembersError(nullptr, nullptr, "class", "class", "variable", false, false);
|
||||||
c.copyCtorAndEqOperatorError(nullptr, "class", false, false);
|
c.copyCtorAndEqOperatorError(nullptr, "class", false, false);
|
||||||
c.unsafeClassDivZeroError(nullptr, "Class", "dostuff", "x");
|
|
||||||
c.pureVirtualFunctionCallInConstructorError(nullptr, std::list<const Token *>(), "f");
|
c.pureVirtualFunctionCallInConstructorError(nullptr, std::list<const Token *>(), "f");
|
||||||
c.virtualFunctionCallInConstructorError(nullptr, std::list<const Token *>(), "f");
|
c.virtualFunctionCallInConstructorError(nullptr, std::list<const Token *>(), "f");
|
||||||
c.overrideError(nullptr, nullptr);
|
c.overrideError(nullptr, nullptr);
|
||||||
|
|
|
@ -217,8 +217,6 @@ private:
|
||||||
TEST_CASE(explicitConstructors);
|
TEST_CASE(explicitConstructors);
|
||||||
TEST_CASE(copyCtorAndEqOperator);
|
TEST_CASE(copyCtorAndEqOperator);
|
||||||
|
|
||||||
TEST_CASE(unsafeClassDivZero);
|
|
||||||
|
|
||||||
TEST_CASE(override1);
|
TEST_CASE(override1);
|
||||||
TEST_CASE(overrideCVRefQualifiers);
|
TEST_CASE(overrideCVRefQualifiers);
|
||||||
|
|
||||||
|
@ -7058,47 +7056,6 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkUnsafeClassDivZero(const char code[]) {
|
|
||||||
// Clear the error log
|
|
||||||
errout.str("");
|
|
||||||
Settings settings;
|
|
||||||
settings.addEnabled("style");
|
|
||||||
|
|
||||||
// Tokenize..
|
|
||||||
Tokenizer tokenizer(&settings, this);
|
|
||||||
std::istringstream istr(code);
|
|
||||||
tokenizer.tokenize(istr, "test.cpp");
|
|
||||||
|
|
||||||
// Check..
|
|
||||||
CheckClass checkClass(&tokenizer, &settings, this);
|
|
||||||
checkClass.checkUnsafeClassDivZero(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void unsafeClassDivZero() {
|
|
||||||
checkUnsafeClassDivZero("class A {\n"
|
|
||||||
"public:\n"
|
|
||||||
" void dostuff(int x);\n"
|
|
||||||
"}\n"
|
|
||||||
"void A::dostuff(int x) { int a = 1000 / x; }");
|
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (style) Public interface of A is not safe. When calling A::dostuff(), if parameter x is 0 that leads to division by zero.\n", errout.str());
|
|
||||||
|
|
||||||
checkUnsafeClassDivZero("class A {\n"
|
|
||||||
"public:\n"
|
|
||||||
" void f1();\n"
|
|
||||||
" void f2(int x);\n"
|
|
||||||
"}\n"
|
|
||||||
"void A::f1() {}\n"
|
|
||||||
"void A::f2(int x) { int a = 1000 / x; }");
|
|
||||||
ASSERT_EQUALS("[test.cpp:7]: (style) Public interface of A is not safe. When calling A::f2(), if parameter x is 0 that leads to division by zero.\n", errout.str());
|
|
||||||
|
|
||||||
checkUnsafeClassDivZero("class A {\n"
|
|
||||||
"public:\n"
|
|
||||||
" void operator/(int x);\n"
|
|
||||||
"}\n"
|
|
||||||
"void A::operator/(int x) { int a = 1000 / x; }");
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkOverride(const char code[]) {
|
void checkOverride(const char code[]) {
|
||||||
// Clear the error log
|
// Clear the error log
|
||||||
errout.str("");
|
errout.str("");
|
||||||
|
|
Loading…
Reference in New Issue