Refactorization: Improved internal implementation of severity and certainty levels

Backported from LCppC.
This commit is contained in:
PKEuS 2021-02-24 22:00:06 +01:00 committed by Daniel Marjamäki
parent c25b4f1ad6
commit 141d2ac215
85 changed files with 875 additions and 893 deletions

View File

@ -309,7 +309,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
return false; return false;
} }
// when "style" is enabled, also enable "warning", "performance" and "portability" // when "style" is enabled, also enable "warning", "performance" and "portability"
if (mSettings->isEnabled(Settings::STYLE)) { if (mSettings->severity.isEnabled(Severity::style)) {
mSettings->addEnabled("warning"); mSettings->addEnabled("warning");
mSettings->addEnabled("performance"); mSettings->addEnabled("performance");
mSettings->addEnabled("portability"); mSettings->addEnabled("portability");
@ -430,7 +430,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
// Inconclusive checking // Inconclusive checking
else if (std::strcmp(argv[i], "--inconclusive") == 0) else if (std::strcmp(argv[i], "--inconclusive") == 0)
mSettings->inconclusive = true; mSettings->certainty.enable(Certainty::inconclusive);
// Enables inline suppressions. // Enables inline suppressions.
else if (std::strcmp(argv[i], "--inline-suppr") == 0) else if (std::strcmp(argv[i], "--inline-suppr") == 0)
@ -938,7 +938,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
else if ((def || mSettings->preprocessOnly) && !maxconfigs) else if ((def || mSettings->preprocessOnly) && !maxconfigs)
mSettings->maxConfigs = 1U; mSettings->maxConfigs = 1U;
if (mSettings->isEnabled(Settings::UNUSED_FUNCTION) && mSettings->jobs > 1) { if (mSettings->checks.isEnabled(Checks::unusedFunction) && mSettings->jobs > 1) {
printMessage("cppcheck: unusedFunction check can't be used with '-j' option. Disabling unusedFunction check."); printMessage("cppcheck: unusedFunction check can't be used with '-j' option. Disabling unusedFunction check.");
} }

View File

@ -130,7 +130,7 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
++iter; ++iter;
else { else {
// If the include path is not found, warn user and remove the non-existing path from the list. // If the include path is not found, warn user and remove the non-existing path from the list.
if (settings.isEnabled(Settings::INFORMATION)) if (settings.severity.isEnabled(Severity::information))
std::cout << "(information) Couldn't find path given by -I '" << path << '\'' << std::endl; std::cout << "(information) Couldn't find path given by -I '" << path << '\'' << std::endl;
iter = settings.includePaths.erase(iter); iter = settings.includePaths.erase(iter);
} }
@ -853,7 +853,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck, int /*argc*/, const cha
if (!tryLoadLibrary(settings.library, argv[0], lib.c_str())) { if (!tryLoadLibrary(settings.library, argv[0], lib.c_str())) {
const std::string msg("Failed to load the library " + lib); const std::string msg("Failed to load the library " + lib);
const std::list<ErrorMessage::FileLocation> callstack; const std::list<ErrorMessage::FileLocation> callstack;
ErrorMessage errmsg(callstack, emptyString, Severity::information, msg, "failedToLoadCfg", false); ErrorMessage errmsg(callstack, emptyString, Severity::information, msg, "failedToLoadCfg", Certainty::normal);
reportErr(errmsg); reportErr(errmsg);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -879,7 +879,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck, int /*argc*/, const cha
"std.cfg should be available in " + cfgfolder + " or the FILESDIR " "std.cfg should be available in " + cfgfolder + " or the FILESDIR "
"should be configured."); "should be configured.");
#endif #endif
ErrorMessage errmsg(callstack, emptyString, Severity::information, msg+" "+details, "failedToLoadCfg", false); ErrorMessage errmsg(callstack, emptyString, Severity::information, msg+" "+details, "failedToLoadCfg", Certainty::normal);
reportErr(errmsg); reportErr(errmsg);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -963,7 +963,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck, int /*argc*/, const cha
cppcheck.analyseWholeProgram(mSettings->buildDir, mFiles); cppcheck.analyseWholeProgram(mSettings->buildDir, mFiles);
if (settings.isEnabled(Settings::INFORMATION) || settings.checkConfiguration) { if (settings.severity.isEnabled(Severity::information) || settings.checkConfiguration) {
const bool enableUnusedFunctionCheck = cppcheck.isUnusedFunctionCheckEnabled(); const bool enableUnusedFunctionCheck = cppcheck.isUnusedFunctionCheckEnabled();
if (settings.jointSuppressionReport) { if (settings.jointSuppressionReport) {
@ -982,7 +982,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck, int /*argc*/, const cha
if (!settings.checkConfiguration) { if (!settings.checkConfiguration) {
cppcheck.tooManyConfigsError("",0U); cppcheck.tooManyConfigsError("",0U);
if (settings.isEnabled(Settings::MISSING_INCLUDE) && (Preprocessor::missingIncludeFlag || Preprocessor::missingSystemIncludeFlag)) { if (settings.checks.isEnabled(Checks::missingInclude) && (Preprocessor::missingIncludeFlag || Preprocessor::missingSystemIncludeFlag)) {
const std::list<ErrorMessage::FileLocation> callStack; const std::list<ErrorMessage::FileLocation> callStack;
ErrorMessage msg(callStack, ErrorMessage msg(callStack,
emptyString, emptyString,
@ -994,7 +994,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck, int /*argc*/, const cha
"as include directories for Cppcheck. To see what files Cppcheck cannot find use " "as include directories for Cppcheck. To see what files Cppcheck cannot find use "
"--check-config.", "--check-config.",
Preprocessor::missingIncludeFlag ? "missingInclude" : "missingIncludeSystem", Preprocessor::missingIncludeFlag ? "missingInclude" : "missingIncludeSystem",
false); Certainty::normal);
reportInfo(msg); reportInfo(msg);
} }
} }

View File

@ -396,7 +396,7 @@ void CheckThread::parseClangErrors(const QString &tool, const QString &file0, QS
const std::string f0 = file0.toStdString(); const std::string f0 = file0.toStdString();
const std::string msg = e.message.toStdString(); const std::string msg = e.message.toStdString();
const std::string id = e.errorId.toStdString(); const std::string id = e.errorId.toStdString();
ErrorMessage errmsg(callstack, f0, e.severity, msg, id, false); ErrorMessage errmsg(callstack, f0, e.severity, msg, id, Certainty::normal);
mResult.reportErr(errmsg); mResult.reportErr(errmsg);
} }
} }

View File

@ -47,7 +47,7 @@ ErrorItem::ErrorItem(const ErrorMessage &errmsg)
, errorId(QString::fromStdString(errmsg.id)) , errorId(QString::fromStdString(errmsg.id))
, severity(errmsg.severity) , severity(errmsg.severity)
, incomplete(errmsg.incomplete) , incomplete(errmsg.incomplete)
, inconclusive(errmsg.inconclusive) , inconclusive(errmsg.certainty == Certainty::inconclusive)
, summary(QString::fromStdString(errmsg.shortMessage())) , summary(QString::fromStdString(errmsg.shortMessage()))
, message(QString::fromStdString(errmsg.verboseMessage())) , message(QString::fromStdString(errmsg.verboseMessage()))
, cwe(errmsg.cwe.id) , cwe(errmsg.cwe.id)

View File

@ -974,14 +974,14 @@ Settings MainWindow::getCppcheckSettings()
addIncludeDirs(includes, result); addIncludeDirs(includes, result);
} }
result.addEnabled("warning"); result.severity.enable(Severity::warning);
result.addEnabled("style"); result.severity.enable(Severity::style);
result.addEnabled("performance"); result.severity.enable(Severity::performance);
result.addEnabled("portability"); result.severity.enable(Severity::portability);
result.addEnabled("information"); result.severity.enable(Severity::information);
result.addEnabled("missingInclude"); result.checks.enable(Checks::missingInclude);
if (!result.buildDir.empty()) if (!result.buildDir.empty())
result.addEnabled("unusedFunction"); result.checks.enable(Checks::unusedFunction);
result.debugwarnings = mSettings->value(SETTINGS_SHOW_DEBUG_WARNINGS, false).toBool(); result.debugwarnings = mSettings->value(SETTINGS_SHOW_DEBUG_WARNINGS, false).toBool();
result.quiet = false; result.quiet = false;
result.verbose = true; result.verbose = true;
@ -989,7 +989,7 @@ Settings MainWindow::getCppcheckSettings()
result.xml = false; result.xml = false;
result.jobs = mSettings->value(SETTINGS_CHECK_THREADS, 1).toInt(); result.jobs = mSettings->value(SETTINGS_CHECK_THREADS, 1).toInt();
result.inlineSuppressions = mSettings->value(SETTINGS_INLINE_SUPPRESSIONS, false).toBool(); result.inlineSuppressions = mSettings->value(SETTINGS_INLINE_SUPPRESSIONS, false).toBool();
result.inconclusive = mSettings->value(SETTINGS_INCONCLUSIVE_ERRORS, false).toBool(); result.certainty.setEnabled(Certainty::inconclusive, mSettings->value(SETTINGS_INCONCLUSIVE_ERRORS, false).toBool());
if (!mProjectFile || result.platformType == cppcheck::Platform::Unspecified) if (!mProjectFile || result.platformType == cppcheck::Platform::Unspecified)
result.platform((cppcheck::Platform::PlatformType) mSettings->value(SETTINGS_CHECKED_PLATFORM, 0).toInt()); result.platform((cppcheck::Platform::PlatformType) mSettings->value(SETTINGS_CHECKED_PLATFORM, 0).toInt());
result.standards.setCPP(mSettings->value(SETTINGS_STD_CPP, QString()).toString().toStdString()); result.standards.setCPP(mSettings->value(SETTINGS_STD_CPP, QString()).toString().toStdString());

View File

@ -474,7 +474,7 @@ static void uninit(const Token *tok, const ExprEngine::Value &value, ExprEngine:
return; return;
} }
if (inconclusive && !dataBase->settings->inconclusive) if (inconclusive && !dataBase->settings->certainty.isEnabled(Certainty::inconclusive))
return; return;
// Avoid FP for array declaration // Avoid FP for array declaration

View File

@ -46,18 +46,18 @@ void Check::reportError(const ErrorMessage &errmsg)
} }
void Check::reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg, const CWE &cwe, bool inconclusive) void Check::reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty::CertaintyLevel certainty)
{ {
const ErrorMessage errmsg(callstack, mTokenizer ? &mTokenizer->list : nullptr, severity, id, msg, cwe, inconclusive, mSettings ? mSettings->bugHunting : false); const ErrorMessage errmsg(callstack, mTokenizer ? &mTokenizer->list : nullptr, severity, id, msg, cwe, certainty, mSettings ? mSettings->bugHunting : false);
if (mErrorLogger) if (mErrorLogger)
mErrorLogger->reportErr(errmsg); mErrorLogger->reportErr(errmsg);
else else
reportError(errmsg); reportError(errmsg);
} }
void Check::reportError(const ErrorPath &errorPath, Severity::SeverityType severity, const char id[], const std::string &msg, const CWE &cwe, bool inconclusive) void Check::reportError(const ErrorPath &errorPath, Severity::SeverityType severity, const char id[], const std::string &msg, const CWE &cwe, Certainty::CertaintyLevel certainty)
{ {
const ErrorMessage errmsg(errorPath, mTokenizer ? &mTokenizer->list : nullptr, severity, id, msg, cwe, inconclusive, mSettings ? mSettings->bugHunting : false); const ErrorMessage errmsg(errorPath, mTokenizer ? &mTokenizer->list : nullptr, severity, id, msg, cwe, certainty, mSettings ? mSettings->bugHunting : false);
if (mErrorLogger) if (mErrorLogger)
mErrorLogger->reportErr(errmsg); mErrorLogger->reportErr(errmsg);
else else

View File

@ -133,24 +133,24 @@ protected:
/** report an error */ /** report an error */
void reportError(const Token *tok, const Severity::SeverityType severity, const std::string &id, const std::string &msg) { void reportError(const Token *tok, const Severity::SeverityType severity, const std::string &id, const std::string &msg) {
reportError(tok, severity, id, msg, CWE(0U), false); reportError(tok, severity, id, msg, CWE(0U), Certainty::normal);
} }
/** report an error */ /** report an error */
void reportError(const Token *tok, const Severity::SeverityType severity, const std::string &id, const std::string &msg, const CWE &cwe, bool inconclusive) { void reportError(const Token *tok, const Severity::SeverityType severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty::CertaintyLevel certainty) {
const std::list<const Token *> callstack(1, tok); const std::list<const Token *> callstack(1, tok);
reportError(callstack, severity, id, msg, cwe, inconclusive); reportError(callstack, severity, id, msg, cwe, certainty);
} }
/** report an error */ /** report an error */
void reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg) { void reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg) {
reportError(callstack, severity, id, msg, CWE(0U), false); reportError(callstack, severity, id, msg, CWE(0U), Certainty::normal);
} }
/** report an error */ /** report an error */
void reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg, const CWE &cwe, bool inconclusive); void reportError(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty::CertaintyLevel certainty);
void reportError(const ErrorPath &errorPath, Severity::SeverityType severity, const char id[], const std::string &msg, const CWE &cwe, bool inconclusive); void reportError(const ErrorPath &errorPath, Severity::SeverityType severity, const char id[], const std::string &msg, const CWE &cwe, Certainty::CertaintyLevel certainty);
ErrorPath getErrorPath(const Token* errtok, const ValueFlow::Value* value, const std::string& bug) const; ErrorPath getErrorPath(const Token* errtok, const ValueFlow::Value* value, const std::string& bug) const;

View File

@ -42,7 +42,7 @@ namespace {
void Check64BitPortability::pointerassignment() void Check64BitPortability::pointerassignment()
{ {
if (!mSettings->isEnabled(Settings::PORTABILITY)) if (!mSettings->severity.isEnabled(Severity::portability))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -124,7 +124,7 @@ void Check64BitPortability::assignmentAddressToIntegerError(const Token *tok)
"Assigning a pointer to an integer (int/long/etc) is not portable across different platforms and " "Assigning a pointer to an integer (int/long/etc) is not portable across different platforms and "
"compilers. For example in 32-bit Windows and linux they are same width, but in 64-bit Windows and linux " "compilers. For example in 32-bit Windows and linux they are same width, but in 64-bit Windows and linux "
"they are of different width. In worst case you end up assigning 64-bit address to 32-bit integer. The safe " "they are of different width. In worst case you end up assigning 64-bit address to 32-bit integer. The safe "
"way is to store addresses only in pointer types (or typedefs like uintptr_t).", CWE758, false); "way is to store addresses only in pointer types (or typedefs like uintptr_t).", CWE758, Certainty::normal);
} }
void Check64BitPortability::assignmentIntegerToAddressError(const Token *tok) void Check64BitPortability::assignmentIntegerToAddressError(const Token *tok)
@ -135,7 +135,7 @@ void Check64BitPortability::assignmentIntegerToAddressError(const Token *tok)
"Assigning an integer (int/long/etc) to a pointer is not portable across different platforms and " "Assigning an integer (int/long/etc) to a pointer is not portable across different platforms and "
"compilers. For example in 32-bit Windows and linux they are same width, but in 64-bit Windows and linux " "compilers. For example in 32-bit Windows and linux they are same width, but in 64-bit Windows and linux "
"they are of different width. In worst case you end up assigning 64-bit integer to 32-bit pointer. The safe " "they are of different width. In worst case you end up assigning 64-bit integer to 32-bit pointer. The safe "
"way is to store addresses only in pointer types (or typedefs like uintptr_t).", CWE758, false); "way is to store addresses only in pointer types (or typedefs like uintptr_t).", CWE758, Certainty::normal);
} }
void Check64BitPortability::returnPointerError(const Token *tok) void Check64BitPortability::returnPointerError(const Token *tok)
@ -146,7 +146,7 @@ void Check64BitPortability::returnPointerError(const Token *tok)
"Returning an address value in a function with integer (int/long/etc) return type is not portable across " "Returning an address value in a function with integer (int/long/etc) return type is not portable across "
"different platforms and compilers. For example in 32-bit Windows and Linux they are same width, but in " "different platforms and compilers. For example in 32-bit Windows and Linux they are same width, but in "
"64-bit Windows and Linux they are of different width. In worst case you end up casting 64-bit address down " "64-bit Windows and Linux they are of different width. In worst case you end up casting 64-bit address down "
"to 32-bit integer. The safe way is to always return an integer.", CWE758, false); "to 32-bit integer. The safe way is to always return an integer.", CWE758, Certainty::normal);
} }
void Check64BitPortability::returnIntegerError(const Token *tok) void Check64BitPortability::returnIntegerError(const Token *tok)
@ -157,5 +157,5 @@ void Check64BitPortability::returnIntegerError(const Token *tok)
"Returning an integer (int/long/etc) in a function with pointer return type is not portable across different " "Returning an integer (int/long/etc) in a function with pointer return type is not portable across different "
"platforms and compilers. For example in 32-bit Windows and Linux they are same width, but in 64-bit Windows " "platforms and compilers. For example in 32-bit Windows and Linux they are same width, but in 64-bit Windows "
"and Linux they are of different width. In worst case you end up casting 64-bit integer down to 32-bit pointer. " "and Linux they are of different width. In worst case you end up casting 64-bit integer down to 32-bit pointer. "
"The safe way is to always return a pointer.", CWE758, false); "The safe way is to always return a pointer.", CWE758, Certainty::normal);
} }

View File

@ -40,7 +40,7 @@ namespace {
void CheckAssert::assertWithSideEffects() void CheckAssert::assertWithSideEffects()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
for (const Token* tok = mTokenizer->list.front(); tok; tok = tok->next()) { for (const Token* tok = mTokenizer->list.front(); tok; tok = tok->next()) {
@ -104,7 +104,7 @@ void CheckAssert::sideEffectInAssertError(const Token *tok, const std::string& f
"Non-pure function: '$symbol' is called inside assert statement. " "Non-pure function: '$symbol' is called inside assert statement. "
"Assert statements are removed from release builds so the code inside " "Assert statements are removed from release builds so the code inside "
"assert statement is not executed. If the code is needed also in release " "assert statement is not executed. If the code is needed also in release "
"builds, this is a bug.", CWE398, false); "builds, this is a bug.", CWE398, Certainty::normal);
} }
void CheckAssert::assignmentInAssertError(const Token *tok, const std::string& varname) void CheckAssert::assignmentInAssertError(const Token *tok, const std::string& varname)
@ -116,7 +116,7 @@ void CheckAssert::assignmentInAssertError(const Token *tok, const std::string& v
"Variable '$symbol' is modified inside assert statement. " "Variable '$symbol' is modified inside assert statement. "
"Assert statements are removed from release builds so the code inside " "Assert statements are removed from release builds so the code inside "
"assert statement is not executed. If the code is needed also in release " "assert statement is not executed. If the code is needed also in release "
"builds, this is a bug.", CWE398, false); "builds, this is a bug.", CWE398, Certainty::normal);
} }
// checks if side effects happen on the variable prior to tmp // checks if side effects happen on the variable prior to tmp

View File

@ -202,8 +202,8 @@ static bool variableIsUsedInScope(const Token* start, nonneg int varId, const Sc
void CheckAutoVariables::assignFunctionArg() void CheckAutoVariables::assignFunctionArg()
{ {
const bool printStyle = mSettings->isEnabled(Settings::STYLE); const bool printStyle = mSettings->severity.isEnabled(Severity::style);
const bool printWarning = mSettings->isEnabled(Settings::WARNING); const bool printWarning = mSettings->severity.isEnabled(Severity::warning);
if (!printStyle && !printWarning) if (!printStyle && !printWarning)
return; return;
@ -231,7 +231,7 @@ void CheckAutoVariables::assignFunctionArg()
void CheckAutoVariables::autoVariables() void CheckAutoVariables::autoVariables()
{ {
const bool printInconclusive = mSettings->inconclusive; const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive);
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope * scope : symbolDatabase->functionScopes) { for (const Scope * scope : symbolDatabase->functionScopes) {
for (const Token *tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) { for (const Token *tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) {
@ -331,17 +331,17 @@ bool CheckAutoVariables::checkAutoVariableAssignment(const Token *expr, bool inc
void CheckAutoVariables::errorReturnAddressToAutoVariable(const Token *tok) void CheckAutoVariables::errorReturnAddressToAutoVariable(const Token *tok)
{ {
reportError(tok, Severity::error, "returnAddressOfAutoVariable", "Address of an auto-variable returned.", CWE562, false); reportError(tok, Severity::error, "returnAddressOfAutoVariable", "Address of an auto-variable returned.", CWE562, Certainty::normal);
} }
void CheckAutoVariables::errorReturnAddressToAutoVariable(const Token *tok, const ValueFlow::Value *value) void CheckAutoVariables::errorReturnAddressToAutoVariable(const Token *tok, const ValueFlow::Value *value)
{ {
reportError(tok, Severity::error, "returnAddressOfAutoVariable", "Address of auto-variable '" + value->tokvalue->astOperand1()->expressionString() + "' returned", CWE562, false); reportError(tok, Severity::error, "returnAddressOfAutoVariable", "Address of auto-variable '" + value->tokvalue->astOperand1()->expressionString() + "' returned", CWE562, Certainty::normal);
} }
void CheckAutoVariables::errorReturnPointerToLocalArray(const Token *tok) void CheckAutoVariables::errorReturnPointerToLocalArray(const Token *tok)
{ {
reportError(tok, Severity::error, "returnLocalVariable", "Pointer to local array variable returned.", CWE562, false); reportError(tok, Severity::error, "returnLocalVariable", "Pointer to local array variable returned.", CWE562, Certainty::normal);
} }
void CheckAutoVariables::errorAutoVariableAssignment(const Token *tok, bool inconclusive) void CheckAutoVariables::errorAutoVariableAssignment(const Token *tok, bool inconclusive)
@ -352,7 +352,7 @@ void CheckAutoVariables::errorAutoVariableAssignment(const Token *tok, bool inco
"Dangerous assignment - the function parameter is assigned the address of a local " "Dangerous assignment - the function parameter is assigned the address of a local "
"auto-variable. Local auto-variables are reserved from the stack which " "auto-variable. Local auto-variables are reserved from the stack which "
"is freed when the function ends. So the pointer to a local variable " "is freed when the function ends. So the pointer to a local variable "
"is invalid after the function ends.", CWE562, false); "is invalid after the function ends.", CWE562, Certainty::normal);
} else { } else {
reportError(tok, Severity::error, "autoVariables", reportError(tok, Severity::error, "autoVariables",
"Address of local auto-variable assigned to a function parameter.\n" "Address of local auto-variable assigned to a function parameter.\n"
@ -361,7 +361,7 @@ void CheckAutoVariables::errorAutoVariableAssignment(const Token *tok, bool inco
"the function ends. The address is invalid after the function ends and it " "the function ends. The address is invalid after the function ends and it "
"might 'leak' from the function through the parameter.", "might 'leak' from the function through the parameter.",
CWE562, CWE562,
true); Certainty::inconclusive);
} }
} }
@ -372,7 +372,7 @@ void CheckAutoVariables::errorReturnAddressOfFunctionParameter(const Token *tok,
"Address of function parameter '$symbol' returned.\n" "Address of function parameter '$symbol' returned.\n"
"Address of the function parameter '$symbol' becomes invalid after the function exits because " "Address of the function parameter '$symbol' becomes invalid after the function exits because "
"function parameters are stored on the stack which is freed when the function exits. Thus the returned " "function parameters are stored on the stack which is freed when the function exits. Thus the returned "
"value is invalid.", CWE562, false); "value is invalid.", CWE562, Certainty::normal);
} }
void CheckAutoVariables::errorUselessAssignmentArg(const Token *tok) void CheckAutoVariables::errorUselessAssignmentArg(const Token *tok)
@ -380,7 +380,7 @@ void CheckAutoVariables::errorUselessAssignmentArg(const Token *tok)
reportError(tok, reportError(tok,
Severity::style, Severity::style,
"uselessAssignmentArg", "uselessAssignmentArg",
"Assignment of function parameter has no effect outside the function.", CWE398, false); "Assignment of function parameter has no effect outside the function.", CWE398, Certainty::normal);
} }
void CheckAutoVariables::errorUselessAssignmentPtrArg(const Token *tok) void CheckAutoVariables::errorUselessAssignmentPtrArg(const Token *tok)
@ -388,7 +388,7 @@ void CheckAutoVariables::errorUselessAssignmentPtrArg(const Token *tok)
reportError(tok, reportError(tok,
Severity::warning, Severity::warning,
"uselessAssignmentPtrArg", "uselessAssignmentPtrArg",
"Assignment of function parameter has no effect outside the function. Did you forget dereferencing it?", CWE398, false); "Assignment of function parameter has no effect outside the function. Did you forget dereferencing it?", CWE398, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -492,7 +492,7 @@ static bool isDanglingSubFunction(const Token* tokvalue, const Token* tok)
void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token * end) void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token * end)
{ {
const bool printInconclusive = (mSettings->inconclusive); const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive);
if (!start) if (!start)
return; return;
const Scope * scope = start->scope(); const Scope * scope = start->scope();
@ -630,7 +630,7 @@ void CheckAutoVariables::errorReturnDanglingLifetime(const Token *tok, const Val
ErrorPath errorPath = val ? val->errorPath : ErrorPath(); ErrorPath errorPath = val ? val->errorPath : ErrorPath();
std::string msg = "Returning " + lifetimeMessage(tok, val, errorPath); std::string msg = "Returning " + lifetimeMessage(tok, val, errorPath);
errorPath.emplace_back(tok, ""); errorPath.emplace_back(tok, "");
reportError(errorPath, Severity::error, "returnDanglingLifetime", msg + " that will be invalid when returning.", CWE562, inconclusive); reportError(errorPath, Severity::error, "returnDanglingLifetime", msg + " that will be invalid when returning.", CWE562, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckAutoVariables::errorInvalidLifetime(const Token *tok, const ValueFlow::Value* val) void CheckAutoVariables::errorInvalidLifetime(const Token *tok, const ValueFlow::Value* val)
@ -639,7 +639,7 @@ void CheckAutoVariables::errorInvalidLifetime(const Token *tok, const ValueFlow:
ErrorPath errorPath = val ? val->errorPath : ErrorPath(); ErrorPath errorPath = val ? val->errorPath : ErrorPath();
std::string msg = "Using " + lifetimeMessage(tok, val, errorPath); std::string msg = "Using " + lifetimeMessage(tok, val, errorPath);
errorPath.emplace_back(tok, ""); errorPath.emplace_back(tok, "");
reportError(errorPath, Severity::error, "invalidLifetime", msg + " that is out of scope.", CWE562, inconclusive); reportError(errorPath, Severity::error, "invalidLifetime", msg + " that is out of scope.", CWE562, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckAutoVariables::errorDanglingTemporaryLifetime(const Token* tok, const ValueFlow::Value* val) void CheckAutoVariables::errorDanglingTemporaryLifetime(const Token* tok, const ValueFlow::Value* val)
@ -648,7 +648,7 @@ void CheckAutoVariables::errorDanglingTemporaryLifetime(const Token* tok, const
ErrorPath errorPath = val ? val->errorPath : ErrorPath(); ErrorPath errorPath = val ? val->errorPath : ErrorPath();
std::string msg = "Using " + lifetimeMessage(tok, val, errorPath); std::string msg = "Using " + lifetimeMessage(tok, val, errorPath);
errorPath.emplace_back(tok, ""); errorPath.emplace_back(tok, "");
reportError(errorPath, Severity::error, "danglingTemporaryLifetime", msg + " to temporary.", CWE562, inconclusive); reportError(errorPath, Severity::error, "danglingTemporaryLifetime", msg + " to temporary.", CWE562, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckAutoVariables::errorDanglngLifetime(const Token *tok, const ValueFlow::Value *val) void CheckAutoVariables::errorDanglngLifetime(const Token *tok, const ValueFlow::Value *val)
@ -658,21 +658,21 @@ void CheckAutoVariables::errorDanglngLifetime(const Token *tok, const ValueFlow:
std::string tokName = tok ? tok->expressionString() : "x"; std::string tokName = tok ? tok->expressionString() : "x";
std::string msg = "Non-local variable '" + tokName + "' will use " + lifetimeMessage(tok, val, errorPath); std::string msg = "Non-local variable '" + tokName + "' will use " + lifetimeMessage(tok, val, errorPath);
errorPath.emplace_back(tok, ""); errorPath.emplace_back(tok, "");
reportError(errorPath, Severity::error, "danglingLifetime", msg + ".", CWE562, inconclusive); reportError(errorPath, Severity::error, "danglingLifetime", msg + ".", CWE562, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckAutoVariables::errorDanglingTempReference(const Token* tok, ErrorPath errorPath, bool inconclusive) void CheckAutoVariables::errorDanglingTempReference(const Token* tok, ErrorPath errorPath, bool inconclusive)
{ {
errorPath.emplace_back(tok, ""); errorPath.emplace_back(tok, "");
reportError( reportError(
errorPath, Severity::error, "danglingTempReference", "Using reference to dangling temporary.", CWE562, inconclusive); errorPath, Severity::error, "danglingTempReference", "Using reference to dangling temporary.", CWE562, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckAutoVariables::errorReturnReference(const Token* tok, ErrorPath errorPath, bool inconclusive) void CheckAutoVariables::errorReturnReference(const Token* tok, ErrorPath errorPath, bool inconclusive)
{ {
errorPath.emplace_back(tok, ""); errorPath.emplace_back(tok, "");
reportError( reportError(
errorPath, Severity::error, "returnReference", "Reference to local variable returned.", CWE562, inconclusive); errorPath, Severity::error, "returnReference", "Reference to local variable returned.", CWE562, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckAutoVariables::errorDanglingReference(const Token *tok, const Variable *var, ErrorPath errorPath) void CheckAutoVariables::errorDanglingReference(const Token *tok, const Variable *var, ErrorPath errorPath)
@ -681,14 +681,14 @@ void CheckAutoVariables::errorDanglingReference(const Token *tok, const Variable
std::string varName = var ? var->name() : "y"; std::string varName = var ? var->name() : "y";
std::string msg = "Non-local reference variable '" + tokName + "' to local variable '" + varName + "'"; std::string msg = "Non-local reference variable '" + tokName + "' to local variable '" + varName + "'";
errorPath.emplace_back(tok, ""); errorPath.emplace_back(tok, "");
reportError(errorPath, Severity::error, "danglingReference", msg, CWE562, false); reportError(errorPath, Severity::error, "danglingReference", msg, CWE562, Certainty::normal);
} }
void CheckAutoVariables::errorReturnTempReference(const Token* tok, ErrorPath errorPath, bool inconclusive) void CheckAutoVariables::errorReturnTempReference(const Token* tok, ErrorPath errorPath, bool inconclusive)
{ {
errorPath.emplace_back(tok, ""); errorPath.emplace_back(tok, "");
reportError( reportError(
errorPath, Severity::error, "returnTempReference", "Reference to temporary returned.", CWE562, inconclusive); errorPath, Severity::error, "returnTempReference", "Reference to temporary returned.", CWE562, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckAutoVariables::errorInvalidDeallocation(const Token *tok, const ValueFlow::Value *val) void CheckAutoVariables::errorInvalidDeallocation(const Token *tok, const ValueFlow::Value *val)
@ -711,5 +711,5 @@ void CheckAutoVariables::errorInvalidDeallocation(const Token *tok, const ValueF
"autovarInvalidDeallocation", "autovarInvalidDeallocation",
"Deallocation of an " + type + " results in undefined behaviour.\n" "Deallocation of an " + type + " results in undefined behaviour.\n"
"The deallocation of an " + type + " results in undefined behaviour. You should only free memory " "The deallocation of an " + type + " results in undefined behaviour. You should only free memory "
"that has been allocated dynamically.", CWE590, false); "that has been allocated dynamically.", CWE590, Certainty::normal);
} }

View File

@ -49,7 +49,7 @@ static bool isBool(const Variable* var)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckBool::checkIncrementBoolean() void CheckBool::checkIncrementBoolean()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -70,7 +70,7 @@ void CheckBool::incrementBooleanError(const Token *tok)
"incrementboolean", "incrementboolean",
"Incrementing a variable of type 'bool' with postfix operator++ is deprecated by the C++ Standard. You should assign it the value 'true' instead.\n" "Incrementing a variable of type 'bool' with postfix operator++ is deprecated by the C++ Standard. You should assign it the value 'true' instead.\n"
"The operand of a postfix increment operator may be of type bool but it is deprecated by C++ Standard (Annex D-1) and the operand is always set to true. You should assign it the value 'true' instead.", "The operand of a postfix increment operator may be of type bool but it is deprecated by C++ Standard (Annex D-1) and the operand is always set to true. You should assign it the value 'true' instead.",
CWE398, false CWE398, Certainty::normal
); );
} }
@ -80,12 +80,12 @@ void CheckBool::incrementBooleanError(const Token *tok)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckBool::checkBitwiseOnBoolean() void CheckBool::checkBitwiseOnBoolean()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
// danmar: this is inconclusive because I don't like that there are // danmar: this is inconclusive because I don't like that there are
// warnings for calculations. Example: set_flag(a & b); // warnings for calculations. Example: set_flag(a & b);
if (!mSettings->inconclusive) if (!mSettings->certainty.isEnabled(Certainty::inconclusive))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -108,7 +108,7 @@ void CheckBool::bitwiseOnBooleanError(const Token *tok, const std::string &expre
reportError(tok, Severity::style, "bitwiseOnBoolean", reportError(tok, Severity::style, "bitwiseOnBoolean",
"Boolean expression '" + expression + "' is used in bitwise operation. Did you mean '" + op + "'?", "Boolean expression '" + expression + "' is used in bitwise operation. Did you mean '" + op + "'?",
CWE398, CWE398,
true); Certainty::inconclusive);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -117,7 +117,7 @@ void CheckBool::bitwiseOnBooleanError(const Token *tok, const std::string &expre
void CheckBool::checkComparisonOfBoolWithInt() void CheckBool::checkComparisonOfBoolWithInt()
{ {
if (!mSettings->isEnabled(Settings::WARNING) || !mTokenizer->isCPP()) if (!mSettings->severity.isEnabled(Severity::warning) || !mTokenizer->isCPP())
return; return;
const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase();
@ -166,7 +166,7 @@ static bool tokenIsFunctionReturningBool(const Token* tok)
void CheckBool::checkComparisonOfFuncReturningBool() void CheckBool::checkComparisonOfFuncReturningBool()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
if (!mTokenizer->isCPP()) if (!mTokenizer->isCPP())
@ -205,7 +205,7 @@ void CheckBool::comparisonOfFuncReturningBoolError(const Token *tok, const std::
"Comparison of a function returning boolean value using relational (<, >, <= or >=) operator.\n" "Comparison of a function returning boolean value using relational (<, >, <= or >=) operator.\n"
"The return type of function '" + expression + "' is 'bool' " "The return type of function '" + expression + "' is 'bool' "
"and result is of type 'bool'. Comparing 'bool' value using relational (<, >, <= or >=)" "and result is of type 'bool'. Comparing 'bool' value using relational (<, >, <= or >=)"
" operator could cause unexpected results.", CWE398, false); " operator could cause unexpected results.", CWE398, Certainty::normal);
} }
void CheckBool::comparisonOfTwoFuncsReturningBoolError(const Token *tok, const std::string &expression1, const std::string &expression2) void CheckBool::comparisonOfTwoFuncsReturningBoolError(const Token *tok, const std::string &expression1, const std::string &expression2)
@ -214,7 +214,7 @@ void CheckBool::comparisonOfTwoFuncsReturningBoolError(const Token *tok, const s
"Comparison of two functions returning boolean value using relational (<, >, <= or >=) operator.\n" "Comparison of two functions returning boolean value using relational (<, >, <= or >=) operator.\n"
"The return type of function '" + expression1 + "' and function '" + expression2 + "' is 'bool' " "The return type of function '" + expression1 + "' and function '" + expression2 + "' is 'bool' "
"and result is of type 'bool'. Comparing 'bool' value using relational (<, >, <= or >=)" "and result is of type 'bool'. Comparing 'bool' value using relational (<, >, <= or >=)"
" operator could cause unexpected results.", CWE398, false); " operator could cause unexpected results.", CWE398, Certainty::normal);
} }
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
@ -225,10 +225,10 @@ void CheckBool::checkComparisonOfBoolWithBool()
{ {
// FIXME: This checking is "experimental" because of the false positives // FIXME: This checking is "experimental" because of the false positives
// when self checking lib/tokenize.cpp (#2617) // when self checking lib/tokenize.cpp (#2617)
if (!mSettings->experimental) if (!mSettings->certainty.isEnabled(Certainty::experimental))
return; return;
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
if (!mTokenizer->isCPP()) if (!mTokenizer->isCPP())
@ -271,7 +271,7 @@ void CheckBool::comparisonOfBoolWithBoolError(const Token *tok, const std::strin
"Comparison of a variable having boolean value using relational (<, >, <= or >=) operator.\n" "Comparison of a variable having boolean value using relational (<, >, <= or >=) operator.\n"
"The variable '" + expression + "' is of type 'bool' " "The variable '" + expression + "' is of type 'bool' "
"and comparing 'bool' value using relational (<, >, <= or >=)" "and comparing 'bool' value using relational (<, >, <= or >=)"
" operator could cause unexpected results.", CWE398, false); " operator could cause unexpected results.", CWE398, Certainty::normal);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -290,14 +290,14 @@ void CheckBool::checkAssignBoolToPointer()
void CheckBool::assignBoolToPointerError(const Token *tok) void CheckBool::assignBoolToPointerError(const Token *tok)
{ {
reportError(tok, Severity::error, "assignBoolToPointer", reportError(tok, Severity::error, "assignBoolToPointer",
"Boolean value assigned to pointer.", CWE587, false); "Boolean value assigned to pointer.", CWE587, Certainty::normal);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CheckBool::checkComparisonOfBoolExpressionWithInt() void CheckBool::checkComparisonOfBoolExpressionWithInt()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase();
@ -357,10 +357,10 @@ void CheckBool::comparisonOfBoolExpressionWithIntError(const Token *tok, bool no
{ {
if (not0or1) if (not0or1)
reportError(tok, Severity::warning, "compareBoolExpressionWithInt", reportError(tok, Severity::warning, "compareBoolExpressionWithInt",
"Comparison of a boolean expression with an integer other than 0 or 1.", CWE398, false); "Comparison of a boolean expression with an integer other than 0 or 1.", CWE398, Certainty::normal);
else else
reportError(tok, Severity::warning, "compareBoolExpressionWithInt", reportError(tok, Severity::warning, "compareBoolExpressionWithInt",
"Comparison of a boolean expression with an integer.", CWE398, false); "Comparison of a boolean expression with an integer.", CWE398, Certainty::normal);
} }
@ -411,14 +411,14 @@ void CheckBool::pointerArithBoolError(const Token *tok)
Severity::error, Severity::error,
"pointerArithBool", "pointerArithBool",
"Converting pointer arithmetic result to bool. The bool is always true unless there is undefined behaviour.\n" "Converting pointer arithmetic result to bool. The bool is always true unless there is undefined behaviour.\n"
"Converting pointer arithmetic result to bool. The boolean result is always true unless there is pointer arithmetic overflow, and overflow is undefined behaviour. Probably a dereference is forgotten.", CWE571, false); "Converting pointer arithmetic result to bool. The boolean result is always true unless there is pointer arithmetic overflow, and overflow is undefined behaviour. Probably a dereference is forgotten.", CWE571, Certainty::normal);
} }
void CheckBool::checkAssignBoolToFloat() void CheckBool::checkAssignBoolToFloat()
{ {
if (!mTokenizer->isCPP()) if (!mTokenizer->isCPP())
return; return;
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope * scope : symbolDatabase->functionScopes) { for (const Scope * scope : symbolDatabase->functionScopes) {
@ -433,12 +433,12 @@ void CheckBool::checkAssignBoolToFloat()
void CheckBool::assignBoolToFloatError(const Token *tok) void CheckBool::assignBoolToFloatError(const Token *tok)
{ {
reportError(tok, Severity::style, "assignBoolToFloat", reportError(tok, Severity::style, "assignBoolToFloat",
"Boolean value assigned to floating point variable.", CWE704, false); "Boolean value assigned to floating point variable.", CWE704, Certainty::normal);
} }
void CheckBool::returnValueOfFunctionReturningBool() void CheckBool::returnValueOfFunctionReturningBool()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase();

View File

@ -59,6 +59,6 @@ void CheckBoost::checkBoostForeachModification()
void CheckBoost::boostForeachError(const Token *tok) void CheckBoost::boostForeachError(const Token *tok)
{ {
reportError(tok, Severity::error, "boostForeachError", reportError(tok, Severity::error, "boostForeachError",
"BOOST_FOREACH caches the end() iterator. It's undefined behavior if you modify the container inside.", CWE664, false "BOOST_FOREACH caches the end() iterator. It's undefined behavior if you modify the container inside.", CWE664, Certainty::normal
); );
} }

View File

@ -370,8 +370,8 @@ static std::string arrayIndexMessage(const Token *tok, const std::vector<Dimensi
void CheckBufferOverrun::arrayIndexError(const Token *tok, const std::vector<Dimension> &dimensions, const std::vector<const ValueFlow::Value *> &indexes) void CheckBufferOverrun::arrayIndexError(const Token *tok, const std::vector<Dimension> &dimensions, const std::vector<const ValueFlow::Value *> &indexes)
{ {
if (!tok) { if (!tok) {
reportError(tok, Severity::error, "arrayIndexOutOfBounds", "Array 'arr[16]' accessed at index 16, which is out of bounds.", CWE_BUFFER_OVERRUN, false); reportError(tok, Severity::error, "arrayIndexOutOfBounds", "Array 'arr[16]' accessed at index 16, which is out of bounds.", CWE_BUFFER_OVERRUN, Certainty::normal);
reportError(tok, Severity::warning, "arrayIndexOutOfBoundsCond", "Array 'arr[16]' accessed at index 16, which is out of bounds.", CWE_BUFFER_OVERRUN, false); reportError(tok, Severity::warning, "arrayIndexOutOfBoundsCond", "Array 'arr[16]' accessed at index 16, which is out of bounds.", CWE_BUFFER_OVERRUN, Certainty::normal);
return; return;
} }
@ -380,7 +380,7 @@ void CheckBufferOverrun::arrayIndexError(const Token *tok, const std::vector<Dim
for (const ValueFlow::Value *indexValue: indexes) { for (const ValueFlow::Value *indexValue: indexes) {
if (!indexValue) if (!indexValue)
continue; continue;
if (!indexValue->errorSeverity() && !mSettings->isEnabled(Settings::WARNING)) if (!indexValue->errorSeverity() && !mSettings->severity.isEnabled(Severity::warning))
return; return;
if (indexValue->condition) if (indexValue->condition)
condition = indexValue->condition; condition = indexValue->condition;
@ -393,13 +393,13 @@ void CheckBufferOverrun::arrayIndexError(const Token *tok, const std::vector<Dim
index->condition ? "arrayIndexOutOfBoundsCond" : "arrayIndexOutOfBounds", index->condition ? "arrayIndexOutOfBoundsCond" : "arrayIndexOutOfBounds",
arrayIndexMessage(tok, dimensions, indexes, condition), arrayIndexMessage(tok, dimensions, indexes, condition),
CWE_BUFFER_OVERRUN, CWE_BUFFER_OVERRUN,
index->isInconclusive()); index->isInconclusive() ? Certainty::inconclusive : Certainty::normal);
} }
void CheckBufferOverrun::negativeIndexError(const Token *tok, const std::vector<Dimension> &dimensions, const std::vector<const ValueFlow::Value *> &indexes) void CheckBufferOverrun::negativeIndexError(const Token *tok, const std::vector<Dimension> &dimensions, const std::vector<const ValueFlow::Value *> &indexes)
{ {
if (!tok) { if (!tok) {
reportError(tok, Severity::error, "negativeIndex", "Negative array index", CWE_BUFFER_UNDERRUN, false); reportError(tok, Severity::error, "negativeIndex", "Negative array index", CWE_BUFFER_UNDERRUN, Certainty::normal);
return; return;
} }
@ -408,7 +408,7 @@ void CheckBufferOverrun::negativeIndexError(const Token *tok, const std::vector<
for (const ValueFlow::Value *indexValue: indexes) { for (const ValueFlow::Value *indexValue: indexes) {
if (!indexValue) if (!indexValue)
continue; continue;
if (!indexValue->errorSeverity() && !mSettings->isEnabled(Settings::WARNING)) if (!indexValue->errorSeverity() && !mSettings->severity.isEnabled(Severity::warning))
return; return;
if (indexValue->condition) if (indexValue->condition)
condition = indexValue->condition; condition = indexValue->condition;
@ -421,14 +421,14 @@ void CheckBufferOverrun::negativeIndexError(const Token *tok, const std::vector<
"negativeIndex", "negativeIndex",
arrayIndexMessage(tok, dimensions, indexes, condition), arrayIndexMessage(tok, dimensions, indexes, condition),
CWE_BUFFER_UNDERRUN, CWE_BUFFER_UNDERRUN,
negativeValue->isInconclusive()); negativeValue->isInconclusive() ? Certainty::inconclusive : Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckBufferOverrun::pointerArithmetic() void CheckBufferOverrun::pointerArithmetic()
{ {
if (!mSettings->isEnabled(Settings::PORTABILITY)) if (!mSettings->severity.isEnabled(Severity::portability))
return; return;
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
@ -480,8 +480,8 @@ void CheckBufferOverrun::pointerArithmetic()
void CheckBufferOverrun::pointerArithmeticError(const Token *tok, const Token *indexToken, const ValueFlow::Value *indexValue) void CheckBufferOverrun::pointerArithmeticError(const Token *tok, const Token *indexToken, const ValueFlow::Value *indexValue)
{ {
if (!tok) { if (!tok) {
reportError(tok, Severity::portability, "pointerOutOfBounds", "Pointer arithmetic overflow.", CWE_POINTER_ARITHMETIC_OVERFLOW, false); reportError(tok, Severity::portability, "pointerOutOfBounds", "Pointer arithmetic overflow.", CWE_POINTER_ARITHMETIC_OVERFLOW, Certainty::normal);
reportError(tok, Severity::portability, "pointerOutOfBoundsCond", "Pointer arithmetic overflow.", CWE_POINTER_ARITHMETIC_OVERFLOW, false); reportError(tok, Severity::portability, "pointerOutOfBoundsCond", "Pointer arithmetic overflow.", CWE_POINTER_ARITHMETIC_OVERFLOW, Certainty::normal);
return; return;
} }
@ -496,7 +496,7 @@ void CheckBufferOverrun::pointerArithmeticError(const Token *tok, const Token *i
indexValue->condition ? "pointerOutOfBoundsCond" : "pointerOutOfBounds", indexValue->condition ? "pointerOutOfBoundsCond" : "pointerOutOfBounds",
errmsg, errmsg,
CWE_POINTER_ARITHMETIC_OVERFLOW, CWE_POINTER_ARITHMETIC_OVERFLOW,
indexValue->isInconclusive()); indexValue->isInconclusive() ? Certainty::inconclusive : Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -614,14 +614,14 @@ void CheckBufferOverrun::bufferOverflow()
void CheckBufferOverrun::bufferOverflowError(const Token *tok, const ValueFlow::Value *value) void CheckBufferOverrun::bufferOverflowError(const Token *tok, const ValueFlow::Value *value)
{ {
reportError(getErrorPath(tok, value, "Buffer overrun"), Severity::error, "bufferAccessOutOfBounds", "Buffer is accessed out of bounds: " + (tok ? tok->expressionString() : "buf"), CWE_BUFFER_OVERRUN, false); reportError(getErrorPath(tok, value, "Buffer overrun"), Severity::error, "bufferAccessOutOfBounds", "Buffer is accessed out of bounds: " + (tok ? tok->expressionString() : "buf"), CWE_BUFFER_OVERRUN, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckBufferOverrun::arrayIndexThenCheck() void CheckBufferOverrun::arrayIndexThenCheck()
{ {
if (!mSettings->isEnabled(Settings::PORTABILITY)) if (!mSettings->severity.isEnabled(Severity::portability))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -669,7 +669,7 @@ void CheckBufferOverrun::arrayIndexThenCheckError(const Token *tok, const std::s
"Defensive programming: The variable '$symbol' is used as an array index before it " "Defensive programming: The variable '$symbol' is used as an array index before it "
"is checked that is within limits. This can mean that the array might be accessed out of bounds. " "is checked that is within limits. This can mean that the array might be accessed out of bounds. "
"Reorder conditions such as '(a[i] && i < 10)' to '(i < 10 && a[i])'. That way the array will " "Reorder conditions such as '(a[i] && i < 10)' to '(i < 10 && a[i])'. That way the array will "
"not be accessed if the index is out of limits.", CWE_ARRAY_INDEX_THEN_CHECK, false); "not be accessed if the index is out of limits.", CWE_ARRAY_INDEX_THEN_CHECK, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -677,7 +677,7 @@ void CheckBufferOverrun::arrayIndexThenCheckError(const Token *tok, const std::s
void CheckBufferOverrun::stringNotZeroTerminated() void CheckBufferOverrun::stringNotZeroTerminated()
{ {
// this is currently 'inconclusive'. See TestBufferOverrun::terminateStrncpy3 // this is currently 'inconclusive'. See TestBufferOverrun::terminateStrncpy3
if (!mSettings->isEnabled(Settings::WARNING) || !mSettings->inconclusive) if (!mSettings->severity.isEnabled(Severity::warning) || !mSettings->certainty.isEnabled(Certainty::inconclusive))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope * const scope : symbolDatabase->functionScopes) { for (const Scope * const scope : symbolDatabase->functionScopes) {
@ -724,7 +724,7 @@ void CheckBufferOverrun::terminateStrncpyError(const Token *tok, const std::stri
shortMessage + ' ' + shortMessage + ' ' +
"If the source string's size fits or exceeds the given size, strncpy() does not add a " "If the source string's size fits or exceeds the given size, strncpy() does not add a "
"zero at the end of the buffer. This causes bugs later in the code if the code " "zero at the end of the buffer. This causes bugs later in the code if the code "
"assumes buffer is null-terminated.", CWE170, true); "assumes buffer is null-terminated.", CWE170, Certainty::inconclusive);
} }
@ -870,7 +870,7 @@ bool CheckBufferOverrun::analyseWholeProgram1(const std::map<std::string, std::l
Severity::error, Severity::error,
errmsg, errmsg,
errorId, errorId,
cwe, false); cwe, Certainty::normal);
errorLogger.reportErr(errorMessage); errorLogger.reportErr(errorMessage);
return true; return true;
@ -955,5 +955,5 @@ void CheckBufferOverrun::objectIndexError(const Token *tok, const ValueFlow::Val
"objectIndex", "objectIndex",
"The address of local variable '" + name + "' " + verb + " accessed at non-zero index.", "The address of local variable '" + name + "' " + verb + " accessed at non-zero index.",
CWE758, CWE758,
false); Certainty::normal);
} }

View File

@ -94,12 +94,12 @@ CheckClass::CheckClass(const Tokenizer *tokenizer, const Settings *settings, Err
void CheckClass::constructors() void CheckClass::constructors()
{ {
const bool printStyle = mSettings->isEnabled(Settings::STYLE); const bool printStyle = mSettings->severity.isEnabled(Severity::style);
const bool printWarnings = mSettings->isEnabled(Settings::WARNING); const bool printWarnings = mSettings->severity.isEnabled(Severity::warning);
if (!printStyle && !printWarnings) if (!printStyle && !printWarnings)
return; return;
const bool printInconclusive = mSettings->inconclusive; const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive);
for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { for (const Scope * scope : mSymbolDatabase->classAndStructScopes) {
const bool unusedTemplate = Token::simpleMatch(scope->classDef->previous(), ">"); const bool unusedTemplate = Token::simpleMatch(scope->classDef->previous(), ">");
@ -255,7 +255,7 @@ void CheckClass::constructors()
void CheckClass::checkExplicitConstructors() void CheckClass::checkExplicitConstructors()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { for (const Scope * scope : mSymbolDatabase->classAndStructScopes) {
@ -324,7 +324,7 @@ static bool isNonCopyable(const Scope *scope, bool *unknown)
void CheckClass::copyconstructors() void CheckClass::copyconstructors()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { for (const Scope * scope : mSymbolDatabase->classAndStructScopes) {
@ -454,7 +454,7 @@ void CheckClass::copyConstructorMallocError(const Token *cctor, const Token *all
void CheckClass::copyConstructorShallowCopyError(const Token *tok, const std::string& varname) void CheckClass::copyConstructorShallowCopyError(const Token *tok, const std::string& varname)
{ {
reportError(tok, Severity::warning, "copyCtorPointerCopying", reportError(tok, Severity::warning, "copyCtorPointerCopying",
"$symbol:" + varname + "\nValue of pointer '$symbol', which points to allocated memory, is copied in copy constructor instead of allocating new memory.", CWE398, false); "$symbol:" + varname + "\nValue of pointer '$symbol', which points to allocated memory, is copied in copy constructor instead of allocating new memory.", CWE398, Certainty::normal);
} }
static std::string noMemberErrorMessage(const Scope *scope, const char function[], bool isdefault) static std::string noMemberErrorMessage(const Scope *scope, const char function[], bool isdefault)
@ -479,17 +479,17 @@ static std::string noMemberErrorMessage(const Scope *scope, const char function[
void CheckClass::noCopyConstructorError(const Scope *scope, bool isdefault, const Token *alloc, bool inconclusive) void CheckClass::noCopyConstructorError(const Scope *scope, bool isdefault, const Token *alloc, bool inconclusive)
{ {
reportError(alloc, Severity::warning, "noCopyConstructor", noMemberErrorMessage(scope, "copy constructor", isdefault), CWE398, inconclusive); reportError(alloc, Severity::warning, "noCopyConstructor", noMemberErrorMessage(scope, "copy constructor", isdefault), CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckClass::noOperatorEqError(const Scope *scope, bool isdefault, const Token *alloc, bool inconclusive) void CheckClass::noOperatorEqError(const Scope *scope, bool isdefault, const Token *alloc, bool inconclusive)
{ {
reportError(alloc, Severity::warning, "noOperatorEq", noMemberErrorMessage(scope, "operator=", isdefault), CWE398, inconclusive); reportError(alloc, Severity::warning, "noOperatorEq", noMemberErrorMessage(scope, "operator=", isdefault), CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckClass::noDestructorError(const Scope *scope, bool isdefault, const Token *alloc) void CheckClass::noDestructorError(const Scope *scope, bool isdefault, const Token *alloc)
{ {
reportError(alloc, Severity::warning, "noDestructor", noMemberErrorMessage(scope, "destructor", isdefault), CWE398, false); reportError(alloc, Severity::warning, "noDestructor", noMemberErrorMessage(scope, "destructor", isdefault), CWE398, Certainty::normal);
} }
bool CheckClass::canNotCopy(const Scope *scope) bool CheckClass::canNotCopy(const Scope *scope)
@ -936,14 +936,14 @@ void CheckClass::noConstructorError(const Token *tok, const std::string &classna
"The " + std::string(isStruct ? "struct" : "class") + " '$symbol' does not have a constructor although it has private member variables.\n" "The " + std::string(isStruct ? "struct" : "class") + " '$symbol' does not have a constructor although it has private member variables.\n"
"The " + std::string(isStruct ? "struct" : "class") + " '$symbol' does not have a constructor " "The " + std::string(isStruct ? "struct" : "class") + " '$symbol' does not have a constructor "
"although it has private member variables. Member variables of builtin types are left " "although it has private member variables. Member variables of builtin types are left "
"uninitialized when the class is instantiated. That may cause bugs or undefined behavior.", CWE398, false); "uninitialized when the class is instantiated. That may cause bugs or undefined behavior.", CWE398, Certainty::normal);
} }
void CheckClass::noExplicitConstructorError(const Token *tok, const std::string &classname, bool isStruct) void CheckClass::noExplicitConstructorError(const Token *tok, const std::string &classname, bool isStruct)
{ {
const std::string message(std::string(isStruct ? "Struct" : "Class") + " '$symbol' has a constructor with 1 argument that is not explicit."); const std::string message(std::string(isStruct ? "Struct" : "Class") + " '$symbol' has a constructor with 1 argument that is not explicit.");
const std::string verbose(message + " Such constructors should in general be explicit for type safety reasons. Using the explicit keyword in the constructor means some mistakes when using the class can be avoided."); const std::string verbose(message + " Such constructors should in general be explicit for type safety reasons. Using the explicit keyword in the constructor means some mistakes when using the class can be avoided.");
reportError(tok, Severity::style, "noExplicitConstructor", "$symbol:" + classname + '\n' + message + '\n' + verbose, CWE398, false); reportError(tok, Severity::style, "noExplicitConstructor", "$symbol:" + classname + '\n' + message + '\n' + verbose, CWE398, Certainty::normal);
} }
void CheckClass::uninitVarError(const Token *tok, bool isprivate, Function::Type functionType, const std::string &classname, const std::string &varname, bool derived, bool inconclusive) void CheckClass::uninitVarError(const Token *tok, bool isprivate, Function::Type functionType, const std::string &classname, const std::string &varname, bool derived, bool inconclusive)
@ -956,12 +956,12 @@ void CheckClass::uninitVarError(const Token *tok, bool isprivate, Function::Type
if (derived) if (derived)
message += " Maybe it should be initialized directly in the class " + classname + "?"; message += " Maybe it should be initialized directly in the class " + classname + "?";
std::string id = std::string("uninit") + (derived ? "Derived" : "") + "MemberVar" + (isprivate ? "Private" : ""); std::string id = std::string("uninit") + (derived ? "Derived" : "") + "MemberVar" + (isprivate ? "Private" : "");
reportError(tok, Severity::warning, id, "$symbol:" + classname + "::" + varname + "\n" + message, CWE398, inconclusive); reportError(tok, Severity::warning, id, "$symbol:" + classname + "::" + varname + "\n" + message, CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckClass::operatorEqVarError(const Token *tok, const std::string &classname, const std::string &varname, bool inconclusive) void CheckClass::operatorEqVarError(const Token *tok, const std::string &classname, const std::string &varname, bool inconclusive)
{ {
reportError(tok, Severity::warning, "operatorEqVarError", "$symbol:" + classname + "::" + varname + "\nMember variable '$symbol' is not assigned a value in '" + classname + "::operator='.", CWE398, inconclusive); reportError(tok, Severity::warning, "operatorEqVarError", "$symbol:" + classname + "::" + varname + "\nMember variable '$symbol' is not assigned a value in '" + classname + "::operator='.", CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -970,7 +970,7 @@ void CheckClass::operatorEqVarError(const Token *tok, const std::string &classna
void CheckClass::initializationListUsage() void CheckClass::initializationListUsage()
{ {
if (!mSettings->isEnabled(Settings::PERFORMANCE)) if (!mSettings->severity.isEnabled(Severity::performance))
return; return;
for (const Scope *scope : mSymbolDatabase->functionScopes) { for (const Scope *scope : mSymbolDatabase->functionScopes) {
@ -1050,7 +1050,7 @@ void CheckClass::suggestInitializationList(const Token* tok, const std::string&
reportError(tok, Severity::performance, "useInitializationList", "$symbol:" + varname + "\nVariable '$symbol' is assigned in constructor body. Consider performing initialization in initialization list.\n" reportError(tok, Severity::performance, "useInitializationList", "$symbol:" + varname + "\nVariable '$symbol' is assigned in constructor body. Consider performing initialization in initialization list.\n"
"When an object of a class is created, the constructors of all member variables are called consecutively " "When an object of a class is created, the constructors of all member variables are called consecutively "
"in the order the variables are declared, even if you don't explicitly write them to the initialization list. You " "in the order the variables are declared, even if you don't explicitly write them to the initialization list. You "
"could avoid assigning '$symbol' a value by passing the value to the constructor in the initialization list.", CWE398, false); "could avoid assigning '$symbol' a value by passing the value to the constructor in the initialization list.", CWE398, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1109,7 +1109,7 @@ static bool checkFunctionUsage(const Function *privfunc, const Scope* scope)
void CheckClass::privateFunctions() void CheckClass::privateFunctions()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { for (const Scope * scope : mSymbolDatabase->classAndStructScopes) {
@ -1158,7 +1158,7 @@ void CheckClass::privateFunctions()
void CheckClass::unusedPrivateFunctionError(const Token *tok, const std::string &classname, const std::string &funcname) void CheckClass::unusedPrivateFunctionError(const Token *tok, const std::string &classname, const std::string &funcname)
{ {
reportError(tok, Severity::style, "unusedPrivateFunction", "$symbol:" + classname + "::" + funcname + "\nUnused private function: '$symbol'", CWE398, false); reportError(tok, Severity::style, "unusedPrivateFunction", "$symbol:" + classname + "::" + funcname + "\nUnused private function: '$symbol'", CWE398, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1177,7 +1177,7 @@ static const Scope* findFunctionOf(const Scope* scope)
void CheckClass::checkMemset() void CheckClass::checkMemset()
{ {
const bool printWarnings = mSettings->isEnabled(Settings::WARNING); const bool printWarnings = mSettings->severity.isEnabled(Severity::warning);
for (const Scope *scope : mSymbolDatabase->functionScopes) { for (const Scope *scope : mSymbolDatabase->functionScopes) {
for (const Token *tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) { for (const Token *tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) {
if (Token::Match(tok, "memset|memcpy|memmove (")) { if (Token::Match(tok, "memset|memcpy|memmove (")) {
@ -1261,7 +1261,7 @@ void CheckClass::checkMemsetType(const Scope *start, const Token *tok, const Sco
return; return;
parsedTypes.insert(type); parsedTypes.insert(type);
const bool printPortability = mSettings->isEnabled(Settings::PORTABILITY); const bool printPortability = mSettings->severity.isEnabled(Severity::portability);
// recursively check all parent classes // recursively check all parent classes
for (const Type::BaseInfo & i : type->definedType->derivedFrom) { for (const Type::BaseInfo & i : type->definedType->derivedFrom) {
@ -1327,7 +1327,7 @@ void CheckClass::mallocOnClassWarning(const Token* tok, const std::string &memfu
"$symbol:" + memfunc +"\n" "$symbol:" + memfunc +"\n"
"Memory for class instance allocated with $symbol(), but class provides constructors.\n" "Memory for class instance allocated with $symbol(), but class provides constructors.\n"
"Memory for class instance allocated with $symbol(), but class provides constructors. This is unsafe, " "Memory for class instance allocated with $symbol(), but class provides constructors. This is unsafe, "
"since no constructor is called and class members remain uninitialized. Consider using 'new' instead.", CWE762, false); "since no constructor is called and class members remain uninitialized. Consider using 'new' instead.", CWE762, Certainty::normal);
} }
void CheckClass::mallocOnClassError(const Token* tok, const std::string &memfunc, const Token* classTok, const std::string &classname) void CheckClass::mallocOnClassError(const Token* tok, const std::string &memfunc, const Token* classTok, const std::string &classname)
@ -1338,7 +1338,7 @@ void CheckClass::mallocOnClassError(const Token* tok, const std::string &memfunc
"$symbol:" + classname +"\n" "$symbol:" + classname +"\n"
"Memory for class instance allocated with " + memfunc + "(), but class contains a " + classname + ".\n" "Memory for class instance allocated with " + memfunc + "(), but class contains a " + classname + ".\n"
"Memory for class instance allocated with " + memfunc + "(), but class a " + classname + ". This is unsafe, " "Memory for class instance allocated with " + memfunc + "(), but class a " + classname + ". This is unsafe, "
"since no constructor is called and class members remain uninitialized. Consider using 'new' instead.", CWE665, false); "since no constructor is called and class members remain uninitialized. Consider using 'new' instead.", CWE665, Certainty::normal);
} }
void CheckClass::memsetError(const Token *tok, const std::string &memfunc, const std::string &classname, const std::string &type) void CheckClass::memsetError(const Token *tok, const std::string &memfunc, const std::string &classname, const std::string &type)
@ -1349,14 +1349,14 @@ void CheckClass::memsetError(const Token *tok, const std::string &memfunc, const
"Using '" + memfunc + "' on " + type + " that contains a " + classname + ".\n" "Using '" + memfunc + "' on " + type + " that contains a " + classname + ".\n"
"Using '" + memfunc + "' on " + type + " that contains a " + classname + " is unsafe, because constructor, destructor " "Using '" + memfunc + "' on " + type + " that contains a " + classname + " is unsafe, because constructor, destructor "
"and copy operator calls are omitted. These are necessary for this non-POD type to ensure that a valid object " "and copy operator calls are omitted. These are necessary for this non-POD type to ensure that a valid object "
"is created.", CWE762, false); "is created.", CWE762, Certainty::normal);
} }
void CheckClass::memsetErrorReference(const Token *tok, const std::string &memfunc, const std::string &type) void CheckClass::memsetErrorReference(const Token *tok, const std::string &memfunc, const std::string &type)
{ {
reportError(tok, Severity::error, "memsetClassReference", reportError(tok, Severity::error, "memsetClassReference",
"$symbol:" + memfunc +"\n" "$symbol:" + memfunc +"\n"
"Using '" + memfunc + "' on " + type + " that contains a reference.", CWE665, false); "Using '" + memfunc + "' on " + type + " that contains a reference.", CWE665, Certainty::normal);
} }
void CheckClass::memsetErrorFloat(const Token *tok, const std::string &type) void CheckClass::memsetErrorFloat(const Token *tok, const std::string &type)
@ -1365,7 +1365,7 @@ void CheckClass::memsetErrorFloat(const Token *tok, const std::string &type)
"Using memset() on " + type + " which contains a floating point number." "Using memset() on " + type + " which contains a floating point number."
" This is not portable because memset() sets each byte of a block of memory to a specific value and" " This is not portable because memset() sets each byte of a block of memory to a specific value and"
" the actual representation of a floating-point value is implementation defined." " the actual representation of a floating-point value is implementation defined."
" Note: In case of an IEEE754-1985 compatible implementation setting all bits to zero results in the value 0.0.", CWE758, false); " Note: In case of an IEEE754-1985 compatible implementation setting all bits to zero results in the value 0.0.", CWE758, Certainty::normal);
} }
@ -1376,7 +1376,7 @@ void CheckClass::memsetErrorFloat(const Token *tok, const std::string &type)
void CheckClass::operatorEqRetRefThis() void CheckClass::operatorEqRetRefThis()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { for (const Scope * scope : mSymbolDatabase->classAndStructScopes) {
@ -1481,18 +1481,18 @@ void CheckClass::checkReturnPtrThis(const Scope *scope, const Function *func, co
void CheckClass::operatorEqRetRefThisError(const Token *tok) void CheckClass::operatorEqRetRefThisError(const Token *tok)
{ {
reportError(tok, Severity::style, "operatorEqRetRefThis", "'operator=' should return reference to 'this' instance.", CWE398, false); reportError(tok, Severity::style, "operatorEqRetRefThis", "'operator=' should return reference to 'this' instance.", CWE398, Certainty::normal);
} }
void CheckClass::operatorEqShouldBeLeftUnimplementedError(const Token *tok) void CheckClass::operatorEqShouldBeLeftUnimplementedError(const Token *tok)
{ {
reportError(tok, Severity::style, "operatorEqShouldBeLeftUnimplemented", "'operator=' should either return reference to 'this' instance or be declared private and left unimplemented.", CWE398, false); reportError(tok, Severity::style, "operatorEqShouldBeLeftUnimplemented", "'operator=' should either return reference to 'this' instance or be declared private and left unimplemented.", CWE398, Certainty::normal);
} }
void CheckClass::operatorEqMissingReturnStatementError(const Token *tok, bool error) void CheckClass::operatorEqMissingReturnStatementError(const Token *tok, bool error)
{ {
if (error) { if (error) {
reportError(tok, Severity::error, "operatorEqMissingReturnStatement", "No 'return' statement in non-void function causes undefined behavior.", CWE398, false); reportError(tok, Severity::error, "operatorEqMissingReturnStatement", "No 'return' statement in non-void function causes undefined behavior.", CWE398, Certainty::normal);
} else { } else {
operatorEqRetRefThisError(tok); operatorEqRetRefThisError(tok);
} }
@ -1514,7 +1514,7 @@ void CheckClass::operatorEqMissingReturnStatementError(const Token *tok, bool er
void CheckClass::operatorEqToSelf() void CheckClass::operatorEqToSelf()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { for (const Scope * scope : mSymbolDatabase->classAndStructScopes) {
@ -1694,7 +1694,7 @@ void CheckClass::operatorEqToSelfError(const Token *tok)
reportError(tok, Severity::warning, "operatorEqToSelf", reportError(tok, Severity::warning, "operatorEqToSelf",
"'operator=' should check for assignment to self to avoid problems with dynamic memory.\n" "'operator=' should check for assignment to self to avoid problems with dynamic memory.\n"
"'operator=' should check for assignment to self to ensure that each block of dynamically " "'operator=' should check for assignment to self to ensure that each block of dynamically "
"allocated memory is owned and managed by only one instance of the class.", CWE398, false); "allocated memory is owned and managed by only one instance of the class.", CWE398, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1709,7 +1709,7 @@ void CheckClass::virtualDestructor()
// * base class is deleted // * base class is deleted
// unless inconclusive in which case: // unless inconclusive in which case:
// * A class with any virtual functions should have a destructor that is either public and virtual or protected // * A class with any virtual functions should have a destructor that is either public and virtual or protected
const bool printInconclusive = mSettings->inconclusive; const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive);
std::list<const Function *> inconclusiveErrors; std::list<const Function *> inconclusiveErrors;
@ -1839,8 +1839,8 @@ void CheckClass::virtualDestructor()
void CheckClass::virtualDestructorError(const Token *tok, const std::string &Base, const std::string &Derived, bool inconclusive) void CheckClass::virtualDestructorError(const Token *tok, const std::string &Base, const std::string &Derived, bool inconclusive)
{ {
if (inconclusive) { if (inconclusive) {
if (mSettings->isEnabled(Settings::WARNING)) if (mSettings->severity.isEnabled(Severity::warning))
reportError(tok, Severity::warning, "virtualDestructor", "$symbol:" + Base + "\nClass '$symbol' which has virtual members does not have a virtual destructor.", CWE404, true); reportError(tok, Severity::warning, "virtualDestructor", "$symbol:" + Base + "\nClass '$symbol' which has virtual members does not have a virtual destructor.", CWE404, Certainty::inconclusive);
} else { } else {
reportError(tok, Severity::error, "virtualDestructor", reportError(tok, Severity::error, "virtualDestructor",
"$symbol:" + Base +"\n" "$symbol:" + Base +"\n"
@ -1849,7 +1849,7 @@ void CheckClass::virtualDestructorError(const Token *tok, const std::string &Bas
"Class '" + Base + "' which is inherited by class '" + Derived + "' does not have a virtual destructor. " "Class '" + Base + "' which is inherited by class '" + Derived + "' does not have a virtual destructor. "
"If you destroy instances of the derived class by deleting a pointer that points to the base class, only " "If you destroy instances of the derived class by deleting a pointer that points to the base class, only "
"the destructor of the base class is executed. Thus, dynamic memory that is managed by the derived class " "the destructor of the base class is executed. Thus, dynamic memory that is managed by the derived class "
"could leak. This can be avoided by adding a virtual destructor to the base class.", CWE404, false); "could leak. This can be avoided by adding a virtual destructor to the base class.", CWE404, Certainty::normal);
} }
} }
@ -1859,7 +1859,7 @@ void CheckClass::virtualDestructorError(const Token *tok, const std::string &Bas
void CheckClass::thisSubtraction() void CheckClass::thisSubtraction()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const Token *tok = mTokenizer->tokens(); const Token *tok = mTokenizer->tokens();
@ -1877,7 +1877,7 @@ void CheckClass::thisSubtraction()
void CheckClass::thisSubtractionError(const Token *tok) void CheckClass::thisSubtractionError(const Token *tok)
{ {
reportError(tok, Severity::warning, "thisSubtraction", "Suspicious pointer subtraction. Did you intend to write '->'?", CWE398, false); reportError(tok, Severity::warning, "thisSubtraction", "Suspicious pointer subtraction. Did you intend to write '->'?", CWE398, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1887,10 +1887,10 @@ void CheckClass::thisSubtractionError(const Token *tok)
void CheckClass::checkConst() void CheckClass::checkConst()
{ {
// This is an inconclusive check. False positives: #3322. // This is an inconclusive check. False positives: #3322.
if (!mSettings->inconclusive) if (!mSettings->certainty.isEnabled(Certainty::inconclusive))
return; return;
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { for (const Scope * scope : mSymbolDatabase->classAndStructScopes) {
@ -2250,7 +2250,7 @@ void CheckClass::checkConstError2(const Token *tok1, const Token *tok2, const st
"function. Making this function 'const' should not cause compiler errors. " "function. Making this function 'const' should not cause compiler errors. "
"Even though the function can be made const function technically it may not make " "Even though the function can be made const function technically it may not make "
"sense conceptually. Think about your design and the task of the function first - is " "sense conceptually. Think about your design and the task of the function first - is "
"it a function that must not change object internal state?", CWE398, true); "it a function that must not change object internal state?", CWE398, Certainty::inconclusive);
else else
reportError(toks, Severity::performance, "functionStatic", reportError(toks, Severity::performance, "functionStatic",
"$symbol:" + classname + "::" + funcname +"\n" "$symbol:" + classname + "::" + funcname +"\n"
@ -2260,7 +2260,7 @@ void CheckClass::checkConstError2(const Token *tok1, const Token *tok2, const st
"passed to the function. This change should not cause compiler errors but it does not " "passed to the function. This change should not cause compiler errors but it does not "
"necessarily make sense conceptually. Think about your design and the task of the function first - " "necessarily make sense conceptually. Think about your design and the task of the function first - "
"is it a function that must not access members of class instances? And maybe it is more appropriate " "is it a function that must not access members of class instances? And maybe it is more appropriate "
"to move this function to a unnamed namespace.", CWE398, true); "to move this function to a unnamed namespace.", CWE398, Certainty::inconclusive);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -2279,14 +2279,14 @@ namespace { // avoid one-definition-rule violation
void CheckClass::initializerListOrder() void CheckClass::initializerListOrder()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
// This check is not inconclusive. However it only determines if the initialization // This check is not inconclusive. However it only determines if the initialization
// order is incorrect. It does not determine if being out of order causes // order is incorrect. It does not determine if being out of order causes
// a real error. Out of order is not necessarily an error but you can never // a real error. Out of order is not necessarily an error but you can never
// have an error if the list is in order so this enforces defensive programming. // have an error if the list is in order so this enforces defensive programming.
if (!mSettings->inconclusive) if (!mSettings->certainty.isEnabled(Certainty::inconclusive))
return; return;
for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { for (const Scope * scope : mSymbolDatabase->classAndStructScopes) {
@ -2341,7 +2341,7 @@ void CheckClass::initializerListError(const Token *tok1, const Token *tok2, cons
"Members are initialized in the order they are declared, not in the " "Members are initialized in the order they are declared, not in the "
"order they are in the initializer list. Keeping the initializer list " "order they are in the initializer list. Keeping the initializer list "
"in the same order that the members were declared prevents order dependent " "in the same order that the members were declared prevents order dependent "
"initialization errors.", CWE398, true); "initialization errors.", CWE398, Certainty::inconclusive);
} }
@ -2370,7 +2370,7 @@ void CheckClass::checkSelfInitialization()
void CheckClass::selfInitializationError(const Token* tok, const std::string& varname) void CheckClass::selfInitializationError(const Token* tok, const std::string& varname)
{ {
reportError(tok, Severity::error, "selfInitialization", "$symbol:" + varname + "\nMember variable '$symbol' is initialized by itself.", CWE665, false); reportError(tok, Severity::error, "selfInitialization", "$symbol:" + varname + "\nMember variable '$symbol' is initialized by itself.", CWE665, Certainty::normal);
} }
@ -2380,7 +2380,7 @@ void CheckClass::selfInitializationError(const Token* tok, const std::string& va
void CheckClass::checkVirtualFunctionCallInConstructor() void CheckClass::checkVirtualFunctionCallInConstructor()
{ {
if (! mSettings->isEnabled(Settings::WARNING)) if (! mSettings->severity.isEnabled(Severity::warning))
return; return;
std::map<const Function *, std::list<const Token *> > virtualFunctionCallsMap; std::map<const Function *, std::list<const Token *> > virtualFunctionCallsMap;
for (const Scope *scope : mSymbolDatabase->functionScopes) { for (const Scope *scope : mSymbolDatabase->functionScopes) {
@ -2511,7 +2511,7 @@ void CheckClass::virtualFunctionCallInConstructorError(
} }
reportError(errorPath, Severity::style, "virtualCallInConstructor", reportError(errorPath, Severity::style, "virtualCallInConstructor",
"Virtual function '" + funcname + "' is called from " + scopeFunctionTypeName + " '" + constructorName + "' at line " + MathLib::toString(lineNumber) + ". Dynamic binding is not used.", CWE(0U), false); "Virtual function '" + funcname + "' is called from " + scopeFunctionTypeName + " '" + constructorName + "' at line " + MathLib::toString(lineNumber) + ". Dynamic binding is not used.", CWE(0U), Certainty::normal);
} }
void CheckClass::pureVirtualFunctionCallInConstructorError( void CheckClass::pureVirtualFunctionCallInConstructorError(
@ -2530,7 +2530,7 @@ void CheckClass::pureVirtualFunctionCallInConstructorError(
reportError(errorPath, Severity::warning, "pureVirtualCall", reportError(errorPath, Severity::warning, "pureVirtualCall",
"$symbol:" + purefuncname +"\n" "$symbol:" + purefuncname +"\n"
"Call of pure virtual function '$symbol' in " + scopeFunctionTypeName + ".\n" "Call of pure virtual function '$symbol' in " + scopeFunctionTypeName + ".\n"
"Call of pure virtual function '$symbol' in " + scopeFunctionTypeName + ". The call will fail during runtime.", CWE(0U), false); "Call of pure virtual function '$symbol' in " + scopeFunctionTypeName + ". The call will fail during runtime.", CWE(0U), Certainty::normal);
} }
@ -2540,7 +2540,7 @@ void CheckClass::pureVirtualFunctionCallInConstructorError(
void CheckClass::checkDuplInheritedMembers() void CheckClass::checkDuplInheritedMembers()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
// Iterate over all classes // Iterate over all classes
@ -2588,7 +2588,7 @@ void CheckClass::duplInheritedMembersError(const Token *tok1, const Token* tok2,
const std::string message = "The " + std::string(derivedIsStruct ? "struct" : "class") + " '" + derivedName + const std::string message = "The " + std::string(derivedIsStruct ? "struct" : "class") + " '" + derivedName +
"' defines member variable with name '" + variableName + "' also defined in its parent " + "' defines member variable with name '" + variableName + "' also defined in its parent " +
std::string(baseIsStruct ? "struct" : "class") + " '" + baseName + "'."; std::string(baseIsStruct ? "struct" : "class") + " '" + baseName + "'.";
reportError(errorPath, Severity::warning, "duplInheritedMember", symbols + '\n' + message, CWE398, false); reportError(errorPath, Severity::warning, "duplInheritedMember", symbols + '\n' + message, CWE398, Certainty::normal);
} }
@ -2609,7 +2609,7 @@ void CheckClass::checkCopyCtorAndEqOperator()
return; return;
// cppcheck-suppress unreachableCode - remove when code is enabled again // cppcheck-suppress unreachableCode - remove when code is enabled again
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { for (const Scope * scope : mSymbolDatabase->classAndStructScopes) {
@ -2671,7 +2671,7 @@ void CheckClass::copyCtorAndEqOperatorError(const Token *tok, const std::string
void CheckClass::checkOverride() void CheckClass::checkOverride()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
if (mSettings->standards.cpp < Standards::CPP11) if (mSettings->standards.cpp < Standards::CPP11)
return; return;
@ -2703,12 +2703,12 @@ void CheckClass::overrideError(const Function *funcInBase, const Function *funcI
"$symbol:" + functionName + "\n" "$symbol:" + functionName + "\n"
"The " + funcType + " '$symbol' overrides a " + funcType + " in a base class but is not marked with a 'override' specifier.", "The " + funcType + " '$symbol' overrides a " + funcType + " in a base class but is not marked with a 'override' specifier.",
CWE(0U) /* Unknown CWE! */, CWE(0U) /* Unknown CWE! */,
false); Certainty::normal);
} }
void CheckClass::checkThisUseAfterFree() void CheckClass::checkThisUseAfterFree()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
for (const Scope * classScope : mSymbolDatabase->classAndStructScopes) { for (const Scope * classScope : mSymbolDatabase->classAndStructScopes) {
@ -2801,12 +2801,12 @@ void CheckClass::thisUseAfterFree(const Token *self, const Token *free, const To
reportError(errorPath, Severity::warning, "thisUseAfterFree", reportError(errorPath, Severity::warning, "thisUseAfterFree",
"$symbol:" + selfPointer + "\n" + "$symbol:" + selfPointer + "\n" +
usemsg + " when 'this' might be invalid", usemsg + " when 'this' might be invalid",
CWE(0), false); CWE(0), Certainty::normal);
} }
void CheckClass::checkUnsafeClassRefMember() void CheckClass::checkUnsafeClassRefMember()
{ {
if (!mSettings->safeChecks.classes || !mSettings->isEnabled(Settings::WARNING)) if (!mSettings->safeChecks.classes || !mSettings->severity.isEnabled(Severity::warning))
return; return;
for (const Scope * classScope : mSymbolDatabase->classAndStructScopes) { for (const Scope * classScope : mSymbolDatabase->classAndStructScopes) {
for (const Function &func : classScope->functionList) { for (const Function &func : classScope->functionList) {
@ -2833,7 +2833,7 @@ void CheckClass::unsafeClassRefMemberError(const Token *tok, const std::string &
"$symbol:" + varname + "\n" "$symbol:" + varname + "\n"
"Unsafe class: The const reference member '$symbol' is initialized by a const reference constructor argument. You need to be careful about lifetime issues.\n" "Unsafe class: The const reference member '$symbol' is initialized by a const reference constructor argument. You need to be careful about lifetime issues.\n"
"Unsafe class checking: The const reference member '$symbol' is initialized by a const reference constructor argument. You need to be careful about lifetime issues. If you pass a local variable or temporary value in this constructor argument, be extra careful. If the argument is always some global object that is never destroyed then this is safe usage. However it would be defensive to make the member '$symbol' a non-reference variable or a smart pointer.", "Unsafe class checking: The const reference member '$symbol' is initialized by a const reference constructor argument. You need to be careful about lifetime issues. If you pass a local variable or temporary value in this constructor argument, be extra careful. If the argument is always some global object that is never destroyed then this is safe usage. However it would be defensive to make the member '$symbol' a non-reference variable or a smart pointer.",
CWE(0), false); CWE(0), Certainty::normal);
} }
Check::FileInfo *CheckClass::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const Check::FileInfo *CheckClass::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const
@ -2969,7 +2969,7 @@ bool CheckClass::analyseWholeProgram(const CTU::FileInfo *ctu, const std::list<C
"\nThe one definition rule is violated, different classes/structs have the same name '$symbol'", "\nThe one definition rule is violated, different classes/structs have the same name '$symbol'",
"ctuOneDefinitionRuleViolation", "ctuOneDefinitionRuleViolation",
CWE_ONE_DEFINITION_RULE, CWE_ONE_DEFINITION_RULE,
false); Certainty::normal);
errorLogger.reportErr(errmsg); errorLogger.reportErr(errmsg);
foundErrors = true; foundErrors = true;

View File

@ -83,7 +83,7 @@ bool CheckCondition::isAliased(const std::set<int> &vars) const
void CheckCondition::assignIf() void CheckCondition::assignIf()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
@ -238,7 +238,7 @@ void CheckCondition::assignIfError(const Token *tok1, const Token *tok2, const s
reportError(locations, reportError(locations,
Severity::style, Severity::style,
"assignIfError", "assignIfError",
"Mismatching assignment and comparison, comparison '" + condition + "' is always " + std::string(result ? "true" : "false") + ".", CWE398, false); "Mismatching assignment and comparison, comparison '" + condition + "' is always " + std::string(result ? "true" : "false") + ".", CWE398, Certainty::normal);
} }
@ -253,7 +253,7 @@ void CheckCondition::mismatchingBitAndError(const Token *tok1, const MathLib::bi
reportError(locations, reportError(locations,
Severity::style, Severity::style,
"mismatchingBitAnd", "mismatchingBitAnd",
msg.str(), CWE398, false); msg.str(), CWE398, Certainty::normal);
} }
@ -289,7 +289,7 @@ static bool inBooleanFunction(const Token *tok)
void CheckCondition::checkBadBitmaskCheck() void CheckCondition::checkBadBitmaskCheck()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
@ -312,12 +312,12 @@ void CheckCondition::checkBadBitmaskCheck()
void CheckCondition::badBitmaskCheckError(const Token *tok) void CheckCondition::badBitmaskCheckError(const Token *tok)
{ {
reportError(tok, Severity::warning, "badBitmaskCheck", "Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?", CWE571, false); reportError(tok, Severity::warning, "badBitmaskCheck", "Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?", CWE571, Certainty::normal);
} }
void CheckCondition::comparison() void CheckCondition::comparison()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
@ -387,7 +387,7 @@ void CheckCondition::comparisonError(const Token *tok, const std::string &bitop,
"spot sometimes. In case of complex expression it might help to split it to " "spot sometimes. In case of complex expression it might help to split it to "
"separate expressions."); "separate expressions.");
reportError(tok, Severity::style, "comparisonError", errmsg, CWE398, false); reportError(tok, Severity::style, "comparisonError", errmsg, CWE398, Certainty::normal);
} }
bool CheckCondition::isOverlappingCond(const Token * const cond1, const Token * const cond2, bool pure) const bool CheckCondition::isOverlappingCond(const Token * const cond1, const Token * const cond2, bool pure) const
@ -433,7 +433,7 @@ bool CheckCondition::isOverlappingCond(const Token * const cond1, const Token *
void CheckCondition::duplicateCondition() void CheckCondition::duplicateCondition()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase *const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *const symbolDatabase = mTokenizer->getSymbolDatabase();
@ -477,12 +477,12 @@ void CheckCondition::duplicateConditionError(const Token *tok1, const Token *tok
std::string msg = "The if condition is the same as the previous if condition"; std::string msg = "The if condition is the same as the previous if condition";
reportError(errorPath, Severity::style, "duplicateCondition", msg, CWE398, false); reportError(errorPath, Severity::style, "duplicateCondition", msg, CWE398, Certainty::normal);
} }
void CheckCondition::multiCondition() void CheckCondition::multiCondition()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase();
@ -526,7 +526,7 @@ void CheckCondition::overlappingElseIfConditionError(const Token *tok, nonneg in
errmsg << "Expression is always false because 'else if' condition matches previous condition at line " errmsg << "Expression is always false because 'else if' condition matches previous condition at line "
<< line1 << "."; << line1 << ".";
reportError(tok, Severity::style, "multiCondition", errmsg.str(), CWE398, false); reportError(tok, Severity::style, "multiCondition", errmsg.str(), CWE398, Certainty::normal);
} }
void CheckCondition::oppositeElseIfConditionError(const Token *ifCond, const Token *elseIfCond, ErrorPath errorPath) void CheckCondition::oppositeElseIfConditionError(const Token *ifCond, const Token *elseIfCond, ErrorPath errorPath)
@ -540,7 +540,7 @@ void CheckCondition::oppositeElseIfConditionError(const Token *ifCond, const Tok
errorPath.emplace_back(ifCond, "first condition"); errorPath.emplace_back(ifCond, "first condition");
errorPath.emplace_back(elseIfCond, "else if condition is opposite to first condition"); errorPath.emplace_back(elseIfCond, "else if condition is opposite to first condition");
reportError(errorPath, Severity::style, "multiCondition", errmsg.str(), CWE398, false); reportError(errorPath, Severity::style, "multiCondition", errmsg.str(), CWE398, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -567,7 +567,7 @@ static bool isNonConstFunctionCall(const Token *ftok, const Library &library)
void CheckCondition::multiCondition2() void CheckCondition::multiCondition2()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -818,7 +818,7 @@ void CheckCondition::oppositeInnerConditionError(const Token *tok1, const Token*
const std::string msg("Opposite inner '" + innerSmt + "' condition leads to a dead code block.\n" const std::string msg("Opposite inner '" + innerSmt + "' condition leads to a dead code block.\n"
"Opposite inner '" + innerSmt + "' condition leads to a dead code block (outer condition is '" + s1 + "' and inner condition is '" + s2 + "')."); "Opposite inner '" + innerSmt + "' condition leads to a dead code block (outer condition is '" + s1 + "' and inner condition is '" + s2 + "').");
reportError(errorPath, Severity::warning, "oppositeInnerCondition", msg, CWE398, false); reportError(errorPath, Severity::warning, "oppositeInnerCondition", msg, CWE398, Certainty::normal);
} }
void CheckCondition::identicalInnerConditionError(const Token *tok1, const Token* tok2, ErrorPath errorPath) void CheckCondition::identicalInnerConditionError(const Token *tok1, const Token* tok2, ErrorPath errorPath)
@ -833,7 +833,7 @@ void CheckCondition::identicalInnerConditionError(const Token *tok1, const Token
const std::string msg("Identical inner '" + innerSmt + "' condition is always true.\n" const std::string msg("Identical inner '" + innerSmt + "' condition is always true.\n"
"Identical inner '" + innerSmt + "' condition is always true (outer condition is '" + s1 + "' and inner condition is '" + s2 + "')."); "Identical inner '" + innerSmt + "' condition is always true (outer condition is '" + s1 + "' and inner condition is '" + s2 + "').");
reportError(errorPath, Severity::warning, "identicalInnerCondition", msg, CWE398, false); reportError(errorPath, Severity::warning, "identicalInnerCondition", msg, CWE398, Certainty::normal);
} }
void CheckCondition::identicalConditionAfterEarlyExitError(const Token *cond1, const Token* cond2, ErrorPath errorPath) void CheckCondition::identicalConditionAfterEarlyExitError(const Token *cond1, const Token* cond2, ErrorPath errorPath)
@ -856,7 +856,7 @@ void CheckCondition::identicalConditionAfterEarlyExitError(const Token *cond1, c
? ("Identical condition and return expression '" + cond + "', return value is always " + value) ? ("Identical condition and return expression '" + cond + "', return value is always " + value)
: ("Identical condition '" + cond + "', second condition is always false"), : ("Identical condition '" + cond + "', second condition is always false"),
CWE398, CWE398,
false); Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1034,11 +1034,11 @@ static std::string conditionString(const Token * tok)
void CheckCondition::checkIncorrectLogicOperator() void CheckCondition::checkIncorrectLogicOperator()
{ {
const bool printStyle = mSettings->isEnabled(Settings::STYLE); const bool printStyle = mSettings->severity.isEnabled(Severity::style);
const bool printWarning = mSettings->isEnabled(Settings::WARNING); const bool printWarning = mSettings->severity.isEnabled(Severity::warning);
if (!printWarning && !printStyle) if (!printWarning && !printStyle)
return; return;
const bool printInconclusive = mSettings->inconclusive; const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive);
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope * scope : symbolDatabase->functionScopes) { for (const Scope * scope : symbolDatabase->functionScopes) {
@ -1244,19 +1244,19 @@ void CheckCondition::incorrectLogicOperatorError(const Token *tok, const std::st
reportError(errors, Severity::warning, "incorrectLogicOperator", reportError(errors, Severity::warning, "incorrectLogicOperator",
"Logical disjunction always evaluates to true: " + condition + ".\n" "Logical disjunction always evaluates to true: " + condition + ".\n"
"Logical disjunction always evaluates to true: " + condition + ". " "Logical disjunction always evaluates to true: " + condition + ". "
"Are these conditions necessary? Did you intend to use && instead? Are the numbers correct? Are you comparing the correct variables?", CWE571, inconclusive); "Are these conditions necessary? Did you intend to use && instead? Are the numbers correct? Are you comparing the correct variables?", CWE571, inconclusive ? Certainty::inconclusive : Certainty::normal);
else else
reportError(errors, Severity::warning, "incorrectLogicOperator", reportError(errors, Severity::warning, "incorrectLogicOperator",
"Logical conjunction always evaluates to false: " + condition + ".\n" "Logical conjunction always evaluates to false: " + condition + ".\n"
"Logical conjunction always evaluates to false: " + condition + ". " "Logical conjunction always evaluates to false: " + condition + ". "
"Are these conditions necessary? Did you intend to use || instead? Are the numbers correct? Are you comparing the correct variables?", CWE570, inconclusive); "Are these conditions necessary? Did you intend to use || instead? Are the numbers correct? Are you comparing the correct variables?", CWE570, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckCondition::redundantConditionError(const Token *tok, const std::string &text, bool inconclusive) void CheckCondition::redundantConditionError(const Token *tok, const std::string &text, bool inconclusive)
{ {
if (diag(tok)) if (diag(tok))
return; return;
reportError(tok, Severity::style, "redundantCondition", "Redundant condition: " + text, CWE398, inconclusive); reportError(tok, Severity::style, "redundantCondition", "Redundant condition: " + text, CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1264,7 +1264,7 @@ void CheckCondition::redundantConditionError(const Token *tok, const std::string
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CheckCondition::checkModuloAlwaysTrueFalse() void CheckCondition::checkModuloAlwaysTrueFalse()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -1293,7 +1293,7 @@ void CheckCondition::checkModuloAlwaysTrueFalse()
void CheckCondition::moduloAlwaysTrueFalseError(const Token* tok, const std::string& maxVal) void CheckCondition::moduloAlwaysTrueFalseError(const Token* tok, const std::string& maxVal)
{ {
reportError(tok, Severity::warning, "moduloAlwaysTrueFalse", reportError(tok, Severity::warning, "moduloAlwaysTrueFalse",
"Comparison of modulo result is predetermined, because it is always less than " + maxVal + ".", CWE398, false); "Comparison of modulo result is predetermined, because it is always less than " + maxVal + ".", CWE398, Certainty::normal);
} }
static int countPar(const Token *tok1, const Token *tok2) static int countPar(const Token *tok1, const Token *tok2)
@ -1316,7 +1316,7 @@ static int countPar(const Token *tok1, const Token *tok2)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckCondition::clarifyCondition() void CheckCondition::clarifyCondition()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const bool isC = mTokenizer->isC(); const bool isC = mTokenizer->isC();
@ -1375,12 +1375,12 @@ void CheckCondition::clarifyConditionError(const Token *tok, bool assign, bool b
reportError(tok, reportError(tok,
Severity::style, Severity::style,
"clarifyCondition", "clarifyCondition",
errmsg, CWE398, false); errmsg, CWE398, Certainty::normal);
} }
void CheckCondition::alwaysTrueFalse() void CheckCondition::alwaysTrueFalse()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -1496,7 +1496,7 @@ void CheckCondition::alwaysTrueFalseError(const Token *tok, const ValueFlow::Val
Severity::style, Severity::style,
"knownConditionTrueFalse", "knownConditionTrueFalse",
errmsg, errmsg,
(alwaysTrue ? CWE571 : CWE570), false); (alwaysTrue ? CWE571 : CWE570), Certainty::normal);
} }
void CheckCondition::checkInvalidTestForOverflow() void CheckCondition::checkInvalidTestForOverflow()
@ -1514,7 +1514,7 @@ void CheckCondition::checkInvalidTestForOverflow()
// x + y < x -> y < 0 // x + y < x -> y < 0
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
@ -1597,13 +1597,13 @@ void CheckCondition::invalidTestForOverflow(const Token* tok, const ValueType *v
errmsg += " Some mainstream compilers remove such overflow tests when optimising the code and assume it's always " + replace + "."; errmsg += " Some mainstream compilers remove such overflow tests when optimising the code and assume it's always " + replace + ".";
else else
errmsg += " Some mainstream compilers removes handling of overflows when optimising the code and change the code to '" + replace + "'."; errmsg += " Some mainstream compilers removes handling of overflows when optimising the code and change the code to '" + replace + "'.";
reportError(tok, Severity::warning, "invalidTestForOverflow", errmsg, uncheckedErrorConditionCWE, false); reportError(tok, Severity::warning, "invalidTestForOverflow", errmsg, uncheckedErrorConditionCWE, Certainty::normal);
} }
void CheckCondition::checkPointerAdditionResultNotNull() void CheckCondition::checkPointerAdditionResultNotNull()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -1648,7 +1648,7 @@ void CheckCondition::pointerAdditionResultNotNullError(const Token *tok, const T
void CheckCondition::checkDuplicateConditionalAssign() void CheckCondition::checkDuplicateConditionalAssign()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -1699,5 +1699,5 @@ void CheckCondition::duplicateConditionalAssignError(const Token *condTok, const
} }
reportError( reportError(
errors, Severity::style, "duplicateConditionalAssign", msg, CWE398, false); errors, Severity::style, "duplicateConditionalAssign", msg, CWE398, Certainty::normal);
} }

View File

@ -38,7 +38,7 @@ namespace {
void CheckExceptionSafety::destructors() void CheckExceptionSafety::destructors()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase();
@ -78,10 +78,10 @@ void CheckExceptionSafety::destructors()
void CheckExceptionSafety::deallocThrow() void CheckExceptionSafety::deallocThrow()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const bool printInconclusive = mSettings->inconclusive; const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive);
const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase();
// Deallocate a global/member pointer and then throw exception // Deallocate a global/member pointer and then throw exception
@ -145,7 +145,7 @@ void CheckExceptionSafety::deallocThrow()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckExceptionSafety::checkRethrowCopy() void CheckExceptionSafety::checkRethrowCopy()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase();
@ -179,7 +179,7 @@ void CheckExceptionSafety::checkRethrowCopy()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckExceptionSafety::checkCatchExceptionByValue() void CheckExceptionSafety::checkCatchExceptionByValue()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase();
@ -281,7 +281,7 @@ void CheckExceptionSafety::nothrowThrows()
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
void CheckExceptionSafety::unhandledExceptionSpecification() void CheckExceptionSafety::unhandledExceptionSpecification()
{ {
if (!mSettings->isEnabled(Settings::STYLE) || !mSettings->inconclusive) if (!mSettings->severity.isEnabled(Severity::style) || !mSettings->certainty.isEnabled(Certainty::inconclusive))
return; return;
const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase();

View File

@ -99,30 +99,30 @@ private:
"Class " + className + " is not safe, destructor throws exception\n" "Class " + className + " is not safe, destructor throws exception\n"
"The class " + className + " is not safe because its destructor " "The class " + className + " is not safe because its destructor "
"throws an exception. If " + className + " is used and an exception " "throws an exception. If " + className + " is used and an exception "
"is thrown that is caught in an outer scope the program will terminate.", CWE398, false); "is thrown that is caught in an outer scope the program will terminate.", CWE398, Certainty::normal);
} }
void deallocThrowError(const Token * const tok, const std::string &varname) { void deallocThrowError(const Token * const tok, const std::string &varname) {
reportError(tok, Severity::warning, "exceptDeallocThrow", "Exception thrown in invalid state, '" + reportError(tok, Severity::warning, "exceptDeallocThrow", "Exception thrown in invalid state, '" +
varname + "' points at deallocated memory.", CWE398, false); varname + "' points at deallocated memory.", CWE398, Certainty::normal);
} }
void rethrowCopyError(const Token * const tok, const std::string &varname) { void rethrowCopyError(const Token * const tok, const std::string &varname) {
reportError(tok, Severity::style, "exceptRethrowCopy", reportError(tok, Severity::style, "exceptRethrowCopy",
"Throwing a copy of the caught exception instead of rethrowing the original exception.\n" "Throwing a copy of the caught exception instead of rethrowing the original exception.\n"
"Rethrowing an exception with 'throw " + varname + ";' creates an unnecessary copy of '" + varname + "'. " "Rethrowing an exception with 'throw " + varname + ";' creates an unnecessary copy of '" + varname + "'. "
"To rethrow the caught exception without unnecessary copying or slicing, use a bare 'throw;'.", CWE398, false); "To rethrow the caught exception without unnecessary copying or slicing, use a bare 'throw;'.", CWE398, Certainty::normal);
} }
void catchExceptionByValueError(const Token *tok) { void catchExceptionByValueError(const Token *tok) {
reportError(tok, Severity::style, reportError(tok, Severity::style,
"catchExceptionByValue", "Exception should be caught by reference.\n" "catchExceptionByValue", "Exception should be caught by reference.\n"
"The exception is caught by value. It could be caught " "The exception is caught by value. It could be caught "
"as a (const) reference which is usually recommended in C++.", CWE398, false); "as a (const) reference which is usually recommended in C++.", CWE398, Certainty::normal);
} }
void noexceptThrowError(const Token * const tok) { void noexceptThrowError(const Token * const tok) {
reportError(tok, Severity::error, "throwInNoexceptFunction", "Exception thrown in function declared not to throw exceptions.", CWE398, false); reportError(tok, Severity::error, "throwInNoexceptFunction", "Exception thrown in function declared not to throw exceptions.", CWE398, Certainty::normal);
} }
/** Missing exception specification */ /** Missing exception specification */
@ -132,7 +132,7 @@ private:
reportError(locationList, Severity::style, "unhandledExceptionSpecification", reportError(locationList, Severity::style, "unhandledExceptionSpecification",
"Unhandled exception specification when calling function " + str1 + "().\n" "Unhandled exception specification when calling function " + str1 + "().\n"
"Unhandled exception specification when calling function " + str1 + "(). " "Unhandled exception specification when calling function " + str1 + "(). "
"Either use a try/catch around the function call, or add a exception specification for " + funcname + "() also.", CWE703, true); "Either use a try/catch around the function call, or add a exception specification for " + funcname + "() also.", CWE703, Certainty::inconclusive);
} }
/** Generate all possible errors (for --errorlist) */ /** Generate all possible errors (for --errorlist) */

View File

@ -54,7 +54,7 @@ static const CWE CWE688(688U); // Function Call With Incorrect Variable or Refe
void CheckFunctions::checkProhibitedFunctions() void CheckFunctions::checkProhibitedFunctions()
{ {
const bool checkAlloca = mSettings->isEnabled(Settings::WARNING) && ((mSettings->standards.c >= Standards::C99 && mTokenizer->isC()) || mSettings->standards.cpp >= Standards::CPP11); const bool checkAlloca = mSettings->severity.isEnabled(Severity::warning) && ((mSettings->standards.c >= Standards::C99 && mTokenizer->isC()) || mSettings->standards.cpp >= Standards::CPP11);
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope *scope : symbolDatabase->functionScopes) { for (const Scope *scope : symbolDatabase->functionScopes) {
@ -84,9 +84,9 @@ void CheckFunctions::checkProhibitedFunctions()
const Library::WarnInfo* wi = mSettings->library.getWarnInfo(tok); const Library::WarnInfo* wi = mSettings->library.getWarnInfo(tok);
if (wi) { if (wi) {
if (mSettings->isEnabled(wi->severity) && mSettings->standards.c >= wi->standards.c && mSettings->standards.cpp >= wi->standards.cpp) { if (mSettings->severity.isEnabled(wi->severity) && mSettings->standards.c >= wi->standards.c && mSettings->standards.cpp >= wi->standards.cpp) {
const std::string daca = mSettings->daca ? "prohibited" : ""; const std::string daca = mSettings->daca ? "prohibited" : "";
reportError(tok, wi->severity, daca + tok->str() + "Called", wi->message, CWE477, false); reportError(tok, wi->severity, daca + tok->str() + "Called", wi->message, CWE477, Certainty::normal);
} }
} }
} }
@ -161,14 +161,14 @@ void CheckFunctions::invalidFunctionArgError(const Token *tok, const std::string
"invalidFunctionArg", "invalidFunctionArg",
errmsg.str(), errmsg.str(),
CWE628, CWE628,
invalidValue->isInconclusive()); invalidValue->isInconclusive() ? Certainty::inconclusive : Certainty::normal);
else else
reportError(tok, reportError(tok,
Severity::error, Severity::error,
"invalidFunctionArg", "invalidFunctionArg",
errmsg.str(), errmsg.str(),
CWE628, CWE628,
false); Certainty::normal);
} }
void CheckFunctions::invalidFunctionArgBoolError(const Token *tok, const std::string &functionName, int argnr) void CheckFunctions::invalidFunctionArgBoolError(const Token *tok, const std::string &functionName, int argnr)
@ -176,7 +176,7 @@ void CheckFunctions::invalidFunctionArgBoolError(const Token *tok, const std::st
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "$symbol:" << functionName << '\n'; errmsg << "$symbol:" << functionName << '\n';
errmsg << "Invalid $symbol() argument nr " << argnr << ". A non-boolean value is required."; errmsg << "Invalid $symbol() argument nr " << argnr << ". A non-boolean value is required.";
reportError(tok, Severity::error, "invalidFunctionArgBool", errmsg.str(), CWE628, false); reportError(tok, Severity::error, "invalidFunctionArgBool", errmsg.str(), CWE628, Certainty::normal);
} }
void CheckFunctions::invalidFunctionArgStrError(const Token *tok, const std::string &functionName, nonneg int argnr) void CheckFunctions::invalidFunctionArgStrError(const Token *tok, const std::string &functionName, nonneg int argnr)
@ -184,7 +184,7 @@ void CheckFunctions::invalidFunctionArgStrError(const Token *tok, const std::str
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "$symbol:" << functionName << '\n'; errmsg << "$symbol:" << functionName << '\n';
errmsg << "Invalid $symbol() argument nr " << argnr << ". A nul-terminated string is required."; errmsg << "Invalid $symbol() argument nr " << argnr << ". A nul-terminated string is required.";
reportError(tok, Severity::error, "invalidFunctionArgStr", errmsg.str(), CWE628, false); reportError(tok, Severity::error, "invalidFunctionArgStr", errmsg.str(), CWE628, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -192,7 +192,7 @@ void CheckFunctions::invalidFunctionArgStrError(const Token *tok, const std::str
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckFunctions::checkIgnoredReturnValue() void CheckFunctions::checkIgnoredReturnValue()
{ {
if (!mSettings->isEnabled(Settings::WARNING) && !mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -218,11 +218,11 @@ void CheckFunctions::checkIgnoredReturnValue()
if ((!tok->function() || !Token::Match(tok->function()->retDef, "void %name%")) && if ((!tok->function() || !Token::Match(tok->function()->retDef, "void %name%")) &&
!WRONG_DATA(!tok->next()->astOperand1(), tok)) { !WRONG_DATA(!tok->next()->astOperand1(), tok)) {
const Library::UseRetValType retvalTy = mSettings->library.getUseRetValType(tok); const Library::UseRetValType retvalTy = mSettings->library.getUseRetValType(tok);
if (mSettings->isEnabled(Settings::WARNING) && if (mSettings->severity.isEnabled(Severity::warning) &&
((retvalTy == Library::UseRetValType::DEFAULT) || ((retvalTy == Library::UseRetValType::DEFAULT) ||
(tok->function() && tok->function()->isAttributeNodiscard()))) (tok->function() && tok->function()->isAttributeNodiscard())))
ignoredReturnValueError(tok, tok->next()->astOperand1()->expressionString()); ignoredReturnValueError(tok, tok->next()->astOperand1()->expressionString());
else if (mSettings->isEnabled(Settings::STYLE) && else if (mSettings->severity.isEnabled(Severity::style) &&
retvalTy == Library::UseRetValType::ERROR_CODE) retvalTy == Library::UseRetValType::ERROR_CODE)
ignoredReturnErrorCode(tok, tok->next()->astOperand1()->expressionString()); ignoredReturnErrorCode(tok, tok->next()->astOperand1()->expressionString());
} }
@ -233,13 +233,13 @@ void CheckFunctions::checkIgnoredReturnValue()
void CheckFunctions::ignoredReturnValueError(const Token* tok, const std::string& function) void CheckFunctions::ignoredReturnValueError(const Token* tok, const std::string& function)
{ {
reportError(tok, Severity::warning, "ignoredReturnValue", reportError(tok, Severity::warning, "ignoredReturnValue",
"$symbol:" + function + "\nReturn value of function $symbol() is not used.", CWE252, false); "$symbol:" + function + "\nReturn value of function $symbol() is not used.", CWE252, Certainty::normal);
} }
void CheckFunctions::ignoredReturnErrorCode(const Token* tok, const std::string& function) void CheckFunctions::ignoredReturnErrorCode(const Token* tok, const std::string& function)
{ {
reportError(tok, Severity::style, "ignoredReturnErrorCode", reportError(tok, Severity::style, "ignoredReturnErrorCode",
"$symbol:" + function + "\nError code from the return value of function $symbol() is not used.", CWE252, false); "$symbol:" + function + "\nError code from the return value of function $symbol() is not used.", CWE252, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -247,8 +247,8 @@ void CheckFunctions::ignoredReturnErrorCode(const Token* tok, const std::string&
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckFunctions::checkMathFunctions() void CheckFunctions::checkMathFunctions()
{ {
const bool styleC99 = mSettings->isEnabled(Settings::STYLE) && mSettings->standards.c != Standards::C89 && mSettings->standards.cpp != Standards::CPP03; const bool styleC99 = mSettings->severity.isEnabled(Severity::style) && mSettings->standards.c != Standards::C89 && mSettings->standards.cpp != Standards::CPP03;
const bool printWarnings = mSettings->isEnabled(Settings::WARNING); const bool printWarnings = mSettings->severity.isEnabled(Severity::warning);
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope *scope : symbolDatabase->functionScopes) { for (const Scope *scope : symbolDatabase->functionScopes) {
@ -305,16 +305,16 @@ void CheckFunctions::mathfunctionCallWarning(const Token *tok, const nonneg int
{ {
if (tok) { if (tok) {
if (numParam == 1) if (numParam == 1)
reportError(tok, Severity::warning, "wrongmathcall", "$symbol:" + tok->str() + "\nPassing value " + tok->strAt(2) + " to $symbol() leads to implementation-defined result.", CWE758, false); reportError(tok, Severity::warning, "wrongmathcall", "$symbol:" + tok->str() + "\nPassing value " + tok->strAt(2) + " to $symbol() leads to implementation-defined result.", CWE758, Certainty::normal);
else if (numParam == 2) else if (numParam == 2)
reportError(tok, Severity::warning, "wrongmathcall", "$symbol:" + tok->str() + "\nPassing values " + tok->strAt(2) + " and " + tok->strAt(4) + " to $symbol() leads to implementation-defined result.", CWE758, false); reportError(tok, Severity::warning, "wrongmathcall", "$symbol:" + tok->str() + "\nPassing values " + tok->strAt(2) + " and " + tok->strAt(4) + " to $symbol() leads to implementation-defined result.", CWE758, Certainty::normal);
} else } else
reportError(tok, Severity::warning, "wrongmathcall", "Passing value '#' to #() leads to implementation-defined result.", CWE758, false); reportError(tok, Severity::warning, "wrongmathcall", "Passing value '#' to #() leads to implementation-defined result.", CWE758, Certainty::normal);
} }
void CheckFunctions::mathfunctionCallWarning(const Token *tok, const std::string& oldexp, const std::string& newexp) void CheckFunctions::mathfunctionCallWarning(const Token *tok, const std::string& oldexp, const std::string& newexp)
{ {
reportError(tok, Severity::style, "unpreciseMathCall", "Expression '" + oldexp + "' can be replaced by '" + newexp + "' to avoid loss of precision.", CWE758, false); reportError(tok, Severity::style, "unpreciseMathCall", "Expression '" + oldexp + "' can be replaced by '" + newexp + "' to avoid loss of precision.", CWE758, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -329,7 +329,7 @@ void CheckFunctions::memsetZeroBytes()
// <warn knownIntValue="0" severity="warning" msg="..."/> // <warn knownIntValue="0" severity="warning" msg="..."/>
// </arg> // </arg>
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -353,7 +353,7 @@ void CheckFunctions::memsetZeroBytesError(const Token *tok)
const std::string verbose(summary + " The second and third arguments might be inverted." const std::string verbose(summary + " The second and third arguments might be inverted."
" The function memset ( void * ptr, int value, size_t num ) sets the" " The function memset ( void * ptr, int value, size_t num ) sets the"
" first num bytes of the block of memory pointed by ptr to the specified value."); " first num bytes of the block of memory pointed by ptr to the specified value.");
reportError(tok, Severity::warning, "memsetZeroBytes", summary + "\n" + verbose, CWE687, false); reportError(tok, Severity::warning, "memsetZeroBytes", summary + "\n" + verbose, CWE687, Certainty::normal);
} }
void CheckFunctions::memsetInvalid2ndParam() void CheckFunctions::memsetInvalid2ndParam()
@ -366,8 +366,8 @@ void CheckFunctions::memsetInvalid2ndParam()
// <warn possibleIntValue=":-129,256:" severity="warning" msg="..."/> // <warn possibleIntValue=":-129,256:" severity="warning" msg="..."/>
// </arg> // </arg>
const bool printPortability = mSettings->isEnabled(Settings::PORTABILITY); const bool printPortability = mSettings->severity.isEnabled(Severity::portability);
const bool printWarning = mSettings->isEnabled(Settings::WARNING); const bool printWarning = mSettings->severity.isEnabled(Severity::warning);
if (!printWarning && !printPortability) if (!printWarning && !printPortability)
return; return;
@ -408,14 +408,14 @@ void CheckFunctions::memsetFloatError(const Token *tok, const std::string &var_v
"' is a float, its representation is implementation defined."); "' is a float, its representation is implementation defined.");
const std::string verbose(message + " memset() is used to set each byte of a block of memory to a specific value and" const std::string verbose(message + " memset() is used to set each byte of a block of memory to a specific value and"
" the actual representation of a floating-point value is implementation defined."); " the actual representation of a floating-point value is implementation defined.");
reportError(tok, Severity::portability, "memsetFloat", message + "\n" + verbose, CWE688, false); reportError(tok, Severity::portability, "memsetFloat", message + "\n" + verbose, CWE688, Certainty::normal);
} }
void CheckFunctions::memsetValueOutOfRangeError(const Token *tok, const std::string &value) void CheckFunctions::memsetValueOutOfRangeError(const Token *tok, const std::string &value)
{ {
const std::string message("The 2nd memset() argument '" + value + "' doesn't fit into an 'unsigned char'."); const std::string message("The 2nd memset() argument '" + value + "' doesn't fit into an 'unsigned char'.");
const std::string verbose(message + " The 2nd parameter is passed as an 'int', but the function fills the block of memory using the 'unsigned char' conversion of this value."); const std::string verbose(message + " The 2nd parameter is passed as an 'int', but the function fills the block of memory using the 'unsigned char' conversion of this value.");
reportError(tok, Severity::warning, "memsetValueOutOfRange", message + "\n" + verbose, CWE686, false); reportError(tok, Severity::warning, "memsetValueOutOfRange", message + "\n" + verbose, CWE686, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -424,7 +424,7 @@ void CheckFunctions::memsetValueOutOfRangeError(const Token *tok, const std::str
void CheckFunctions::checkLibraryMatchFunctions() void CheckFunctions::checkLibraryMatchFunctions()
{ {
if (!mSettings->checkLibrary || !mSettings->isEnabled(Settings::INFORMATION)) if (!mSettings->checkLibrary || !mSettings->severity.isEnabled(Severity::information))
return; return;
bool insideNew = false; bool insideNew = false;

View File

@ -45,7 +45,7 @@ public:
} }
void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) OVERRIDE { void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) OVERRIDE {
if (!settings->isEnabled(Settings::INTERNAL)) if (!settings->checks.isEnabled(Checks::internalCheck))
return; return;
CheckInternal checkInternal(tokenizer, settings, errorLogger); CheckInternal checkInternal(tokenizer, settings, errorLogger);

View File

@ -78,7 +78,7 @@ void CheckIO::checkCoutCerrMisusage()
void CheckIO::coutCerrMisusageError(const Token* tok, const std::string& streamName) void CheckIO::coutCerrMisusageError(const Token* tok, const std::string& streamName)
{ {
reportError(tok, Severity::error, "coutCerrMisusage", "Invalid usage of output stream: '<< std::" + streamName + "'.", CWE398, false); reportError(tok, Severity::error, "coutCerrMisusage", "Invalid usage of output stream: '<< std::" + streamName + "'.", CWE398, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -118,8 +118,8 @@ namespace {
void CheckIO::checkFileUsage() void CheckIO::checkFileUsage()
{ {
const bool windows = mSettings->isWindowsPlatform(); const bool windows = mSettings->isWindowsPlatform();
const bool printPortability = mSettings->isEnabled(Settings::PORTABILITY); const bool printPortability = mSettings->severity.isEnabled(Severity::portability);
const bool printWarnings = mSettings->isEnabled(Settings::WARNING); const bool printWarnings = mSettings->severity.isEnabled(Severity::warning);
std::map<int, Filepointer> filepointers; std::map<int, Filepointer> filepointers;
@ -337,37 +337,37 @@ void CheckIO::checkFileUsage()
void CheckIO::fflushOnInputStreamError(const Token *tok, const std::string &varname) void CheckIO::fflushOnInputStreamError(const Token *tok, const std::string &varname)
{ {
reportError(tok, Severity::portability, reportError(tok, Severity::portability,
"fflushOnInputStream", "fflush() called on input stream '" + varname + "' may result in undefined behaviour on non-linux systems.", CWE398, false); "fflushOnInputStream", "fflush() called on input stream '" + varname + "' may result in undefined behaviour on non-linux systems.", CWE398, Certainty::normal);
} }
void CheckIO::ioWithoutPositioningError(const Token *tok) void CheckIO::ioWithoutPositioningError(const Token *tok)
{ {
reportError(tok, Severity::error, reportError(tok, Severity::error,
"IOWithoutPositioning", "Read and write operations without a call to a positioning function (fseek, fsetpos or rewind) or fflush in between result in undefined behaviour.", CWE664, false); "IOWithoutPositioning", "Read and write operations without a call to a positioning function (fseek, fsetpos or rewind) or fflush in between result in undefined behaviour.", CWE664, Certainty::normal);
} }
void CheckIO::readWriteOnlyFileError(const Token *tok) void CheckIO::readWriteOnlyFileError(const Token *tok)
{ {
reportError(tok, Severity::error, reportError(tok, Severity::error,
"readWriteOnlyFile", "Read operation on a file that was opened only for writing.", CWE664, false); "readWriteOnlyFile", "Read operation on a file that was opened only for writing.", CWE664, Certainty::normal);
} }
void CheckIO::writeReadOnlyFileError(const Token *tok) void CheckIO::writeReadOnlyFileError(const Token *tok)
{ {
reportError(tok, Severity::error, reportError(tok, Severity::error,
"writeReadOnlyFile", "Write operation on a file that was opened only for reading.", CWE664, false); "writeReadOnlyFile", "Write operation on a file that was opened only for reading.", CWE664, Certainty::normal);
} }
void CheckIO::useClosedFileError(const Token *tok) void CheckIO::useClosedFileError(const Token *tok)
{ {
reportError(tok, Severity::error, reportError(tok, Severity::error,
"useClosedFile", "Used file that is not opened.", CWE910, false); "useClosedFile", "Used file that is not opened.", CWE910, Certainty::normal);
} }
void CheckIO::seekOnAppendedFileError(const Token *tok) void CheckIO::seekOnAppendedFileError(const Token *tok)
{ {
reportError(tok, Severity::warning, reportError(tok, Severity::warning,
"seekOnAppendedFile", "Repositioning operation performed on a file opened in append mode has no effect.", CWE398, false); "seekOnAppendedFile", "Repositioning operation performed on a file opened in append mode has no effect.", CWE398, Certainty::normal);
} }
@ -376,7 +376,7 @@ void CheckIO::seekOnAppendedFileError(const Token *tok)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckIO::invalidScanf() void CheckIO::invalidScanf()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase();
@ -442,7 +442,7 @@ void CheckIO::invalidScanfError(const Token *tok)
"terminating null byte.\n" "terminating null byte.\n"
"Source: http://linux.die.net/man/3/scanf\n" "Source: http://linux.die.net/man/3/scanf\n"
"Source: http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/libkern/stdio/scanf.c", "Source: http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/libkern/stdio/scanf.c",
CWE119, false); CWE119, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -567,7 +567,7 @@ void CheckIO::checkFormatString(const Token * const tok,
const bool scanf_s) const bool scanf_s)
{ {
const bool isWindows = mSettings->isWindowsPlatform(); const bool isWindows = mSettings->isWindowsPlatform();
const bool printWarning = mSettings->isEnabled(Settings::WARNING); const bool printWarning = mSettings->severity.isEnabled(Severity::warning);
const std::string &formatString = formatStringTok->str(); const std::string &formatString = formatStringTok->str();
// Count format string parameters.. // Count format string parameters..
@ -1686,7 +1686,7 @@ void CheckIO::wrongPrintfScanfArgumentsError(const Token* tok,
nonneg int numFunction) nonneg int numFunction)
{ {
const Severity::SeverityType severity = numFormat > numFunction ? Severity::error : Severity::warning; const Severity::SeverityType severity = numFormat > numFunction ? Severity::error : Severity::warning;
if (severity != Severity::error && !mSettings->isEnabled(Settings::WARNING)) if (severity != Severity::error && !mSettings->severity.isEnabled(Severity::warning))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
@ -1699,13 +1699,13 @@ void CheckIO::wrongPrintfScanfArgumentsError(const Token* tok,
<< (numFunction != 1 ? " are" : " is") << (numFunction != 1 ? " are" : " is")
<< " given."; << " given.";
reportError(tok, severity, "wrongPrintfScanfArgNum", errmsg.str(), CWE685, false); reportError(tok, severity, "wrongPrintfScanfArgNum", errmsg.str(), CWE685, Certainty::normal);
} }
void CheckIO::wrongPrintfScanfPosixParameterPositionError(const Token* tok, const std::string& functionName, void CheckIO::wrongPrintfScanfPosixParameterPositionError(const Token* tok, const std::string& functionName,
nonneg int index, nonneg int numFunction) nonneg int index, nonneg int numFunction)
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << functionName << ": "; errmsg << functionName << ": ";
@ -1714,13 +1714,13 @@ void CheckIO::wrongPrintfScanfPosixParameterPositionError(const Token* tok, cons
} else { } else {
errmsg << "referencing parameter " << index << " while " << numFunction << " arguments given"; errmsg << "referencing parameter " << index << " while " << numFunction << " arguments given";
} }
reportError(tok, Severity::warning, "wrongPrintfScanfParameterPositionError", errmsg.str(), CWE685, false); reportError(tok, Severity::warning, "wrongPrintfScanfParameterPositionError", errmsg.str(), CWE685, Certainty::normal);
} }
void CheckIO::invalidScanfArgTypeError_s(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) void CheckIO::invalidScanfArgTypeError_s(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo)
{ {
const Severity::SeverityType severity = getSeverity(argInfo); const Severity::SeverityType severity = getSeverity(argInfo);
if (!mSettings->isEnabled(severity)) if (!mSettings->severity.isEnabled(severity))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires a \'"; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires a \'";
@ -1731,12 +1731,12 @@ void CheckIO::invalidScanfArgTypeError_s(const Token* tok, nonneg int numFormat,
errmsg << " *\' but the argument type is "; errmsg << " *\' but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, severity, "invalidScanfArgType_s", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidScanfArgType_s", errmsg.str(), CWE686, Certainty::normal);
} }
void CheckIO::invalidScanfArgTypeError_int(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo, bool isUnsigned) void CheckIO::invalidScanfArgTypeError_int(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo, bool isUnsigned)
{ {
const Severity::SeverityType severity = getSeverity(argInfo); const Severity::SeverityType severity = getSeverity(argInfo);
if (!mSettings->isEnabled(severity)) if (!mSettings->severity.isEnabled(severity))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires \'"; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires \'";
@ -1776,12 +1776,12 @@ void CheckIO::invalidScanfArgTypeError_int(const Token* tok, nonneg int numForma
errmsg << " *\' but the argument type is "; errmsg << " *\' but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, severity, "invalidScanfArgType_int", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidScanfArgType_int", errmsg.str(), CWE686, Certainty::normal);
} }
void CheckIO::invalidScanfArgTypeError_float(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) void CheckIO::invalidScanfArgTypeError_float(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo)
{ {
const Severity::SeverityType severity = getSeverity(argInfo); const Severity::SeverityType severity = getSeverity(argInfo);
if (!mSettings->isEnabled(severity)) if (!mSettings->severity.isEnabled(severity))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires \'"; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires \'";
@ -1794,41 +1794,41 @@ void CheckIO::invalidScanfArgTypeError_float(const Token* tok, nonneg int numFor
errmsg << " *\' but the argument type is "; errmsg << " *\' but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, severity, "invalidScanfArgType_float", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidScanfArgType_float", errmsg.str(), CWE686, Certainty::normal);
} }
void CheckIO::invalidPrintfArgTypeError_s(const Token* tok, nonneg int numFormat, const ArgumentInfo* argInfo) void CheckIO::invalidPrintfArgTypeError_s(const Token* tok, nonneg int numFormat, const ArgumentInfo* argInfo)
{ {
const Severity::SeverityType severity = getSeverity(argInfo); const Severity::SeverityType severity = getSeverity(argInfo);
if (!mSettings->isEnabled(severity)) if (!mSettings->severity.isEnabled(severity))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%s in format string (no. " << numFormat << ") requires \'char *\' but the argument type is "; errmsg << "%s in format string (no. " << numFormat << ") requires \'char *\' but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, severity, "invalidPrintfArgType_s", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidPrintfArgType_s", errmsg.str(), CWE686, Certainty::normal);
} }
void CheckIO::invalidPrintfArgTypeError_n(const Token* tok, nonneg int numFormat, const ArgumentInfo* argInfo) void CheckIO::invalidPrintfArgTypeError_n(const Token* tok, nonneg int numFormat, const ArgumentInfo* argInfo)
{ {
const Severity::SeverityType severity = getSeverity(argInfo); const Severity::SeverityType severity = getSeverity(argInfo);
if (!mSettings->isEnabled(severity)) if (!mSettings->severity.isEnabled(severity))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%n in format string (no. " << numFormat << ") requires \'int *\' but the argument type is "; errmsg << "%n in format string (no. " << numFormat << ") requires \'int *\' but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, severity, "invalidPrintfArgType_n", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidPrintfArgType_n", errmsg.str(), CWE686, Certainty::normal);
} }
void CheckIO::invalidPrintfArgTypeError_p(const Token* tok, nonneg int numFormat, const ArgumentInfo* argInfo) void CheckIO::invalidPrintfArgTypeError_p(const Token* tok, nonneg int numFormat, const ArgumentInfo* argInfo)
{ {
const Severity::SeverityType severity = getSeverity(argInfo); const Severity::SeverityType severity = getSeverity(argInfo);
if (!mSettings->isEnabled(severity)) if (!mSettings->severity.isEnabled(severity))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%p in format string (no. " << numFormat << ") requires an address but the argument type is "; errmsg << "%p in format string (no. " << numFormat << ") requires an address but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, severity, "invalidPrintfArgType_p", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidPrintfArgType_p", errmsg.str(), CWE686, Certainty::normal);
} }
static void printfFormatType(std::ostream& os, const std::string& specifier, bool isUnsigned) static void printfFormatType(std::ostream& os, const std::string& specifier, bool isUnsigned)
{ {
@ -1872,7 +1872,7 @@ static void printfFormatType(std::ostream& os, const std::string& specifier, boo
void CheckIO::invalidPrintfArgTypeError_uint(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) void CheckIO::invalidPrintfArgTypeError_uint(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo)
{ {
const Severity::SeverityType severity = getSeverity(argInfo); const Severity::SeverityType severity = getSeverity(argInfo);
if (!mSettings->isEnabled(severity)) if (!mSettings->severity.isEnabled(severity))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires "; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires ";
@ -1880,13 +1880,13 @@ void CheckIO::invalidPrintfArgTypeError_uint(const Token* tok, nonneg int numFor
errmsg << " but the argument type is "; errmsg << " but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, severity, "invalidPrintfArgType_uint", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidPrintfArgType_uint", errmsg.str(), CWE686, Certainty::normal);
} }
void CheckIO::invalidPrintfArgTypeError_sint(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) void CheckIO::invalidPrintfArgTypeError_sint(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo)
{ {
const Severity::SeverityType severity = getSeverity(argInfo); const Severity::SeverityType severity = getSeverity(argInfo);
if (!mSettings->isEnabled(severity)) if (!mSettings->severity.isEnabled(severity))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires "; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires ";
@ -1894,12 +1894,12 @@ void CheckIO::invalidPrintfArgTypeError_sint(const Token* tok, nonneg int numFor
errmsg << " but the argument type is "; errmsg << " but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, severity, "invalidPrintfArgType_sint", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidPrintfArgType_sint", errmsg.str(), CWE686, Certainty::normal);
} }
void CheckIO::invalidPrintfArgTypeError_float(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo) void CheckIO::invalidPrintfArgTypeError_float(const Token* tok, nonneg int numFormat, const std::string& specifier, const ArgumentInfo* argInfo)
{ {
const Severity::SeverityType severity = getSeverity(argInfo); const Severity::SeverityType severity = getSeverity(argInfo);
if (!mSettings->isEnabled(severity)) if (!mSettings->severity.isEnabled(severity))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires \'"; errmsg << "%" << specifier << " in format string (no. " << numFormat << ") requires \'";
@ -1908,7 +1908,7 @@ void CheckIO::invalidPrintfArgTypeError_float(const Token* tok, nonneg int numFo
errmsg << "double\' but the argument type is "; errmsg << "double\' but the argument type is ";
argumentType(errmsg, argInfo); argumentType(errmsg, argInfo);
errmsg << "."; errmsg << ".";
reportError(tok, severity, "invalidPrintfArgType_float", errmsg.str(), CWE686, false); reportError(tok, severity, "invalidPrintfArgType_float", errmsg.str(), CWE686, Certainty::normal);
} }
Severity::SeverityType CheckIO::getSeverity(const CheckIO::ArgumentInfo *argInfo) Severity::SeverityType CheckIO::getSeverity(const CheckIO::ArgumentInfo *argInfo)
@ -1968,11 +1968,11 @@ void CheckIO::argumentType(std::ostream& os, const ArgumentInfo * argInfo)
void CheckIO::invalidLengthModifierError(const Token* tok, nonneg int numFormat, const std::string& modifier) void CheckIO::invalidLengthModifierError(const Token* tok, nonneg int numFormat, const std::string& modifier)
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
std::ostringstream errmsg; std::ostringstream errmsg;
errmsg << "'" << modifier << "' in format string (no. " << numFormat << ") is a length modifier and cannot be used without a conversion specifier."; errmsg << "'" << modifier << "' in format string (no. " << numFormat << ") is a length modifier and cannot be used without a conversion specifier.";
reportError(tok, Severity::warning, "invalidLengthModifierError", errmsg.str(), CWE704, false); reportError(tok, Severity::warning, "invalidLengthModifierError", errmsg.str(), CWE704, Certainty::normal);
} }
void CheckIO::invalidScanfFormatWidthError(const Token* tok, nonneg int numFormat, int width, const Variable *var, char c) void CheckIO::invalidScanfFormatWidthError(const Token* tok, nonneg int numFormat, int width, const Variable *var, char c)
@ -1987,14 +1987,14 @@ void CheckIO::invalidScanfFormatWidthError(const Token* tok, nonneg int numForma
std::ostringstream errmsg; std::ostringstream errmsg;
if (arrlen > width) { if (arrlen > width) {
if (tok != nullptr && (!mSettings->inconclusive || !mSettings->isEnabled(Settings::WARNING))) if (tok != nullptr && (!mSettings->certainty.isEnabled(Certainty::inconclusive) || !mSettings->severity.isEnabled(Severity::warning)))
return; return;
errmsg << "Width " << width << " given in format string (no. " << numFormat << ") is smaller than destination buffer" errmsg << "Width " << width << " given in format string (no. " << numFormat << ") is smaller than destination buffer"
<< " '" << varname << "[" << arrlen << "]'."; << " '" << varname << "[" << arrlen << "]'.";
reportError(tok, Severity::warning, "invalidScanfFormatWidth_smaller", errmsg.str(), CWE(0U), true); reportError(tok, Severity::warning, "invalidScanfFormatWidth_smaller", errmsg.str(), CWE(0U), Certainty::inconclusive);
} else { } else {
errmsg << "Width " << width << " given in format string (no. " << numFormat << ") is larger than destination buffer '" errmsg << "Width " << width << " given in format string (no. " << numFormat << ") is larger than destination buffer '"
<< varname << "[" << arrlen << "]', use %" << (c == 'c' ? arrlen : (arrlen - 1)) << c << " to prevent overflowing it."; << varname << "[" << arrlen << "]', use %" << (c == 'c' ? arrlen : (arrlen - 1)) << c << " to prevent overflowing it.";
reportError(tok, Severity::error, "invalidScanfFormatWidth", errmsg.str(), CWE687, false); reportError(tok, Severity::error, "invalidScanfFormatWidth", errmsg.str(), CWE687, Certainty::normal);
} }
} }

View File

@ -152,12 +152,12 @@ void CheckLeakAutoVar::deallocUseError(const Token *tok, const std::string &varn
void CheckLeakAutoVar::deallocReturnError(const Token *tok, const Token *deallocTok, const std::string &varname) void CheckLeakAutoVar::deallocReturnError(const Token *tok, const Token *deallocTok, const std::string &varname)
{ {
const std::list<const Token *> locations = { deallocTok, tok }; const std::list<const Token *> locations = { deallocTok, tok };
reportError(locations, Severity::error, "deallocret", "$symbol:" + varname + "\nReturning/dereferencing '$symbol' after it is deallocated / released", CWE672, false); reportError(locations, Severity::error, "deallocret", "$symbol:" + varname + "\nReturning/dereferencing '$symbol' after it is deallocated / released", CWE672, Certainty::normal);
} }
void CheckLeakAutoVar::configurationInfo(const Token* tok, const std::string &functionName) void CheckLeakAutoVar::configurationInfo(const Token* tok, const std::string &functionName)
{ {
if (mSettings->checkLibrary && mSettings->isEnabled(Settings::INFORMATION)) { if (mSettings->checkLibrary && mSettings->severity.isEnabled(Severity::information)) {
reportError(tok, reportError(tok,
Severity::information, Severity::information,
"checkLibraryUseIgnore", "checkLibraryUseIgnore",
@ -170,9 +170,9 @@ void CheckLeakAutoVar::doubleFreeError(const Token *tok, const Token *prevFreeTo
const std::list<const Token *> locations = { prevFreeTok, tok }; const std::list<const Token *> locations = { prevFreeTok, tok };
if (Library::isresource(type)) if (Library::isresource(type))
reportError(locations, Severity::error, "doubleFree", "$symbol:" + varname + "\nResource handle '$symbol' freed twice.", CWE415, false); reportError(locations, Severity::error, "doubleFree", "$symbol:" + varname + "\nResource handle '$symbol' freed twice.", CWE415, Certainty::normal);
else else
reportError(locations, Severity::error, "doubleFree", "$symbol:" + varname + "\nMemory pointed to by '$symbol' is freed twice.", CWE415, false); reportError(locations, Severity::error, "doubleFree", "$symbol:" + varname + "\nMemory pointed to by '$symbol' is freed twice.", CWE415, Certainty::normal);
} }

View File

@ -297,7 +297,7 @@ void CheckMemoryLeak::reportErr(const Token *tok, Severity::SeverityType severit
void CheckMemoryLeak::reportErr(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg, const CWE &cwe) const void CheckMemoryLeak::reportErr(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg, const CWE &cwe) const
{ {
const ErrorMessage errmsg(callstack, mTokenizer_ ? &mTokenizer_->list : nullptr, severity, id, msg, cwe, false, mSettings_->bugHunting); const ErrorMessage errmsg(callstack, mTokenizer_ ? &mTokenizer_->list : nullptr, severity, id, msg, cwe, Certainty::normal, mSettings_->bugHunting);
if (mErrorLogger_) if (mErrorLogger_)
mErrorLogger_->reportErr(errmsg); mErrorLogger_->reportErr(errmsg);
else else
@ -711,14 +711,14 @@ void CheckMemoryLeakInClass::variable(const Scope *scope, const Token *tokVarnam
void CheckMemoryLeakInClass::unsafeClassError(const Token *tok, const std::string &classname, const std::string &varname) void CheckMemoryLeakInClass::unsafeClassError(const Token *tok, const std::string &classname, const std::string &varname)
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
reportError(tok, Severity::style, "unsafeClassCanLeak", reportError(tok, Severity::style, "unsafeClassCanLeak",
"$symbol:" + classname + "\n" "$symbol:" + classname + "\n"
"$symbol:" + varname + "\n" "$symbol:" + varname + "\n"
"Class '" + classname + "' is unsafe, '" + varname + "' can leak by wrong usage.\n" "Class '" + classname + "' is unsafe, '" + varname + "' can leak by wrong usage.\n"
"The class '" + classname + "' is unsafe, wrong usage can cause memory/resource leaks for '" + varname + "'. This can for instance be fixed by adding proper cleanup in the destructor.", CWE398, false); "The class '" + classname + "' is unsafe, wrong usage can cause memory/resource leaks for '" + varname + "'. This can for instance be fixed by adding proper cleanup in the destructor.", CWE398, Certainty::normal);
} }
@ -727,7 +727,7 @@ void CheckMemoryLeakInClass::checkPublicFunctions(const Scope *scope, const Toke
// Check that public functions deallocate the pointers that they allocate. // Check that public functions deallocate the pointers that they allocate.
// There is no checking how these functions are used and therefore it // There is no checking how these functions are used and therefore it
// isn't established if there is real leaks or not. // isn't established if there is real leaks or not.
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const int varid = classtok->varId(); const int varid = classtok->varId();
@ -754,7 +754,7 @@ void CheckMemoryLeakInClass::checkPublicFunctions(const Scope *scope, const Toke
void CheckMemoryLeakInClass::publicAllocationError(const Token *tok, const std::string &varname) void CheckMemoryLeakInClass::publicAllocationError(const Token *tok, const std::string &varname)
{ {
reportError(tok, Severity::warning, "publicAllocationError", "$symbol:" + varname + "\nPossible leak in public function. The pointer '$symbol' is not deallocated before it is allocated.", CWE398, false); reportError(tok, Severity::warning, "publicAllocationError", "$symbol:" + varname + "\nPossible leak in public function. The pointer '$symbol' is not deallocated before it is allocated.", CWE398, Certainty::normal);
} }
@ -1081,7 +1081,7 @@ void CheckMemoryLeakNoVar::checkForUnusedReturnValue(const Scope *scope)
void CheckMemoryLeakNoVar::checkForUnsafeArgAlloc(const Scope *scope) void CheckMemoryLeakNoVar::checkForUnsafeArgAlloc(const Scope *scope)
{ {
// This test only applies to C++ source // This test only applies to C++ source
if (!mTokenizer->isCPP() || !mSettings->inconclusive || !mSettings->isEnabled(Settings::WARNING)) if (!mTokenizer->isCPP() || !mSettings->certainty.isEnabled(Certainty::inconclusive) || !mSettings->severity.isEnabled(Severity::warning))
return; return;
for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) {
@ -1125,12 +1125,12 @@ void CheckMemoryLeakNoVar::checkForUnsafeArgAlloc(const Scope *scope)
void CheckMemoryLeakNoVar::functionCallLeak(const Token *loc, const std::string &alloc, const std::string &functionCall) void CheckMemoryLeakNoVar::functionCallLeak(const Token *loc, const std::string &alloc, const std::string &functionCall)
{ {
reportError(loc, Severity::error, "leakNoVarFunctionCall", "Allocation with " + alloc + ", " + functionCall + " doesn't release it.", CWE772, false); reportError(loc, Severity::error, "leakNoVarFunctionCall", "Allocation with " + alloc + ", " + functionCall + " doesn't release it.", CWE772, Certainty::normal);
} }
void CheckMemoryLeakNoVar::returnValueNotUsedError(const Token *tok, const std::string &alloc) void CheckMemoryLeakNoVar::returnValueNotUsedError(const Token *tok, const std::string &alloc)
{ {
reportError(tok, Severity::error, "leakReturnValNotUsed", "$symbol:" + alloc + "\nReturn value of allocation function '$symbol' is not stored.", CWE771, false); reportError(tok, Severity::error, "leakReturnValNotUsed", "$symbol:" + alloc + "\nReturn value of allocation function '$symbol' is not stored.", CWE771, Certainty::normal);
} }
void CheckMemoryLeakNoVar::unsafeArgAllocError(const Token *tok, const std::string &funcName, const std::string &ptrType, const std::string& objType) void CheckMemoryLeakNoVar::unsafeArgAllocError(const Token *tok, const std::string &funcName, const std::string &ptrType, const std::string& objType)
@ -1140,5 +1140,5 @@ void CheckMemoryLeakNoVar::unsafeArgAllocError(const Token *tok, const std::stri
"$symbol:" + funcName + "\n" "$symbol:" + funcName + "\n"
"Unsafe allocation. If $symbol() throws, memory could be leaked. Use " + factoryFunc + "<" + objType + ">() instead.", "Unsafe allocation. If $symbol() throws, memory could be leaked. Use " + factoryFunc + "<" + objType + ">() instead.",
CWE401, CWE401,
true); // Inconclusive because funcName may never throw Certainty::inconclusive); // Inconclusive because funcName may never throw
} }

View File

@ -277,7 +277,7 @@ static bool isNullablePointer(const Token* tok, const Settings* settings)
void CheckNullPointer::nullPointerByDeRefAndChec() void CheckNullPointer::nullPointerByDeRefAndChec()
{ {
const bool printInconclusive = (mSettings->inconclusive); const bool printInconclusive = (mSettings->certainty.isEnabled(Certainty::inconclusive));
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
if (Token::Match(tok, "sizeof|decltype|typeid|typeof (")) { if (Token::Match(tok, "sizeof|decltype|typeid|typeof (")) {
@ -422,14 +422,14 @@ void CheckNullPointer::nullPointerError(const Token *tok, const std::string &var
const std::string errmsgdefarg("$symbol:" + varname + "\nPossible null pointer dereference if the default parameter value is used: $symbol"); const std::string errmsgdefarg("$symbol:" + varname + "\nPossible null pointer dereference if the default parameter value is used: $symbol");
if (!tok) { if (!tok) {
reportError(tok, Severity::error, "nullPointer", "Null pointer dereference", CWE_NULL_POINTER_DEREFERENCE, false); reportError(tok, Severity::error, "nullPointer", "Null pointer dereference", CWE_NULL_POINTER_DEREFERENCE, Certainty::normal);
reportError(tok, Severity::warning, "nullPointerDefaultArg", errmsgdefarg, CWE_NULL_POINTER_DEREFERENCE, false); reportError(tok, Severity::warning, "nullPointerDefaultArg", errmsgdefarg, CWE_NULL_POINTER_DEREFERENCE, Certainty::normal);
reportError(tok, Severity::warning, "nullPointerRedundantCheck", errmsgcond, CWE_NULL_POINTER_DEREFERENCE, false); reportError(tok, Severity::warning, "nullPointerRedundantCheck", errmsgcond, CWE_NULL_POINTER_DEREFERENCE, Certainty::normal);
return; return;
} }
if (!value) { if (!value) {
reportError(tok, Severity::error, "nullPointer", "Null pointer dereference", CWE_NULL_POINTER_DEREFERENCE, inconclusive); reportError(tok, Severity::error, "nullPointer", "Null pointer dereference", CWE_NULL_POINTER_DEREFERENCE, inconclusive ? Certainty::inconclusive : Certainty::normal);
return; return;
} }
@ -439,9 +439,9 @@ void CheckNullPointer::nullPointerError(const Token *tok, const std::string &var
const ErrorPath errorPath = getErrorPath(tok, value, "Null pointer dereference"); const ErrorPath errorPath = getErrorPath(tok, value, "Null pointer dereference");
if (value->condition) { if (value->condition) {
reportError(errorPath, Severity::warning, "nullPointerRedundantCheck", errmsgcond, CWE_NULL_POINTER_DEREFERENCE, inconclusive || value->isInconclusive()); reportError(errorPath, Severity::warning, "nullPointerRedundantCheck", errmsgcond, CWE_NULL_POINTER_DEREFERENCE, inconclusive || value->isInconclusive() ? Certainty::inconclusive : Certainty::normal);
} else if (value->defaultArg) { } else if (value->defaultArg) {
reportError(errorPath, Severity::warning, "nullPointerDefaultArg", errmsgdefarg, CWE_NULL_POINTER_DEREFERENCE, inconclusive || value->isInconclusive()); reportError(errorPath, Severity::warning, "nullPointerDefaultArg", errmsgdefarg, CWE_NULL_POINTER_DEREFERENCE, inconclusive || value->isInconclusive() ? Certainty::inconclusive : Certainty::normal);
} else { } else {
std::string errmsg; std::string errmsg;
errmsg = std::string(value->isKnown() ? "Null" : "Possible null") + " pointer dereference"; errmsg = std::string(value->isKnown() ? "Null" : "Possible null") + " pointer dereference";
@ -452,7 +452,7 @@ void CheckNullPointer::nullPointerError(const Token *tok, const std::string &var
value->isKnown() ? Severity::error : Severity::warning, value->isKnown() ? Severity::error : Severity::warning,
"nullPointer", "nullPointer",
errmsg, errmsg,
CWE_NULL_POINTER_DEREFERENCE, inconclusive || value->isInconclusive()); CWE_NULL_POINTER_DEREFERENCE, inconclusive || value->isInconclusive() ? Certainty::inconclusive : Certainty::normal);
} }
} }
@ -478,9 +478,9 @@ void CheckNullPointer::arithmetic()
const ValueFlow::Value* value = pointerOperand->getValue(0); const ValueFlow::Value* value = pointerOperand->getValue(0);
if (!value) if (!value)
continue; continue;
if (!mSettings->inconclusive && value->isInconclusive()) if (!mSettings->certainty.isEnabled(Certainty::inconclusive) && value->isInconclusive())
continue; continue;
if (value->condition && !mSettings->isEnabled(Settings::WARNING)) if (value->condition && !mSettings->severity.isEnabled(Severity::warning))
continue; continue;
if (value->condition) if (value->condition)
redundantConditionWarning(tok, value, value->condition, value->isInconclusive()); redundantConditionWarning(tok, value, value->condition, value->isInconclusive());
@ -515,7 +515,7 @@ void CheckNullPointer::pointerArithmeticError(const Token* tok, const ValueFlow:
"nullPointerArithmetic", "nullPointerArithmetic",
errmsg, errmsg,
CWE_INCORRECT_CALCULATION, CWE_INCORRECT_CALCULATION,
inconclusive); inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckNullPointer::redundantConditionWarning(const Token* tok, const ValueFlow::Value *value, const Token *condition, bool inconclusive) void CheckNullPointer::redundantConditionWarning(const Token* tok, const ValueFlow::Value *value, const Token *condition, bool inconclusive)
@ -533,7 +533,7 @@ void CheckNullPointer::redundantConditionWarning(const Token* tok, const ValueFl
"nullPointerArithmeticRedundantCheck", "nullPointerArithmeticRedundantCheck",
errmsg, errmsg,
CWE_INCORRECT_CALCULATION, CWE_INCORRECT_CALCULATION,
inconclusive); inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
std::string CheckNullPointer::MyFileInfo::toString() const std::string CheckNullPointer::MyFileInfo::toString() const
@ -587,7 +587,7 @@ bool CheckNullPointer::analyseWholeProgram(const CTU::FileInfo *ctu, const std::
continue; continue;
for (const CTU::FileInfo::UnsafeUsage &unsafeUsage : fi->unsafeUsage) { for (const CTU::FileInfo::UnsafeUsage &unsafeUsage : fi->unsafeUsage) {
for (int warning = 0; warning <= 1; warning++) { for (int warning = 0; warning <= 1; warning++) {
if (warning == 1 && !settings.isEnabled(Settings::WARNING)) if (warning == 1 && !settings.severity.isEnabled(Severity::warning))
break; break;
const std::list<ErrorMessage::FileLocation> &locationList = const std::list<ErrorMessage::FileLocation> &locationList =
@ -605,7 +605,7 @@ bool CheckNullPointer::analyseWholeProgram(const CTU::FileInfo *ctu, const std::
warning ? Severity::warning : Severity::error, warning ? Severity::warning : Severity::error,
"Null pointer dereference: " + unsafeUsage.myArgumentName, "Null pointer dereference: " + unsafeUsage.myArgumentName,
"ctunullpointer", "ctunullpointer",
CWE_NULL_POINTER_DEREFERENCE, false); CWE_NULL_POINTER_DEREFERENCE, Certainty::normal);
errorLogger.reportErr(errmsg); errorLogger.reportErr(errmsg);
foundErrors = true; foundErrors = true;

View File

@ -80,7 +80,7 @@ static const struct CWE CWE783(783U); // Operator Precedence Logic Error
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
void CheckOther::checkCastIntToCharAndBack() void CheckOther::checkCastIntToCharAndBack()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -138,7 +138,7 @@ void CheckOther::checkCastIntToCharAndBackError(const Token *tok, const std::str
" When $symbol() returns EOF this value is truncated. Comparing the char " " When $symbol() returns EOF this value is truncated. Comparing the char "
"variable with EOF can have unexpected results. For instance a loop \"while (EOF != (c = $symbol());\" " "variable with EOF can have unexpected results. For instance a loop \"while (EOF != (c = $symbol());\" "
"loops forever on some compilers/platforms and on other compilers/platforms it will stop " "loops forever on some compilers/platforms and on other compilers/platforms it will stop "
"when the file contains a matching character.", CWE197, false "when the file contains a matching character.", CWE197, Certainty::normal
); );
} }
@ -148,7 +148,7 @@ void CheckOther::checkCastIntToCharAndBackError(const Token *tok, const std::str
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckOther::clarifyCalculation() void CheckOther::clarifyCalculation()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -209,7 +209,7 @@ void CheckOther::clarifyCalculationError(const Token *tok, const std::string &op
"clarifyCalculation", "clarifyCalculation",
"Clarify calculation precedence for '" + op + "' and '?'.\n" "Clarify calculation precedence for '" + op + "' and '?'.\n"
"Suspicious calculation. Please use parentheses to clarify the code. " "Suspicious calculation. Please use parentheses to clarify the code. "
"The code '" + calc + "' should be written as either '" + s1 + "' or '" + s2 + "'.", CWE783, false); "The code '" + calc + "' should be written as either '" + s1 + "' or '" + s2 + "'.", CWE783, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -217,7 +217,7 @@ void CheckOther::clarifyCalculationError(const Token *tok, const std::string &op
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckOther::clarifyStatement() void CheckOther::clarifyStatement()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -243,7 +243,7 @@ void CheckOther::clarifyStatementError(const Token *tok)
{ {
reportError(tok, Severity::warning, "clarifyStatement", "In expression like '*A++' the result of '*' is unused. Did you intend to write '(*A)++;'?\n" reportError(tok, Severity::warning, "clarifyStatement", "In expression like '*A++' the result of '*' is unused. Did you intend to write '(*A)++;'?\n"
"A statement like '*A++;' might not do what you intended. Postfix 'operator++' is executed before 'operator*'. " "A statement like '*A++;' might not do what you intended. Postfix 'operator++' is executed before 'operator*'. "
"Thus, the dereference is meaningless. Did you intend to write '(*A)++;'?", CWE783, false); "Thus, the dereference is meaningless. Did you intend to write '(*A)++;'?", CWE783, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -251,7 +251,7 @@ void CheckOther::clarifyStatementError(const Token *tok)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckOther::checkSuspiciousSemicolon() void CheckOther::checkSuspiciousSemicolon()
{ {
if (!mSettings->inconclusive || !mSettings->isEnabled(Settings::WARNING)) if (!mSettings->certainty.isEnabled(Certainty::inconclusive) || !mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase();
@ -274,7 +274,7 @@ void CheckOther::checkSuspiciousSemicolon()
void CheckOther::suspiciousSemicolonError(const Token* tok) void CheckOther::suspiciousSemicolonError(const Token* tok)
{ {
reportError(tok, Severity::warning, "suspiciousSemicolon", reportError(tok, Severity::warning, "suspiciousSemicolon",
"Suspicious use of ; at the end of '" + (tok ? tok->str() : std::string()) + "' statement.", CWE398, false); "Suspicious use of ; at the end of '" + (tok ? tok->str() : std::string()) + "' statement.", CWE398, Certainty::normal);
} }
@ -284,7 +284,7 @@ void CheckOther::suspiciousSemicolonError(const Token* tok)
void CheckOther::warningOldStylePointerCast() void CheckOther::warningOldStylePointerCast()
{ {
// Only valid on C++ code // Only valid on C++ code
if (!mSettings->isEnabled(Settings::STYLE) || !mTokenizer->isCPP()) if (!mSettings->severity.isEnabled(Severity::style) || !mTokenizer->isCPP())
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -325,7 +325,7 @@ void CheckOther::cstyleCastError(const Token *tok)
"C-style pointer casting detected. C++ offers four different kinds of casts as replacements: " "C-style pointer casting detected. C++ offers four different kinds of casts as replacements: "
"static_cast, const_cast, dynamic_cast and reinterpret_cast. A C-style cast could evaluate to " "static_cast, const_cast, dynamic_cast and reinterpret_cast. A C-style cast could evaluate to "
"any of those automatically, thus it is considered safer if the programmer explicitly states " "any of those automatically, thus it is considered safer if the programmer explicitly states "
"which kind of cast is expected. See also: https://www.securecoding.cert.org/confluence/display/cplusplus/EXP05-CPP.+Do+not+use+C-style+casts.", CWE398, false); "which kind of cast is expected. See also: https://www.securecoding.cert.org/confluence/display/cplusplus/EXP05-CPP.+Do+not+use+C-style+casts.", CWE398, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -334,10 +334,10 @@ void CheckOther::cstyleCastError(const Token *tok)
void CheckOther::invalidPointerCast() void CheckOther::invalidPointerCast()
{ {
if (!mSettings->isEnabled(Settings::PORTABILITY)) if (!mSettings->severity.isEnabled(Severity::portability))
return; return;
const bool printInconclusive = mSettings->inconclusive; const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive);
const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope * scope : symbolDatabase->functionScopes) { for (const Scope * scope : symbolDatabase->functionScopes) {
for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) {
@ -373,9 +373,9 @@ void CheckOther::invalidPointerCast()
void CheckOther::invalidPointerCastError(const Token* tok, const std::string& from, const std::string& to, bool inconclusive, bool toIsInt) void CheckOther::invalidPointerCastError(const Token* tok, const std::string& from, const std::string& to, bool inconclusive, bool toIsInt)
{ {
if (toIsInt) { // If we cast something to int*, this can be useful to play with its binary data representation if (toIsInt) { // If we cast something to int*, this can be useful to play with its binary data representation
reportError(tok, Severity::portability, "invalidPointerCast", "Casting from " + from + " to " + to + " is not portable due to different binary data representations on different platforms.", CWE704, inconclusive); reportError(tok, Severity::portability, "invalidPointerCast", "Casting from " + from + " to " + to + " is not portable due to different binary data representations on different platforms.", CWE704, inconclusive ? Certainty::inconclusive : Certainty::normal);
} else } else
reportError(tok, Severity::portability, "invalidPointerCast", "Casting between " + from + " and " + to + " which have an incompatible binary data representation.", CWE704, false); reportError(tok, Severity::portability, "invalidPointerCast", "Casting between " + from + " and " + to + " which have an incompatible binary data representation.", CWE704, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -417,7 +417,7 @@ void CheckOther::checkPipeParameterSizeError(const Token *tok, const std::string
"$symbol:" + strVarName + "\n" "$symbol:" + strVarName + "\n"
"Buffer '$symbol' must have size of 2 integers if used as parameter of pipe().\n" "Buffer '$symbol' must have size of 2 integers if used as parameter of pipe().\n"
"The pipe()/pipe2() system command takes an argument, which is an array of exactly two integers.\n" "The pipe()/pipe2() system command takes an argument, which is an array of exactly two integers.\n"
"The variable '$symbol' is an array of size " + strDim + ", which does not match.", CWE686, false); "The variable '$symbol' is an array of size " + strDim + ", which does not match.", CWE686, Certainty::safe);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -426,7 +426,7 @@ void CheckOther::checkPipeParameterSizeError(const Token *tok, const std::string
void CheckOther::checkRedundantAssignment() void CheckOther::checkRedundantAssignment()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope *scope : symbolDatabase->functionScopes) { for (const Scope *scope : symbolDatabase->functionScopes) {
@ -490,7 +490,7 @@ void CheckOther::checkRedundantAssignment()
} }
} }
} }
if (inconclusive && !mSettings->inconclusive) if (inconclusive && !mSettings->certainty.isEnabled(Certainty::inconclusive))
continue; continue;
FwdAnalysis fwdAnalysis(mTokenizer->isCPP(), mSettings->library); FwdAnalysis fwdAnalysis(mTokenizer->isCPP(), mSettings->library);
@ -538,7 +538,7 @@ void CheckOther::redundantCopyError(const Token *tok1, const Token* tok2, const
const std::list<const Token *> callstack = { tok1, tok2 }; const std::list<const Token *> callstack = { tok1, tok2 };
reportError(callstack, Severity::performance, "redundantCopy", reportError(callstack, Severity::performance, "redundantCopy",
"$symbol:" + var + "\n" "$symbol:" + var + "\n"
"Buffer '$symbol' is being written before its old content has been used.", CWE563, false); "Buffer '$symbol' is being written before its old content has been used.", CWE563, Certainty::normal);
} }
void CheckOther::redundantCopyInSwitchError(const Token *tok1, const Token* tok2, const std::string &var) void CheckOther::redundantCopyInSwitchError(const Token *tok1, const Token* tok2, const std::string &var)
@ -546,7 +546,7 @@ void CheckOther::redundantCopyInSwitchError(const Token *tok1, const Token* tok2
const std::list<const Token *> callstack = { tok1, tok2 }; const std::list<const Token *> callstack = { tok1, tok2 };
reportError(callstack, Severity::style, "redundantCopyInSwitch", reportError(callstack, Severity::style, "redundantCopyInSwitch",
"$symbol:" + var + "\n" "$symbol:" + var + "\n"
"Buffer '$symbol' is being written before its old content has been used. 'break;' missing?", CWE563, false); "Buffer '$symbol' is being written before its old content has been used. 'break;' missing?", CWE563, Certainty::normal);
} }
void CheckOther::redundantAssignmentError(const Token *tok1, const Token* tok2, const std::string& var, bool inconclusive) void CheckOther::redundantAssignmentError(const Token *tok1, const Token* tok2, const std::string& var, bool inconclusive)
@ -556,11 +556,11 @@ void CheckOther::redundantAssignmentError(const Token *tok1, const Token* tok2,
reportError(errorPath, Severity::style, "redundantAssignment", reportError(errorPath, Severity::style, "redundantAssignment",
"$symbol:" + var + "\n" "$symbol:" + var + "\n"
"Variable '$symbol' is reassigned a value before the old one has been used if variable is no semaphore variable.\n" "Variable '$symbol' is reassigned a value before the old one has been used if variable is no semaphore variable.\n"
"Variable '$symbol' is reassigned a value before the old one has been used. Make sure that this variable is not used like a semaphore in a threading environment before simplifying this code.", CWE563, true); "Variable '$symbol' is reassigned a value before the old one has been used. Make sure that this variable is not used like a semaphore in a threading environment before simplifying this code.", CWE563, Certainty::inconclusive);
else else
reportError(errorPath, Severity::style, "redundantAssignment", reportError(errorPath, Severity::style, "redundantAssignment",
"$symbol:" + var + "\n" "$symbol:" + var + "\n"
"Variable '$symbol' is reassigned a value before the old one has been used.", CWE563, false); "Variable '$symbol' is reassigned a value before the old one has been used.", CWE563, Certainty::normal);
} }
void CheckOther::redundantInitializationError(const Token *tok1, const Token* tok2, const std::string& var, bool inconclusive) void CheckOther::redundantInitializationError(const Token *tok1, const Token* tok2, const std::string& var, bool inconclusive)
@ -569,7 +569,7 @@ void CheckOther::redundantInitializationError(const Token *tok1, const Token* to
reportError(errorPath, Severity::style, "redundantInitialization", reportError(errorPath, Severity::style, "redundantInitialization",
"$symbol:" + var + "\nRedundant initialization for '$symbol'. The initialized value is overwritten before it is read.", "$symbol:" + var + "\nRedundant initialization for '$symbol'. The initialized value is overwritten before it is read.",
CWE563, CWE563,
inconclusive); inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckOther::redundantAssignmentInSwitchError(const Token *tok1, const Token* tok2, const std::string &var) void CheckOther::redundantAssignmentInSwitchError(const Token *tok1, const Token* tok2, const std::string &var)
@ -577,7 +577,7 @@ void CheckOther::redundantAssignmentInSwitchError(const Token *tok1, const Token
const ErrorPath errorPath = { ErrorPathItem(tok1, "$symbol is assigned"), ErrorPathItem(tok2, "$symbol is overwritten") }; const ErrorPath errorPath = { ErrorPathItem(tok1, "$symbol is assigned"), ErrorPathItem(tok2, "$symbol is overwritten") };
reportError(errorPath, Severity::style, "redundantAssignInSwitch", reportError(errorPath, Severity::style, "redundantAssignInSwitch",
"$symbol:" + var + "\n" "$symbol:" + var + "\n"
"Variable '$symbol' is reassigned a value before the old one has been used. 'break;' missing?", CWE563, false); "Variable '$symbol' is reassigned a value before the old one has been used. 'break;' missing?", CWE563, Certainty::normal);
} }
@ -600,7 +600,7 @@ static inline bool isFunctionOrBreakPattern(const Token *tok)
void CheckOther::checkRedundantAssignmentInSwitch() void CheckOther::checkRedundantAssignmentInSwitch()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -727,7 +727,7 @@ void CheckOther::redundantBitwiseOperationInSwitchError(const Token *tok, const
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckOther::checkSuspiciousCaseInSwitch() void CheckOther::checkSuspiciousCaseInSwitch()
{ {
if (!mSettings->inconclusive || !mSettings->isEnabled(Settings::WARNING)) if (!mSettings->certainty.isEnabled(Certainty::inconclusive) || !mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -761,7 +761,7 @@ void CheckOther::suspiciousCaseInSwitchError(const Token* tok, const std::string
{ {
reportError(tok, Severity::warning, "suspiciousCase", reportError(tok, Severity::warning, "suspiciousCase",
"Found suspicious case label in switch(). Operator '" + operatorString + "' probably doesn't work as intended.\n" "Found suspicious case label in switch(). Operator '" + operatorString + "' probably doesn't work as intended.\n"
"Using an operator like '" + operatorString + "' in a case label is suspicious. Did you intend to use a bitwise operator, multiple case labels or if/else instead?", CWE398, true); "Using an operator like '" + operatorString + "' in a case label is suspicious. Did you intend to use a bitwise operator, multiple case labels or if/else instead?", CWE398, Certainty::inconclusive);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -772,9 +772,9 @@ void CheckOther::suspiciousCaseInSwitchError(const Token* tok, const std::string
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckOther::checkUnreachableCode() void CheckOther::checkUnreachableCode()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const bool printInconclusive = mSettings->inconclusive; const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive);
const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope * scope : symbolDatabase->functionScopes) { for (const Scope * scope : symbolDatabase->functionScopes) {
for (const Token* tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) { for (const Token* tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) {
@ -871,13 +871,13 @@ void CheckOther::duplicateBreakError(const Token *tok, bool inconclusive)
reportError(tok, Severity::style, "duplicateBreak", reportError(tok, Severity::style, "duplicateBreak",
"Consecutive return, break, continue, goto or throw statements are unnecessary.\n" "Consecutive return, break, continue, goto or throw statements are unnecessary.\n"
"Consecutive return, break, continue, goto or throw statements are unnecessary. " "Consecutive return, break, continue, goto or throw statements are unnecessary. "
"The second statement can never be executed, and so should be removed.", CWE561, inconclusive); "The second statement can never be executed, and so should be removed.", CWE561, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckOther::unreachableCodeError(const Token *tok, bool inconclusive) void CheckOther::unreachableCodeError(const Token *tok, bool inconclusive)
{ {
reportError(tok, Severity::style, "unreachableCode", reportError(tok, Severity::style, "unreachableCode",
"Statements following return, break, continue, goto or throw will never be executed.", CWE561, inconclusive); "Statements following return, break, continue, goto or throw will never be executed.", CWE561, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -888,7 +888,7 @@ void CheckOther::checkVariableScope()
if (mSettings->clang) if (mSettings->clang)
return; return;
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -1082,7 +1082,7 @@ void CheckOther::variableScopeError(const Token *tok, const std::string &varname
" }\n" " }\n"
" }\n" " }\n"
"}\n" "}\n"
"When you see this message it is always safe to reduce the variable scope 1 level.", CWE398, false); "When you see this message it is always safe to reduce the variable scope 1 level.", CWE398, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1091,10 +1091,10 @@ void CheckOther::variableScopeError(const Token *tok, const std::string &varname
void CheckOther::checkCommaSeparatedReturn() void CheckOther::checkCommaSeparatedReturn()
{ {
// This is experimental for now. See #5076 // This is experimental for now. See #5076
if (!mSettings->experimental) if (!mSettings->certainty.isEnabled(Certainty::experimental))
return; return;
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
@ -1130,7 +1130,7 @@ void CheckOther::commaSeparatedReturnError(const Token *tok)
" return a + 1,\n" " return a + 1,\n"
" b++;\n" " b++;\n"
"However it can be useful to use comma in macros. Cppcheck does not warn when such a " "However it can be useful to use comma in macros. Cppcheck does not warn when such a "
"macro is then used in a return statement, it is less likely such code is misunderstood.", CWE398, false); "macro is then used in a return statement, it is less likely such code is misunderstood.", CWE398, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1247,7 +1247,7 @@ static bool canBeConst(const Variable *var)
void CheckOther::checkPassByReference() void CheckOther::checkPassByReference()
{ {
if (!mSettings->isEnabled(Settings::PERFORMANCE) || mTokenizer->isC()) if (!mSettings->severity.isEnabled(Severity::performance) || mTokenizer->isC())
return; return;
const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase();
@ -1275,7 +1275,7 @@ void CheckOther::checkPassByReference()
} else } else
continue; continue;
if (inconclusive && !mSettings->inconclusive) if (inconclusive && !mSettings->certainty.isEnabled(Certainty::inconclusive))
continue; continue;
const bool isConst = var->isConst(); const bool isConst = var->isConst();
@ -1300,7 +1300,7 @@ void CheckOther::passedByValueError(const Token *tok, const std::string &parname
"$symbol:" + parname + "\n" "$symbol:" + parname + "\n"
"Function parameter '$symbol' should be passed by const reference.\n" "Function parameter '$symbol' should be passed by const reference.\n"
"Parameter '$symbol' is passed by value. It could be passed " "Parameter '$symbol' is passed by value. It could be passed "
"as a const reference which is usually faster and recommended in C++.", CWE398, inconclusive); "as a const reference which is usually faster and recommended in C++.", CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
static bool isUnusedVariable(const Variable *var) static bool isUnusedVariable(const Variable *var)
@ -1349,7 +1349,7 @@ static bool isVariableMutableInInitializer(const Token* start, const Token * end
void CheckOther::checkConstVariable() void CheckOther::checkConstVariable()
{ {
if (!mSettings->isEnabled(Settings::STYLE) || mTokenizer->isC()) if (!mSettings->severity.isEnabled(Severity::style) || mTokenizer->isC())
return; return;
const SymbolDatabase *const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *const symbolDatabase = mTokenizer->getSymbolDatabase();
@ -1467,7 +1467,7 @@ void CheckOther::constVariableError(const Variable *var, const Function *functio
message += ". However it seems that '" + function->name() + "' is a callback function, if '$symbol' is declared with const you might also need to cast function pointer(s)."; message += ". However it seems that '" + function->name() + "' is a callback function, if '$symbol' is declared with const you might also need to cast function pointer(s).";
} }
reportError(errorPath, Severity::style, id.c_str(), message, CWE398, false); reportError(errorPath, Severity::style, id.c_str(), message, CWE398, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1476,8 +1476,8 @@ void CheckOther::constVariableError(const Variable *var, const Function *functio
void CheckOther::checkCharVariable() void CheckOther::checkCharVariable()
{ {
const bool warning = mSettings->isEnabled(Settings::WARNING); const bool warning = mSettings->severity.isEnabled(Severity::warning);
const bool portability = mSettings->isEnabled(Settings::PORTABILITY); const bool portability = mSettings->severity.isEnabled(Severity::portability);
if (!warning && !portability) if (!warning && !portability)
return; return;
@ -1531,7 +1531,7 @@ void CheckOther::signedCharArrayIndexError(const Token *tok)
"Signed 'char' type used as array index.\n" "Signed 'char' type used as array index.\n"
"Signed 'char' type used as array index. If the value " "Signed 'char' type used as array index. If the value "
"can be greater than 127 there will be a buffer underflow " "can be greater than 127 there will be a buffer underflow "
"because of sign extension.", CWE128, false); "because of sign extension.", CWE128, Certainty::normal);
} }
void CheckOther::unknownSignCharArrayIndexError(const Token *tok) void CheckOther::unknownSignCharArrayIndexError(const Token *tok)
@ -1541,7 +1541,7 @@ void CheckOther::unknownSignCharArrayIndexError(const Token *tok)
"unknownSignCharArrayIndex", "unknownSignCharArrayIndex",
"'char' type used as array index.\n" "'char' type used as array index.\n"
"'char' type used as array index. Values greater than 127 will be " "'char' type used as array index. Values greater than 127 will be "
"treated depending on whether 'char' is signed or unsigned on target platform.", CWE758, false); "treated depending on whether 'char' is signed or unsigned on target platform.", CWE758, Certainty::normal);
} }
void CheckOther::charBitOpError(const Token *tok) void CheckOther::charBitOpError(const Token *tok)
@ -1555,7 +1555,7 @@ void CheckOther::charBitOpError(const Token *tok)
" int i = 0 | c;\n" " int i = 0 | c;\n"
" if (i & 0x8000)\n" " if (i & 0x8000)\n"
" printf(\"not expected\");\n" " printf(\"not expected\");\n"
"The \"not expected\" will be printed on the screen.", CWE398, false); "The \"not expected\" will be printed on the screen.", CWE398, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1646,7 +1646,7 @@ static bool isConstTop(const Token *tok)
void CheckOther::checkIncompleteStatement() void CheckOther::checkIncompleteStatement()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
@ -1693,7 +1693,7 @@ void CheckOther::checkIncompleteStatement()
// Possible archive // Possible archive
continue; continue;
bool inconclusive = Token::Match(tok, "%cop%"); bool inconclusive = Token::Match(tok, "%cop%");
if (mSettings->inconclusive || !inconclusive) if (mSettings->certainty.isEnabled(Certainty::inconclusive) || !inconclusive)
constStatementError(tok, tok->isNumber() ? "numeric" : "string", inconclusive); constStatementError(tok, tok->isNumber() ? "numeric" : "string", inconclusive);
} }
} }
@ -1717,7 +1717,7 @@ void CheckOther::constStatementError(const Token *tok, const std::string &type,
msg = "Redundant code: Found a statement that begins with " + type + " constant."; msg = "Redundant code: Found a statement that begins with " + type + " constant.";
else else
return; // Strange! return; // Strange!
reportError(tok, Severity::warning, "constStatement", msg, CWE398, inconclusive); reportError(tok, Severity::warning, "constStatement", msg, CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1743,8 +1743,8 @@ void CheckOther::checkZeroDivision()
void CheckOther::zerodivError(const Token *tok, const ValueFlow::Value *value) void CheckOther::zerodivError(const Token *tok, const ValueFlow::Value *value)
{ {
if (!tok && !value) { if (!tok && !value) {
reportError(tok, Severity::error, "zerodiv", "Division by zero.", CWE369, false); reportError(tok, Severity::error, "zerodiv", "Division by zero.", CWE369, Certainty::normal);
reportError(tok, Severity::error, "zerodivcond", ValueFlow::eitherTheConditionIsRedundant(nullptr) + " or there is division by zero.", CWE369, false); reportError(tok, Severity::error, "zerodivcond", ValueFlow::eitherTheConditionIsRedundant(nullptr) + " or there is division by zero.", CWE369, Certainty::normal);
return; return;
} }
@ -1761,7 +1761,7 @@ void CheckOther::zerodivError(const Token *tok, const ValueFlow::Value *value)
reportError(errorPath, reportError(errorPath,
value->errorSeverity() ? Severity::error : Severity::warning, value->errorSeverity() ? Severity::error : Severity::warning,
value->condition ? "zerodivcond" : "zerodiv", value->condition ? "zerodivcond" : "zerodiv",
errmsg.str(), CWE369, value->isInconclusive()); errmsg.str(), CWE369, value->isInconclusive() ? Certainty::inconclusive : Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1771,7 +1771,7 @@ void CheckOther::zerodivError(const Token *tok, const ValueFlow::Value *value)
void CheckOther::checkNanInArithmeticExpression() void CheckOther::checkNanInArithmeticExpression()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
if (tok->str() != "/") if (tok->str() != "/")
@ -1788,7 +1788,7 @@ void CheckOther::nanInArithmeticExpressionError(const Token *tok)
reportError(tok, Severity::style, "nanInArithmeticExpression", reportError(tok, Severity::style, "nanInArithmeticExpression",
"Using NaN/Inf in a computation.\n" "Using NaN/Inf in a computation.\n"
"Using NaN/Inf in a computation. " "Using NaN/Inf in a computation. "
"Although nothing bad really happens, it is suspicious.", CWE369, false); "Although nothing bad really happens, it is suspicious.", CWE369, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1800,7 +1800,7 @@ void CheckOther::checkMisusedScopedObject()
if (mTokenizer->isC()) if (mTokenizer->isC())
return; return;
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase();
@ -1824,7 +1824,7 @@ void CheckOther::misusedScopeObjectError(const Token *tok, const std::string& va
reportError(tok, Severity::style, reportError(tok, Severity::style,
"unusedScopedObject", "unusedScopedObject",
"$symbol:" + varname + "\n" "$symbol:" + varname + "\n"
"Instance of '$symbol' object is destroyed immediately.", CWE563, false); "Instance of '$symbol' object is destroyed immediately.", CWE563, Certainty::normal);
} }
static const Token * getSingleExpressionInBlock(const Token * tok) static const Token * getSingleExpressionInBlock(const Token * tok)
@ -1854,7 +1854,7 @@ void CheckOther::checkDuplicateBranch()
// and their conditional code is a duplicate of the condition that // and their conditional code is a duplicate of the condition that
// is always true just in case it would be false. See for instance // is always true just in case it would be false. See for instance
// abiword. // abiword.
if (!mSettings->isEnabled(Settings::STYLE) || !mSettings->inconclusive) if (!mSettings->severity.isEnabled(Severity::style) || !mSettings->certainty.isEnabled(Certainty::inconclusive))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -1915,7 +1915,7 @@ void CheckOther::duplicateBranchError(const Token *tok1, const Token *tok2, Erro
reportError(errors, Severity::style, "duplicateBranch", "Found duplicate branches for 'if' and 'else'.\n" reportError(errors, Severity::style, "duplicateBranch", "Found duplicate branches for 'if' and 'else'.\n"
"Finding the same code in an 'if' and related 'else' branch is suspicious and " "Finding the same code in an 'if' and related 'else' branch is suspicious and "
"might indicate a cut and paste or logic error. Please examine this code " "might indicate a cut and paste or logic error. Please examine this code "
"carefully to determine if it is correct.", CWE398, true); "carefully to determine if it is correct.", CWE398, Certainty::inconclusive);
} }
@ -1929,7 +1929,7 @@ void CheckOther::checkInvalidFree()
std::map<int, bool> inconclusive; std::map<int, bool> inconclusive;
std::map<int, std::string> allocation; std::map<int, std::string> allocation;
const bool printInconclusive = mSettings->inconclusive; const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive);
const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope * scope : symbolDatabase->functionScopes) { for (const Scope * scope : symbolDatabase->functionScopes) {
for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) {
@ -2001,7 +2001,7 @@ void CheckOther::invalidFreeError(const Token *tok, const std::string &allocatio
if (alloc != "new") if (alloc != "new")
alloc += "()"; alloc += "()";
std::string deallocated = (alloc == "new") ? "deleted" : "freed"; std::string deallocated = (alloc == "new") ? "deleted" : "freed";
reportError(tok, Severity::error, "invalidFree", "Mismatching address is " + deallocated + ". The address you get from " + alloc + " must be " + deallocated + " without offset.", CWE(0U), inconclusive); reportError(tok, Severity::error, "invalidFree", "Mismatching address is " + deallocated + ". The address you get from " + alloc + " must be " + deallocated + " without offset.", CWE(0U), inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
@ -2040,8 +2040,8 @@ namespace {
void CheckOther::checkDuplicateExpression() void CheckOther::checkDuplicateExpression()
{ {
const bool styleEnabled = mSettings->isEnabled(Settings::STYLE); const bool styleEnabled = mSettings->severity.isEnabled(Severity::style);
const bool warningEnabled = mSettings->isEnabled(Settings::WARNING); const bool warningEnabled = mSettings->severity.isEnabled(Severity::warning);
if (!styleEnabled && !warningEnabled) if (!styleEnabled && !warningEnabled)
return; return;
@ -2113,7 +2113,7 @@ void CheckOther::checkDuplicateExpression()
} }
if (!differentDomain && !isUniqueExpression(tok->astOperand2())) if (!differentDomain && !isUniqueExpression(tok->astOperand2()))
duplicateAssignExpressionError(var1, var2, false); duplicateAssignExpressionError(var1, var2, false);
else if (mSettings->inconclusive) else if (mSettings->certainty.isEnabled(Certainty::inconclusive))
duplicateAssignExpressionError(var1, var2, true); duplicateAssignExpressionError(var1, var2, true);
} }
} }
@ -2215,7 +2215,7 @@ void CheckOther::oppositeExpressionError(const Token *opTok, ErrorPath errors)
reportError(errors, Severity::style, "oppositeExpression", "Opposite expression on both sides of \'" + op + "\'.\n" reportError(errors, Severity::style, "oppositeExpression", "Opposite expression on both sides of \'" + op + "\'.\n"
"Finding the opposite expression on both sides of an operator is suspicious and might " "Finding the opposite expression on both sides of an operator is suspicious and might "
"indicate a cut and paste or logic error. Please examine this code carefully to " "indicate a cut and paste or logic error. Please examine this code carefully to "
"determine if it is correct.", CWE398, false); "determine if it is correct.", CWE398, Certainty::normal);
} }
void CheckOther::duplicateExpressionError(const Token *tok1, const Token *tok2, const Token *opTok, ErrorPath errors) void CheckOther::duplicateExpressionError(const Token *tok1, const Token *tok2, const Token *opTok, ErrorPath errors)
@ -2242,7 +2242,7 @@ void CheckOther::duplicateExpressionError(const Token *tok1, const Token *tok2,
reportError(errors, Severity::style, id, msg + ".\n" reportError(errors, Severity::style, id, msg + ".\n"
"Finding the same expression on both sides of an operator is suspicious and might " "Finding the same expression on both sides of an operator is suspicious and might "
"indicate a cut and paste or logic error. Please examine this code carefully to " "indicate a cut and paste or logic error. Please examine this code carefully to "
"determine if it is correct.", CWE398, false); "determine if it is correct.", CWE398, Certainty::normal);
} }
void CheckOther::duplicateAssignExpressionError(const Token *tok1, const Token *tok2, bool inconclusive) void CheckOther::duplicateAssignExpressionError(const Token *tok1, const Token *tok2, bool inconclusive)
@ -2256,7 +2256,7 @@ void CheckOther::duplicateAssignExpressionError(const Token *tok1, const Token *
"Same expression used in consecutive assignments of '" + var1 + "' and '" + var2 + "'.\n" "Same expression used in consecutive assignments of '" + var1 + "' and '" + var2 + "'.\n"
"Finding variables '" + var1 + "' and '" + var2 + "' that are assigned the same expression " "Finding variables '" + var1 + "' and '" + var2 + "' that are assigned the same expression "
"is suspicious and might indicate a cut and paste or logic error. Please examine this code carefully to " "is suspicious and might indicate a cut and paste or logic error. Please examine this code carefully to "
"determine if it is correct.", CWE398, inconclusive); "determine if it is correct.", CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckOther::duplicateExpressionTernaryError(const Token *tok, ErrorPath errors) void CheckOther::duplicateExpressionTernaryError(const Token *tok, ErrorPath errors)
@ -2264,14 +2264,14 @@ void CheckOther::duplicateExpressionTernaryError(const Token *tok, ErrorPath err
errors.emplace_back(tok, ""); errors.emplace_back(tok, "");
reportError(errors, Severity::style, "duplicateExpressionTernary", "Same expression in both branches of ternary operator.\n" reportError(errors, Severity::style, "duplicateExpressionTernary", "Same expression in both branches of ternary operator.\n"
"Finding the same expression in both branches of ternary operator is suspicious as " "Finding the same expression in both branches of ternary operator is suspicious as "
"the same code is executed regardless of the condition.", CWE398, false); "the same code is executed regardless of the condition.", CWE398, Certainty::normal);
} }
void CheckOther::duplicateValueTernaryError(const Token *tok) void CheckOther::duplicateValueTernaryError(const Token *tok)
{ {
reportError(tok, Severity::style, "duplicateValueTernary", "Same value in both branches of ternary operator.\n" reportError(tok, Severity::style, "duplicateValueTernary", "Same value in both branches of ternary operator.\n"
"Finding the same value in both branches of ternary operator is suspicious as " "Finding the same value in both branches of ternary operator is suspicious as "
"the same code is executed regardless of the condition.", CWE398, false); "the same code is executed regardless of the condition.", CWE398, Certainty::normal);
} }
void CheckOther::selfAssignmentError(const Token *tok, const std::string &varname) void CheckOther::selfAssignmentError(const Token *tok, const std::string &varname)
@ -2279,7 +2279,7 @@ void CheckOther::selfAssignmentError(const Token *tok, const std::string &varnam
reportError(tok, Severity::warning, reportError(tok, Severity::warning,
"selfAssignment", "selfAssignment",
"$symbol:" + varname + "\n" "$symbol:" + varname + "\n"
"Redundant assignment of '$symbol' to itself.", CWE398, false); "Redundant assignment of '$symbol' to itself.", CWE398, Certainty::normal);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -2293,7 +2293,7 @@ void CheckOther::selfAssignmentError(const Token *tok, const std::string &varnam
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CheckOther::checkComparisonFunctionIsAlwaysTrueOrFalse() void CheckOther::checkComparisonFunctionIsAlwaysTrueOrFalse()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -2328,7 +2328,7 @@ void CheckOther::checkComparisonFunctionIsAlwaysTrueOrFalseError(const Token* to
"$symbol:" + functionName + "\n" "$symbol:" + functionName + "\n"
"Comparison of two identical variables with $symbol(" + varName + "," + varName + ") always evaluates to " + strResult + ".\n" "Comparison of two identical variables with $symbol(" + varName + "," + varName + ") always evaluates to " + strResult + ".\n"
"The function $symbol is designed to compare two variables. Calling this function with one variable (" + varName + ") " "The function $symbol is designed to compare two variables. Calling this function with one variable (" + varName + ") "
"for both parameters leads to a statement which is always " + strResult + ".", cweResult, false); "for both parameters leads to a statement which is always " + strResult + ".", cweResult, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -2336,7 +2336,7 @@ void CheckOther::checkComparisonFunctionIsAlwaysTrueOrFalseError(const Token* to
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckOther::checkSignOfUnsignedVariable() void CheckOther::checkSignOfUnsignedVariable()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -2385,26 +2385,26 @@ void CheckOther::unsignedLessThanZeroError(const Token *tok, const ValueFlow::Va
"$symbol:" + varname + "\n" "$symbol:" + varname + "\n"
"Checking if unsigned expression '$symbol' is less than zero.\n" "Checking if unsigned expression '$symbol' is less than zero.\n"
"The unsigned expression '$symbol' will never be negative so it " "The unsigned expression '$symbol' will never be negative so it "
"is either pointless or an error to check if it is.", CWE570, false); "is either pointless or an error to check if it is.", CWE570, Certainty::normal);
} }
void CheckOther::pointerLessThanZeroError(const Token *tok, const ValueFlow::Value *v) void CheckOther::pointerLessThanZeroError(const Token *tok, const ValueFlow::Value *v)
{ {
reportError(getErrorPath(tok, v, "Pointer less than zero"), Severity::style, "pointerLessThanZero", reportError(getErrorPath(tok, v, "Pointer less than zero"), Severity::style, "pointerLessThanZero",
"A pointer can not be negative so it is either pointless or an error to check if it is.", CWE570, false); "A pointer can not be negative so it is either pointless or an error to check if it is.", CWE570, Certainty::normal);
} }
void CheckOther::unsignedPositiveError(const Token *tok, const ValueFlow::Value * v, const std::string &varname) void CheckOther::unsignedPositiveError(const Token *tok, const ValueFlow::Value * v, const std::string &varname)
{ {
reportError(getErrorPath(tok, v, "Unsigned positive"), Severity::style, "unsignedPositive", reportError(getErrorPath(tok, v, "Unsigned positive"), Severity::style, "unsignedPositive",
"$symbol:" + varname + "\n" "$symbol:" + varname + "\n"
"Unsigned expression '$symbol' can't be negative so it is unnecessary to test it.", CWE570, false); "Unsigned expression '$symbol' can't be negative so it is unnecessary to test it.", CWE570, Certainty::normal);
} }
void CheckOther::pointerPositiveError(const Token *tok, const ValueFlow::Value * v) void CheckOther::pointerPositiveError(const Token *tok, const ValueFlow::Value * v)
{ {
reportError(getErrorPath(tok, v, "Pointer positive"), Severity::style, "pointerPositive", reportError(getErrorPath(tok, v, "Pointer positive"), Severity::style, "pointerPositive",
"A pointer can not be negative so it is either pointless or an error to check if it is not.", CWE570, false); "A pointer can not be negative so it is either pointless or an error to check if it is not.", CWE570, Certainty::normal);
} }
/* check if a constructor in given class scope takes a reference */ /* check if a constructor in given class scope takes a reference */
@ -2429,7 +2429,7 @@ static bool constructorTakesReference(const Scope * const classScope)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckOther::checkRedundantCopy() void CheckOther::checkRedundantCopy()
{ {
if (!mSettings->isEnabled(Settings::PERFORMANCE) || mTokenizer->isC() || !mSettings->inconclusive) if (!mSettings->severity.isEnabled(Severity::performance) || mTokenizer->isC() || !mSettings->certainty.isEnabled(Certainty::inconclusive))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -2470,7 +2470,7 @@ void CheckOther::redundantCopyError(const Token *tok,const std::string& varname)
"The const variable '$symbol' is assigned a copy of the data. You can avoid " "The const variable '$symbol' is assigned a copy of the data. You can avoid "
"the unnecessary data copying by converting '$symbol' to const reference.", "the unnecessary data copying by converting '$symbol' to const reference.",
CWE398, CWE398,
true); // since #5618 that check became inconclusive Certainty::inconclusive); // since #5618 that check became inconclusive
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -2484,7 +2484,7 @@ static bool isNegative(const Token *tok, const Settings *settings)
void CheckOther::checkNegativeBitwiseShift() void CheckOther::checkNegativeBitwiseShift()
{ {
const bool portability = mSettings->isEnabled(Settings::PORTABILITY); const bool portability = mSettings->severity.isEnabled(Severity::portability);
for (const Token* tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token* tok = mTokenizer->tokens(); tok; tok = tok->next()) {
if (!tok->astOperand1() || !tok->astOperand2()) if (!tok->astOperand1() || !tok->astOperand2())
@ -2526,9 +2526,9 @@ void CheckOther::negativeBitwiseShiftError(const Token *tok, int op)
// LHS - this is used by intention in various software, if it // LHS - this is used by intention in various software, if it
// is used often in a project and works as expected then this is // is used often in a project and works as expected then this is
// a portability issue // a portability issue
reportError(tok, Severity::portability, "shiftNegativeLHS", "Shifting a negative value is technically undefined behaviour", CWE758, false); reportError(tok, Severity::portability, "shiftNegativeLHS", "Shifting a negative value is technically undefined behaviour", CWE758, Certainty::normal);
else // RHS else // RHS
reportError(tok, Severity::error, "shiftNegative", "Shifting by a negative value is undefined behaviour", CWE758, false); reportError(tok, Severity::error, "shiftNegative", "Shifting by a negative value is undefined behaviour", CWE758, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -2536,10 +2536,10 @@ void CheckOther::negativeBitwiseShiftError(const Token *tok, int op)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckOther::checkIncompleteArrayFill() void CheckOther::checkIncompleteArrayFill()
{ {
if (!mSettings->inconclusive) if (!mSettings->certainty.isEnabled(Certainty::inconclusive))
return; return;
const bool printWarning = mSettings->isEnabled(Settings::WARNING); const bool printWarning = mSettings->severity.isEnabled(Severity::warning);
const bool printPortability = mSettings->isEnabled(Settings::PORTABILITY); const bool printPortability = mSettings->severity.isEnabled(Severity::portability);
if (!printPortability && !printWarning) if (!printPortability && !printWarning)
return; return;
@ -2576,13 +2576,13 @@ void CheckOther::incompleteArrayFillError(const Token* tok, const std::string& b
"$symbol:" + buffer + "\n" "$symbol:" + buffer + "\n"
"$symbol:" + function + "\n" "$symbol:" + function + "\n"
"Array '" + buffer + "' might be filled incompletely. Did you forget to multiply the size given to '" + function + "()' with 'sizeof(*" + buffer + ")'?\n" "Array '" + buffer + "' might be filled incompletely. Did you forget to multiply the size given to '" + function + "()' with 'sizeof(*" + buffer + ")'?\n"
"The array '" + buffer + "' is filled incompletely. The function '" + function + "()' needs the size given in bytes, but the type 'bool' is larger than 1 on some platforms. Did you forget to multiply the size with 'sizeof(*" + buffer + ")'?", CWE131, true); "The array '" + buffer + "' is filled incompletely. The function '" + function + "()' needs the size given in bytes, but the type 'bool' is larger than 1 on some platforms. Did you forget to multiply the size with 'sizeof(*" + buffer + ")'?", CWE131, Certainty::inconclusive);
else else
reportError(tok, Severity::warning, "incompleteArrayFill", reportError(tok, Severity::warning, "incompleteArrayFill",
"$symbol:" + buffer + "\n" "$symbol:" + buffer + "\n"
"$symbol:" + function + "\n" "$symbol:" + function + "\n"
"Array '" + buffer + "' is filled incompletely. Did you forget to multiply the size given to '" + function + "()' with 'sizeof(*" + buffer + ")'?\n" "Array '" + buffer + "' is filled incompletely. Did you forget to multiply the size given to '" + function + "()' with 'sizeof(*" + buffer + ")'?\n"
"The array '" + buffer + "' is filled incompletely. The function '" + function + "()' needs the size given in bytes, but an element of the given array is larger than one byte. Did you forget to multiply the size with 'sizeof(*" + buffer + ")'?", CWE131, true); "The array '" + buffer + "' is filled incompletely. The function '" + function + "()' needs the size given in bytes, but an element of the given array is larger than one byte. Did you forget to multiply the size with 'sizeof(*" + buffer + ")'?", CWE131, Certainty::inconclusive);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -2591,7 +2591,7 @@ void CheckOther::incompleteArrayFillError(const Token* tok, const std::string& b
void CheckOther::checkVarFuncNullUB() void CheckOther::checkVarFuncNullUB()
{ {
if (!mSettings->isEnabled(Settings::PORTABILITY)) if (!mSettings->severity.isEnabled(Severity::portability))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -2669,12 +2669,12 @@ void CheckOther::varFuncNullUBError(const Token *tok)
" h();\n" " h();\n"
" g();\n" " g();\n"
" return 0;\n" " return 0;\n"
"}", CWE475, false); "}", CWE475, Certainty::normal);
} }
void CheckOther::checkRedundantPointerOp() void CheckOther::checkRedundantPointerOp()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
@ -2701,7 +2701,7 @@ void CheckOther::redundantPointerOpError(const Token* tok, const std::string &va
{ {
reportError(tok, Severity::style, "redundantPointerOp", reportError(tok, Severity::style, "redundantPointerOp",
"$symbol:" + varname + "\n" "$symbol:" + varname + "\n"
"Redundant pointer operation on '$symbol' - it's already a pointer.", CWE398, inconclusive); "Redundant pointer operation on '$symbol' - it's already a pointer.", CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckOther::checkInterlockedDecrement() void CheckOther::checkInterlockedDecrement()
@ -2745,12 +2745,12 @@ void CheckOther::checkInterlockedDecrement()
void CheckOther::raceAfterInterlockedDecrementError(const Token* tok) void CheckOther::raceAfterInterlockedDecrementError(const Token* tok)
{ {
reportError(tok, Severity::error, "raceAfterInterlockedDecrement", reportError(tok, Severity::error, "raceAfterInterlockedDecrement",
"Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead.", CWE362, false); "Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead.", CWE362, Certainty::normal);
} }
void CheckOther::checkUnusedLabel() void CheckOther::checkUnusedLabel()
{ {
if (!mSettings->isEnabled(Settings::STYLE) && !mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -2771,7 +2771,7 @@ void CheckOther::checkUnusedLabel()
void CheckOther::unusedLabelError(const Token* tok, bool inSwitch, bool hasIfdef) void CheckOther::unusedLabelError(const Token* tok, bool inSwitch, bool hasIfdef)
{ {
if (tok && !mSettings->isEnabled(inSwitch ? Settings::WARNING : Settings::STYLE)) if (tok && !mSettings->severity.isEnabled(inSwitch ? Severity::warning : Severity::style))
return; return;
std::string id = "unusedLabel"; std::string id = "unusedLabel";
@ -2791,7 +2791,7 @@ void CheckOther::unusedLabelError(const Token* tok, bool inSwitch, bool hasIfdef
id, id,
msg, msg,
CWE398, CWE398,
false); Certainty::normal);
} }
@ -2840,7 +2840,7 @@ void CheckOther::checkEvaluationOrder()
tok->str() == "=" && tok->str() == "=" &&
parent->str() == "=" && parent->str() == "=" &&
isSameExpression(mTokenizer->isCPP(), false, tok->astOperand1(), parent->astOperand1(), mSettings->library, true, false)) { isSameExpression(mTokenizer->isCPP(), false, tok->astOperand1(), parent->astOperand1(), mSettings->library, true, false)) {
if (mSettings->isEnabled(Settings::WARNING) && if (mSettings->severity.isEnabled(Severity::warning) &&
isSameExpression(mTokenizer->isCPP(), true, tok->astOperand1(), parent->astOperand1(), mSettings->library, true, false)) isSameExpression(mTokenizer->isCPP(), true, tok->astOperand1(), parent->astOperand1(), mSettings->library, true, false))
selfAssignmentError(parent, tok->astOperand1()->expressionString()); selfAssignmentError(parent, tok->astOperand1()->expressionString());
break; break;
@ -2871,15 +2871,15 @@ void CheckOther::checkEvaluationOrder()
void CheckOther::unknownEvaluationOrder(const Token* tok) void CheckOther::unknownEvaluationOrder(const Token* tok)
{ {
reportError(tok, Severity::error, "unknownEvaluationOrder", reportError(tok, Severity::error, "unknownEvaluationOrder",
"Expression '" + (tok ? tok->expressionString() : std::string("x = x++;")) + "' depends on order of evaluation of side effects", CWE768, false); "Expression '" + (tok ? tok->expressionString() : std::string("x = x++;")) + "' depends on order of evaluation of side effects", CWE768, Certainty::normal);
} }
void CheckOther::checkAccessOfMovedVariable() void CheckOther::checkAccessOfMovedVariable()
{ {
if (!mTokenizer->isCPP() || mSettings->standards.cpp < Standards::CPP11 || !mSettings->isEnabled(Settings::WARNING)) if (!mTokenizer->isCPP() || mSettings->standards.cpp < Standards::CPP11 || !mSettings->severity.isEnabled(Severity::warning))
return; return;
CheckUninitVar checkUninitVar(mTokenizer, mSettings, mErrorLogger); CheckUninitVar checkUninitVar(mTokenizer, mSettings, mErrorLogger);
const bool reportInconclusive = mSettings->inconclusive; const bool reportInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive);
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope * scope : symbolDatabase->functionScopes) { for (const Scope * scope : symbolDatabase->functionScopes) {
const Token * scopeStart = scope->bodyStart; const Token * scopeStart = scope->bodyStart;
@ -2933,8 +2933,8 @@ bool CheckOther::isMovedParameterAllowedForInconclusiveFunction(const Token * to
void CheckOther::accessMovedError(const Token *tok, const std::string &varname, const ValueFlow::Value *value, bool inconclusive) void CheckOther::accessMovedError(const Token *tok, const std::string &varname, const ValueFlow::Value *value, bool inconclusive)
{ {
if (!tok) { if (!tok) {
reportError(tok, Severity::warning, "accessMoved", "Access of moved variable 'v'.", CWE672, false); reportError(tok, Severity::warning, "accessMoved", "Access of moved variable 'v'.", CWE672, Certainty::normal);
reportError(tok, Severity::warning, "accessForwarded", "Access of forwarded variable 'v'.", CWE672, false); reportError(tok, Severity::warning, "accessForwarded", "Access of forwarded variable 'v'.", CWE672, Certainty::normal);
return; return;
} }
@ -2954,16 +2954,16 @@ void CheckOther::accessMovedError(const Token *tok, const std::string &varname,
} }
const std::string errmsg("$symbol:" + varname + "\nAccess of " + kindString + " variable '$symbol'."); const std::string errmsg("$symbol:" + varname + "\nAccess of " + kindString + " variable '$symbol'.");
const ErrorPath errorPath = getErrorPath(tok, value, errmsg); const ErrorPath errorPath = getErrorPath(tok, value, errmsg);
reportError(errorPath, Severity::warning, errorId, errmsg, CWE672, inconclusive); reportError(errorPath, Severity::warning, errorId, errmsg, CWE672, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckOther::checkFuncArgNamesDifferent() void CheckOther::checkFuncArgNamesDifferent()
{ {
const bool style = mSettings->isEnabled(Settings::STYLE); const bool style = mSettings->severity.isEnabled(Severity::style);
const bool inconclusive = mSettings->inconclusive; const bool inconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive);
const bool warning = mSettings->isEnabled(Settings::WARNING); const bool warning = mSettings->severity.isEnabled(Severity::warning);
if (!(warning || (style && inconclusive))) if (!(warning || (style && inconclusive)))
return; return;
@ -3048,7 +3048,7 @@ void CheckOther::funcArgNamesDifferent(const std::string & functionName, nonneg
"$symbol:" + functionName + "\n" "$symbol:" + functionName + "\n"
"Function '$symbol' argument " + MathLib::toString(index + 1) + " names different: declaration '" + "Function '$symbol' argument " + MathLib::toString(index + 1) + " names different: declaration '" +
(declaration ? declaration->str() : std::string("A")) + "' definition '" + (declaration ? declaration->str() : std::string("A")) + "' definition '" +
(definition ? definition->str() : std::string("B")) + "'.", CWE628, true); (definition ? definition->str() : std::string("B")) + "'.", CWE628, Certainty::inconclusive);
} }
void CheckOther::funcArgOrderDifferent(const std::string & functionName, void CheckOther::funcArgOrderDifferent(const std::string & functionName,
@ -3075,7 +3075,7 @@ void CheckOther::funcArgOrderDifferent(const std::string & functionName,
msg += definitions[i]->str(); msg += definitions[i]->str();
} }
msg += "'"; msg += "'";
reportError(tokens, Severity::warning, "funcArgOrderDifferent", msg, CWE683, false); reportError(tokens, Severity::warning, "funcArgOrderDifferent", msg, CWE683, Certainty::normal);
} }
static const Token *findShadowed(const Scope *scope, const std::string &varname, int linenr) static const Token *findShadowed(const Scope *scope, const std::string &varname, int linenr)
@ -3099,7 +3099,7 @@ static const Token *findShadowed(const Scope *scope, const std::string &varname,
void CheckOther::checkShadowVariables() void CheckOther::checkShadowVariables()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope & scope : symbolDatabase->scopeList) { for (const Scope & scope : symbolDatabase->scopeList) {
@ -3144,7 +3144,7 @@ void CheckOther::shadowError(const Token *var, const Token *shadowed, std::strin
const std::string Type = char(std::toupper(type[0])) + type.substr(1); const std::string Type = char(std::toupper(type[0])) + type.substr(1);
const std::string id = "shadow" + Type; const std::string id = "shadow" + Type;
const std::string message = "$symbol:" + varname + "\nLocal variable \'$symbol\' shadows outer " + type; const std::string message = "$symbol:" + varname + "\nLocal variable \'$symbol\' shadows outer " + type;
reportError(errorPath, Severity::style, id.c_str(), message, CWE398, false); reportError(errorPath, Severity::style, id.c_str(), message, CWE398, Certainty::normal);
} }
static bool isVariableExpression(const Token* tok) static bool isVariableExpression(const Token* tok)
@ -3162,7 +3162,7 @@ static bool isVariableExpression(const Token* tok)
void CheckOther::checkKnownArgument() void CheckOther::checkKnownArgument()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope *functionScope : symbolDatabase->functionScopes) { for (const Scope *functionScope : symbolDatabase->functionScopes) {
@ -3254,7 +3254,7 @@ void CheckOther::knownArgumentError(const Token *tok, const Token *ftok, const V
} }
const ErrorPath errorPath = getErrorPath(tok, value, errmsg); const ErrorPath errorPath = getErrorPath(tok, value, errmsg);
reportError(errorPath, Severity::style, id, errmsg, CWE570, false); reportError(errorPath, Severity::style, id, errmsg, CWE570, Certainty::normal);
} }
void CheckOther::checkComparePointers() void CheckOther::checkComparePointers()
@ -3303,12 +3303,12 @@ void CheckOther::comparePointersError(const Token *tok, const ValueFlow::Value *
} }
errorPath.emplace_back(tok, ""); errorPath.emplace_back(tok, "");
reportError( reportError(
errorPath, Severity::error, "comparePointers", verb + " pointers that point to different objects", CWE570, false); errorPath, Severity::error, "comparePointers", verb + " pointers that point to different objects", CWE570, Certainty::normal);
} }
void CheckOther::checkModuloOfOne() void CheckOther::checkModuloOfOne()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {

View File

@ -44,7 +44,7 @@ static const struct CWE CWE398(398U); // Indicator of Poor Code Quality
void CheckPostfixOperator::postfixOperator() void CheckPostfixOperator::postfixOperator()
{ {
if (!mSettings->isEnabled(Settings::PERFORMANCE)) if (!mSettings->severity.isEnabled(Severity::performance))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -82,5 +82,5 @@ void CheckPostfixOperator::postfixOperatorError(const Token *tok)
"Pre-increment/decrement can be more efficient than " "Pre-increment/decrement can be more efficient than "
"post-increment/decrement. Post-increment/decrement usually " "post-increment/decrement. Post-increment/decrement usually "
"involves keeping a copy of the previous value around and " "involves keeping a copy of the previous value around and "
"adds a little extra code.", CWE398, false); "adds a little extra code.", CWE398, Certainty::normal);
} }

View File

@ -41,7 +41,7 @@ static const struct CWE CWE682(682U); // Incorrect Calculation
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckSizeof::checkSizeofForNumericParameter() void CheckSizeof::checkSizeofForNumericParameter()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -61,7 +61,7 @@ void CheckSizeof::sizeofForNumericParameterError(const Token *tok)
"sizeofwithnumericparameter", "Suspicious usage of 'sizeof' with a numeric constant as parameter.\n" "sizeofwithnumericparameter", "Suspicious usage of 'sizeof' with a numeric constant as parameter.\n"
"It is unusual to use a constant value with sizeof. For example, 'sizeof(10)'" "It is unusual to use a constant value with sizeof. For example, 'sizeof(10)'"
" returns 4 (in 32-bit systems) or 8 (in 64-bit systems) instead of 10. 'sizeof('A')'" " returns 4 (in 32-bit systems) or 8 (in 64-bit systems) instead of 10. 'sizeof('A')'"
" and 'sizeof(char)' can return different results.", CWE682, false); " and 'sizeof(char)' can return different results.", CWE682, Certainty::normal);
} }
@ -69,7 +69,7 @@ void CheckSizeof::sizeofForNumericParameterError(const Token *tok)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckSizeof::checkSizeofForArrayParameter() void CheckSizeof::checkSizeofForArrayParameter()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope * scope : symbolDatabase->functionScopes) { for (const Scope * scope : symbolDatabase->functionScopes) {
@ -101,13 +101,13 @@ void CheckSizeof::sizeofForArrayParameterError(const Token *tok)
" return sizeof(a);\n" " return sizeof(a);\n"
" }\n" " }\n"
"returns 4 (in 32-bit systems) or 8 (in 64-bit systems) instead of 100 (the " "returns 4 (in 32-bit systems) or 8 (in 64-bit systems) instead of 100 (the "
"size of the array in bytes).", CWE467, false "size of the array in bytes).", CWE467, Certainty::normal
); );
} }
void CheckSizeof::checkSizeofForPointerSize() void CheckSizeof::checkSizeofForPointerSize()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -245,20 +245,20 @@ void CheckSizeof::sizeofForPointerError(const Token *tok, const std::string &var
"Size of pointer '" + varname + "' used instead of size of its data.\n" "Size of pointer '" + varname + "' used instead of size of its data.\n"
"Size of pointer '" + varname + "' used instead of size of its data. " "Size of pointer '" + varname + "' used instead of size of its data. "
"This is likely to lead to a buffer overflow. You probably intend to " "This is likely to lead to a buffer overflow. You probably intend to "
"write 'sizeof(*" + varname + ")'.", CWE467, false); "write 'sizeof(*" + varname + ")'.", CWE467, Certainty::normal);
} }
void CheckSizeof::divideBySizeofError(const Token *tok, const std::string &memfunc) void CheckSizeof::divideBySizeofError(const Token *tok, const std::string &memfunc)
{ {
reportError(tok, Severity::warning, "sizeofDivisionMemfunc", reportError(tok, Severity::warning, "sizeofDivisionMemfunc",
"Division by result of sizeof(). " + memfunc + "() expects a size in bytes, did you intend to multiply instead?", CWE682, false); "Division by result of sizeof(). " + memfunc + "() expects a size in bytes, did you intend to multiply instead?", CWE682, Certainty::normal);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CheckSizeof::sizeofsizeof() void CheckSizeof::sizeofsizeof()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
@ -275,17 +275,17 @@ void CheckSizeof::sizeofsizeofError(const Token *tok)
"sizeofsizeof", "Calling 'sizeof' on 'sizeof'.\n" "sizeofsizeof", "Calling 'sizeof' on 'sizeof'.\n"
"Calling sizeof for 'sizeof looks like a suspicious code and " "Calling sizeof for 'sizeof looks like a suspicious code and "
"most likely there should be just one 'sizeof'. The current " "most likely there should be just one 'sizeof'. The current "
"code is equivalent to 'sizeof(size_t)'", CWE682, false); "code is equivalent to 'sizeof(size_t)'", CWE682, Certainty::normal);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CheckSizeof::sizeofCalculation() void CheckSizeof::sizeofCalculation()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const bool printInconclusive = mSettings->inconclusive; const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive);
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
if (!Token::simpleMatch(tok, "sizeof (")) if (!Token::simpleMatch(tok, "sizeof ("))
@ -319,14 +319,14 @@ void CheckSizeof::sizeofCalculation()
void CheckSizeof::sizeofCalculationError(const Token *tok, bool inconclusive) void CheckSizeof::sizeofCalculationError(const Token *tok, bool inconclusive)
{ {
reportError(tok, Severity::warning, reportError(tok, Severity::warning,
"sizeofCalculation", "Found calculation inside sizeof().", CWE682, inconclusive); "sizeofCalculation", "Found calculation inside sizeof().", CWE682, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CheckSizeof::sizeofFunction() void CheckSizeof::sizeofFunction()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
@ -359,7 +359,7 @@ void CheckSizeof::sizeofFunction()
void CheckSizeof::sizeofFunctionError(const Token *tok) void CheckSizeof::sizeofFunctionError(const Token *tok)
{ {
reportError(tok, Severity::warning, reportError(tok, Severity::warning,
"sizeofFunctionCall", "Found function call inside sizeof().", CWE682, false); "sizeofFunctionCall", "Found function call inside sizeof().", CWE682, Certainty::normal);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -367,7 +367,7 @@ void CheckSizeof::sizeofFunctionError(const Token *tok)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CheckSizeof::suspiciousSizeofCalculation() void CheckSizeof::suspiciousSizeofCalculation()
{ {
if (!mSettings->isEnabled(Settings::WARNING) || !mSettings->inconclusive) if (!mSettings->severity.isEnabled(Severity::warning) || !mSettings->certainty.isEnabled(Certainty::inconclusive))
return; return;
// TODO: Use AST here. This should be possible as soon as sizeof without brackets is correctly parsed // TODO: Use AST here. This should be possible as soon as sizeof without brackets is correctly parsed
@ -387,7 +387,7 @@ void CheckSizeof::suspiciousSizeofCalculation()
void CheckSizeof::multiplySizeofError(const Token *tok) void CheckSizeof::multiplySizeofError(const Token *tok)
{ {
reportError(tok, Severity::warning, reportError(tok, Severity::warning,
"multiplySizeof", "Multiplying sizeof() with sizeof() indicates a logic error.", CWE682, true); "multiplySizeof", "Multiplying sizeof() with sizeof() indicates a logic error.", CWE682, Certainty::inconclusive);
} }
void CheckSizeof::divideSizeofError(const Token *tok) void CheckSizeof::divideSizeofError(const Token *tok)
@ -395,12 +395,12 @@ void CheckSizeof::divideSizeofError(const Token *tok)
reportError(tok, Severity::warning, reportError(tok, Severity::warning,
"divideSizeof", "Division of result of sizeof() on pointer type.\n" "divideSizeof", "Division of result of sizeof() on pointer type.\n"
"Division of result of sizeof() on pointer type. sizeof() returns the size of the pointer, " "Division of result of sizeof() on pointer type. sizeof() returns the size of the pointer, "
"not the size of the memory area it points to.", CWE682, true); "not the size of the memory area it points to.", CWE682, Certainty::inconclusive);
} }
void CheckSizeof::sizeofVoid() void CheckSizeof::sizeofVoid()
{ {
if (!mSettings->isEnabled(Settings::PORTABILITY)) if (!mSettings->severity.isEnabled(Severity::portability))
return; return;
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
@ -438,19 +438,19 @@ void CheckSizeof::sizeofVoidError(const Token *tok)
{ {
const std::string message = "Behaviour of 'sizeof(void)' is not covered by the ISO C standard."; const std::string message = "Behaviour of 'sizeof(void)' is not covered by the ISO C standard.";
const std::string verbose = message + " A value for 'sizeof(void)' is defined only as part of a GNU C extension, which defines 'sizeof(void)' to be 1."; const std::string verbose = message + " A value for 'sizeof(void)' is defined only as part of a GNU C extension, which defines 'sizeof(void)' to be 1.";
reportError(tok, Severity::portability, "sizeofVoid", message + "\n" + verbose, CWE682, false); reportError(tok, Severity::portability, "sizeofVoid", message + "\n" + verbose, CWE682, Certainty::normal);
} }
void CheckSizeof::sizeofDereferencedVoidPointerError(const Token *tok, const std::string &varname) void CheckSizeof::sizeofDereferencedVoidPointerError(const Token *tok, const std::string &varname)
{ {
const std::string message = "'*" + varname + "' is of type 'void', the behaviour of 'sizeof(void)' is not covered by the ISO C standard."; const std::string message = "'*" + varname + "' is of type 'void', the behaviour of 'sizeof(void)' is not covered by the ISO C standard.";
const std::string verbose = message + " A value for 'sizeof(void)' is defined only as part of a GNU C extension, which defines 'sizeof(void)' to be 1."; const std::string verbose = message + " A value for 'sizeof(void)' is defined only as part of a GNU C extension, which defines 'sizeof(void)' to be 1.";
reportError(tok, Severity::portability, "sizeofDereferencedVoidPointer", message + "\n" + verbose, CWE682, false); reportError(tok, Severity::portability, "sizeofDereferencedVoidPointer", message + "\n" + verbose, CWE682, Certainty::normal);
} }
void CheckSizeof::arithOperationsOnVoidPointerError(const Token* tok, const std::string &varname, const std::string &vartype) void CheckSizeof::arithOperationsOnVoidPointerError(const Token* tok, const std::string &varname, const std::string &vartype)
{ {
const std::string message = "'$symbol' is of type '" + vartype + "'. When using void pointers in calculations, the behaviour is undefined."; const std::string message = "'$symbol' is of type '" + vartype + "'. When using void pointers in calculations, the behaviour is undefined.";
const std::string verbose = message + " Arithmetic operations on 'void *' is a GNU C extension, which defines the 'sizeof(void)' to be 1."; const std::string verbose = message + " Arithmetic operations on 'void *' is a GNU C extension, which defines the 'sizeof(void)' to be 1.";
reportError(tok, Severity::portability, "arithOperationsOnVoidPointer", "$symbol:" + varname + '\n' + message + '\n' + verbose, CWE467, false); reportError(tok, Severity::portability, "arithOperationsOnVoidPointer", "$symbol:" + varname + '\n' + message + '\n' + verbose, CWE467, Certainty::normal);
} }

View File

@ -80,9 +80,9 @@ void CheckStl::outOfBounds()
continue; continue;
if (value.isImpossible()) if (value.isImpossible())
continue; continue;
if (value.isInconclusive() && !mSettings->inconclusive) if (value.isInconclusive() && !mSettings->certainty.isEnabled(Certainty::inconclusive))
continue; continue;
if (!value.errorSeverity() && !mSettings->isEnabled(Settings::WARNING)) if (!value.errorSeverity() && !mSettings->severity.isEnabled(Severity::warning))
continue; continue;
if (Token::Match(parent, ". %name% (") && isElementAccessYield(container->getYield(parent->strAt(1)))) { if (Token::Match(parent, ". %name% (") && isElementAccessYield(container->getYield(parent->strAt(1)))) {
if (value.intvalue == 0) { if (value.intvalue == 0) {
@ -98,7 +98,7 @@ void CheckStl::outOfBounds()
parent, tok->expressionString(), &value, indexTok->expressionString(), indexValue); parent, tok->expressionString(), &value, indexTok->expressionString(), indexValue);
continue; continue;
} }
if (mSettings->isEnabled(Settings::WARNING)) { if (mSettings->severity.isEnabled(Severity::warning)) {
indexValue = indexTok->getMaxValue(true); indexValue = indexTok->getMaxValue(true);
if (indexValue && indexValue->intvalue >= value.intvalue) { if (indexValue && indexValue->intvalue >= value.intvalue) {
outOfBoundsError( outOfBoundsError(
@ -134,7 +134,7 @@ void CheckStl::outOfBounds()
outOfBoundsError(parent, tok->expressionString(), &value, parent->astOperand2()->expressionString(), indexValue); outOfBoundsError(parent, tok->expressionString(), &value, parent->astOperand2()->expressionString(), indexValue);
continue; continue;
} }
if (mSettings->isEnabled(Settings::WARNING)) { if (mSettings->severity.isEnabled(Severity::warning)) {
indexValue = parent->astOperand2() ? parent->astOperand2()->getMaxValue(true) : nullptr; indexValue = parent->astOperand2() ? parent->astOperand2()->getMaxValue(true) : nullptr;
if (indexValue && indexValue->intvalue >= value.intvalue) { if (indexValue && indexValue->intvalue >= value.intvalue) {
outOfBoundsError(parent, tok->expressionString(), &value, parent->astOperand2()->expressionString(), indexValue); outOfBoundsError(parent, tok->expressionString(), &value, parent->astOperand2()->expressionString(), indexValue);
@ -207,7 +207,7 @@ void CheckStl::outOfBoundsError(const Token *tok, const std::string &containerNa
"containerOutOfBounds", "containerOutOfBounds",
"$symbol:" + containerName +"\n" + errmsg, "$symbol:" + containerName +"\n" + errmsg,
CWE398, CWE398,
(containerSize && containerSize->isInconclusive()) || (indexValue && indexValue->isInconclusive())); (containerSize && containerSize->isInconclusive()) || (indexValue && indexValue->isInconclusive()) ? Certainty::inconclusive : Certainty::normal);
} }
bool CheckStl::isContainerSize(const Token *containerToken, const Token *expr) const bool CheckStl::isContainerSize(const Token *containerToken, const Token *expr) const
@ -281,7 +281,7 @@ void CheckStl::outOfBoundsIndexExpressionError(const Token *tok, const Token *in
"containerOutOfBoundsIndexExpression", "containerOutOfBoundsIndexExpression",
"$symbol:" + varname +"\n" + errmsg, "$symbol:" + varname +"\n" + errmsg,
CWE398, CWE398,
false); Certainty::normal);
} }
@ -289,7 +289,7 @@ void CheckStl::outOfBoundsIndexExpressionError(const Token *tok, const Token *in
// Error message for bad iterator usage.. // Error message for bad iterator usage..
void CheckStl::invalidIteratorError(const Token *tok, const std::string &iteratorName) void CheckStl::invalidIteratorError(const Token *tok, const std::string &iteratorName)
{ {
reportError(tok, Severity::error, "invalidIterator1", "$symbol:"+iteratorName+"\nInvalid iterator: $symbol", CWE664, false); reportError(tok, Severity::error, "invalidIterator1", "$symbol:"+iteratorName+"\nInvalid iterator: $symbol", CWE664, Certainty::normal);
} }
void CheckStl::iteratorsError(const Token* tok, const std::string& containerName1, const std::string& containerName2) void CheckStl::iteratorsError(const Token* tok, const std::string& containerName1, const std::string& containerName2)
@ -297,7 +297,7 @@ void CheckStl::iteratorsError(const Token* tok, const std::string& containerName
reportError(tok, Severity::error, "iterators1", reportError(tok, Severity::error, "iterators1",
"$symbol:" + containerName1 + "\n" "$symbol:" + containerName1 + "\n"
"$symbol:" + containerName2 + "\n" "$symbol:" + containerName2 + "\n"
"Same iterator is used with different containers '" + containerName1 + "' and '" + containerName2 + "'.", CWE664, false); "Same iterator is used with different containers '" + containerName1 + "' and '" + containerName2 + "'.", CWE664, Certainty::normal);
} }
void CheckStl::iteratorsError(const Token* tok, const Token* containerTok, const std::string& containerName1, const std::string& containerName2) void CheckStl::iteratorsError(const Token* tok, const Token* containerTok, const std::string& containerName1, const std::string& containerName2)
@ -306,7 +306,7 @@ void CheckStl::iteratorsError(const Token* tok, const Token* containerTok, const
reportError(callstack, Severity::error, "iterators2", reportError(callstack, Severity::error, "iterators2",
"$symbol:" + containerName1 + "\n" "$symbol:" + containerName1 + "\n"
"$symbol:" + containerName2 + "\n" "$symbol:" + containerName2 + "\n"
"Same iterator is used with different containers '" + containerName1 + "' and '" + containerName2 + "'.", CWE664, false); "Same iterator is used with different containers '" + containerName1 + "' and '" + containerName2 + "'.", CWE664, Certainty::normal);
} }
void CheckStl::iteratorsError(const Token* tok, const Token* containerTok, const std::string& containerName) void CheckStl::iteratorsError(const Token* tok, const Token* containerTok, const std::string& containerName)
@ -314,7 +314,7 @@ void CheckStl::iteratorsError(const Token* tok, const Token* containerTok, const
std::list<const Token*> callstack = { tok, containerTok }; std::list<const Token*> callstack = { tok, containerTok };
reportError(callstack, Severity::error, "iterators3", reportError(callstack, Severity::error, "iterators3",
"$symbol:" + containerName + "\n" "$symbol:" + containerName + "\n"
"Same iterator is used with containers '" + containerName + "' that are defined in different scopes.", CWE664, false); "Same iterator is used with containers '" + containerName + "' that are defined in different scopes.", CWE664, Certainty::normal);
} }
// Error message used when dereferencing an iterator that has been erased.. // Error message used when dereferencing an iterator that has been erased..
@ -326,13 +326,13 @@ void CheckStl::dereferenceErasedError(const Token *erased, const Token* deref, c
"$symbol:" + itername + "\n" "$symbol:" + itername + "\n"
"Iterator '$symbol' used after element has been erased.\n" "Iterator '$symbol' used after element has been erased.\n"
"The iterator '$symbol' is invalid after the element it pointed to has been erased. " "The iterator '$symbol' is invalid after the element it pointed to has been erased. "
"Dereferencing or comparing it with another iterator is invalid operation.", CWE664, inconclusive); "Dereferencing or comparing it with another iterator is invalid operation.", CWE664, inconclusive ? Certainty::inconclusive : Certainty::normal);
} else { } else {
reportError(deref, Severity::error, "eraseDereference", reportError(deref, Severity::error, "eraseDereference",
"$symbol:" + itername + "\n" "$symbol:" + itername + "\n"
"Invalid iterator '$symbol' used.\n" "Invalid iterator '$symbol' used.\n"
"The iterator '$symbol' is invalid before being assigned. " "The iterator '$symbol' is invalid before being assigned. "
"Dereferencing or comparing it with another iterator is invalid operation.", CWE664, inconclusive); "Dereferencing or comparing it with another iterator is invalid operation.", CWE664, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
} }
@ -413,7 +413,7 @@ void CheckStl::iterators()
bool inconclusiveType=false; bool inconclusiveType=false;
if (!isIterator(var, inconclusiveType)) if (!isIterator(var, inconclusiveType))
continue; continue;
if (inconclusiveType && !mSettings->inconclusive) if (inconclusiveType && !mSettings->certainty.isEnabled(Certainty::inconclusive))
continue; continue;
const int iteratorId = var->declarationId(); const int iteratorId = var->declarationId();
@ -586,7 +586,7 @@ void CheckStl::mismatchingContainerIteratorError(const Token* tok, const Token*
"mismatchingContainerIterator", "mismatchingContainerIterator",
"Iterator '" + iter + "' from different container '" + container + "' are used together.", "Iterator '" + iter + "' from different container '" + container + "' are used together.",
CWE664, CWE664,
false); Certainty::normal);
} }
// Error message for bad iterator usage.. // Error message for bad iterator usage..
@ -599,7 +599,7 @@ void CheckStl::mismatchingContainersError(const Token* tok1, const Token* tok2)
"mismatchingContainers", "mismatchingContainers",
"Iterators of different containers '" + expr1 + "' and '" + expr2 + "' are used together.", "Iterators of different containers '" + expr1 + "' and '" + expr2 + "' are used together.",
CWE664, CWE664,
false); Certainty::normal);
} }
void CheckStl::mismatchingContainerExpressionError(const Token *tok1, const Token *tok2) void CheckStl::mismatchingContainerExpressionError(const Token *tok1, const Token *tok2)
@ -608,12 +608,12 @@ void CheckStl::mismatchingContainerExpressionError(const Token *tok1, const Toke
const std::string expr2(tok2 ? tok2->expressionString() : std::string("v2")); const std::string expr2(tok2 ? tok2->expressionString() : std::string("v2"));
reportError(tok1, Severity::warning, "mismatchingContainerExpression", reportError(tok1, Severity::warning, "mismatchingContainerExpression",
"Iterators to containers from different expressions '" + "Iterators to containers from different expressions '" +
expr1 + "' and '" + expr2 + "' are used together.", CWE664, false); expr1 + "' and '" + expr2 + "' are used together.", CWE664, Certainty::normal);
} }
void CheckStl::sameIteratorExpressionError(const Token *tok) void CheckStl::sameIteratorExpressionError(const Token *tok)
{ {
reportError(tok, Severity::style, "sameIteratorExpression", "Same iterators expression are used for algorithm.", CWE664, false); reportError(tok, Severity::style, "sameIteratorExpression", "Same iterators expression are used for algorithm.", CWE664, Certainty::normal);
} }
static const std::set<std::string> algorithm2 = { // func(begin1, end1 static const std::set<std::string> algorithm2 = { // func(begin1, end1
@ -1102,7 +1102,7 @@ void CheckStl::invalidContainerLoopError(const Token *tok, const Token * loopTok
const std::string msg = "Calling '" + method + "' while iterating the container is invalid."; const std::string msg = "Calling '" + method + "' while iterating the container is invalid.";
errorPath.emplace_back(tok, ""); errorPath.emplace_back(tok, "");
reportError(errorPath, Severity::error, "invalidContainerLoop", msg, CWE664, false); reportError(errorPath, Severity::error, "invalidContainerLoop", msg, CWE664, Certainty::normal);
} }
void CheckStl::invalidContainerError(const Token *tok, const Token * /*contTok*/, const ValueFlow::Value *val, ErrorPath errorPath) void CheckStl::invalidContainerError(const Token *tok, const Token * /*contTok*/, const ValueFlow::Value *val, ErrorPath errorPath)
@ -1112,7 +1112,7 @@ void CheckStl::invalidContainerError(const Token *tok, const Token * /*contTok*/
errorPath.insert(errorPath.begin(), val->errorPath.begin(), val->errorPath.end()); errorPath.insert(errorPath.begin(), val->errorPath.begin(), val->errorPath.end());
std::string msg = "Using " + lifetimeMessage(tok, val, errorPath); std::string msg = "Using " + lifetimeMessage(tok, val, errorPath);
errorPath.emplace_back(tok, ""); errorPath.emplace_back(tok, "");
reportError(errorPath, Severity::error, "invalidContainer", msg + " that may be invalid.", CWE664, inconclusive); reportError(errorPath, Severity::error, "invalidContainer", msg + " that may be invalid.", CWE664, inconclusive ? Certainty::inconclusive : Certainty::normal);
} }
void CheckStl::invalidContainerReferenceError(const Token* tok, const Token* contTok, ErrorPath errorPath) void CheckStl::invalidContainerReferenceError(const Token* tok, const Token* contTok, ErrorPath errorPath)
@ -1120,7 +1120,7 @@ void CheckStl::invalidContainerReferenceError(const Token* tok, const Token* con
std::string name = contTok ? contTok->expressionString() : "x"; std::string name = contTok ? contTok->expressionString() : "x";
std::string msg = "Reference to " + name; std::string msg = "Reference to " + name;
errorPath.emplace_back(tok, ""); errorPath.emplace_back(tok, "");
reportError(errorPath, Severity::error, "invalidContainerReference", msg + " that may be invalid.", CWE664, false); reportError(errorPath, Severity::error, "invalidContainerReference", msg + " that may be invalid.", CWE664, Certainty::normal);
} }
void CheckStl::stlOutOfBounds() void CheckStl::stlOutOfBounds()
@ -1207,9 +1207,9 @@ void CheckStl::stlOutOfBounds()
void CheckStl::stlOutOfBoundsError(const Token *tok, const std::string &num, const std::string &var, bool at) void CheckStl::stlOutOfBoundsError(const Token *tok, const std::string &num, const std::string &var, bool at)
{ {
if (at) if (at)
reportError(tok, Severity::error, "stlOutOfBounds", "$symbol:" + var + "\nWhen " + num + "==$symbol.size(), $symbol.at(" + num + ") is out of bounds.", CWE788, false); reportError(tok, Severity::error, "stlOutOfBounds", "$symbol:" + var + "\nWhen " + num + "==$symbol.size(), $symbol.at(" + num + ") is out of bounds.", CWE788, Certainty::normal);
else else
reportError(tok, Severity::error, "stlOutOfBounds", "$symbol:" + var + "\nWhen " + num + "==$symbol.size(), $symbol[" + num + "] is out of bounds.", CWE788, false); reportError(tok, Severity::error, "stlOutOfBounds", "$symbol:" + var + "\nWhen " + num + "==$symbol.size(), $symbol[" + num + "] is out of bounds.", CWE788, Certainty::normal);
} }
void CheckStl::negativeIndex() void CheckStl::negativeIndex()
@ -1243,7 +1243,7 @@ void CheckStl::negativeIndexError(const Token *tok, const ValueFlow::Value &inde
<< ", otherwise there is negative array index " << index.intvalue << "."; << ", otherwise there is negative array index " << index.intvalue << ".";
else else
errmsg << "Array index " << index.intvalue << " is out of bounds."; errmsg << "Array index " << index.intvalue << " is out of bounds.";
reportError(errorPath, index.errorSeverity() ? Severity::error : Severity::warning, "negativeContainerIndex", errmsg.str(), CWE786, index.isInconclusive()); reportError(errorPath, index.errorSeverity() ? Severity::error : Severity::warning, "negativeContainerIndex", errmsg.str(), CWE786, index.isInconclusive() ? Certainty::inconclusive : Certainty::normal);
} }
void CheckStl::erase() void CheckStl::erase()
@ -1337,7 +1337,7 @@ void CheckStl::stlBoundariesError(const Token *tok)
reportError(tok, Severity::error, "stlBoundaries", reportError(tok, Severity::error, "stlBoundaries",
"Dangerous comparison using operator< on iterator.\n" "Dangerous comparison using operator< on iterator.\n"
"Iterator compared with operator<. This is dangerous since the order of items in the " "Iterator compared with operator<. This is dangerous since the order of items in the "
"container is not guaranteed. One should use operator!= instead to compare iterators.", CWE664, false); "container is not guaranteed. One should use operator!= instead to compare iterators.", CWE664, Certainty::normal);
} }
static bool if_findCompare(const Token * const tokBack, bool stdStringLike) static bool if_findCompare(const Token * const tokBack, bool stdStringLike)
@ -1363,8 +1363,8 @@ static bool if_findCompare(const Token * const tokBack, bool stdStringLike)
void CheckStl::if_find() void CheckStl::if_find()
{ {
const bool printWarning = mSettings->isEnabled(Settings::WARNING); const bool printWarning = mSettings->severity.isEnabled(Severity::warning);
const bool printPerformance = mSettings->isEnabled(Settings::PERFORMANCE); const bool printPerformance = mSettings->severity.isEnabled(Severity::performance);
if (!printWarning && !printPerformance) if (!printWarning && !printPerformance)
return; return;
@ -1442,9 +1442,9 @@ void CheckStl::if_findError(const Token *tok, bool str)
"Either inefficient or wrong usage of string::find(). string::starts_with() will be faster if " "Either inefficient or wrong usage of string::find(). string::starts_with() will be faster if "
"string::find's result is compared with 0, because it will not scan the whole " "string::find's result is compared with 0, because it will not scan the whole "
"string. If your intention is to check that there are no findings in the string, " "string. If your intention is to check that there are no findings in the string, "
"you should compare with std::string::npos.", CWE597, false); "you should compare with std::string::npos.", CWE597, Certainty::normal);
if (!str) if (!str)
reportError(tok, Severity::warning, "stlIfFind", "Suspicious condition. The result of find() is an iterator, but it is not properly checked.", CWE398, false); reportError(tok, Severity::warning, "stlIfFind", "Suspicious condition. The result of find() is an iterator, but it is not properly checked.", CWE398, Certainty::normal);
} }
static std::pair<const Token *, const Token *> isMapFind(const Token *tok) static std::pair<const Token *, const Token *> isMapFind(const Token *tok)
@ -1545,7 +1545,7 @@ static const Token *findInsertValue(const Token *tok, const Token *containerTok,
void CheckStl::checkFindInsert() void CheckStl::checkFindInsert()
{ {
if (!mSettings->isEnabled(Settings::PERFORMANCE)) if (!mSettings->severity.isEnabled(Severity::performance))
return; return;
const SymbolDatabase *const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *const symbolDatabase = mTokenizer->getSymbolDatabase();
@ -1590,7 +1590,7 @@ void CheckStl::checkFindInsert()
void CheckStl::checkFindInsertError(const Token *tok) void CheckStl::checkFindInsertError(const Token *tok)
{ {
reportError( reportError(
tok, Severity::performance, "stlFindInsert", "Searching before insertion is not necessary.", CWE398, false); tok, Severity::performance, "stlFindInsert", "Searching before insertion is not necessary.", CWE398, Certainty::normal);
} }
/** /**
@ -1606,7 +1606,7 @@ static bool isCpp03ContainerSizeSlow(const Token *tok)
void CheckStl::size() void CheckStl::size()
{ {
if (!mSettings->isEnabled(Settings::PERFORMANCE)) if (!mSettings->severity.isEnabled(Severity::performance))
return; return;
if (mSettings->standards.cpp >= Standards::CPP11) if (mSettings->standards.cpp >= Standards::CPP11)
@ -1660,12 +1660,12 @@ void CheckStl::sizeError(const Token *tok)
"Checking for '$symbol' emptiness might be inefficient. " "Checking for '$symbol' emptiness might be inefficient. "
"Using $symbol.empty() instead of $symbol.size() can be faster. " "Using $symbol.empty() instead of $symbol.size() can be faster. "
"$symbol.size() can take linear time but $symbol.empty() is " "$symbol.size() can take linear time but $symbol.empty() is "
"guaranteed to take constant time.", CWE398, false); "guaranteed to take constant time.", CWE398, Certainty::normal);
} }
void CheckStl::redundantCondition() void CheckStl::redundantCondition()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -1699,12 +1699,12 @@ void CheckStl::redundantIfRemoveError(const Token *tok)
reportError(tok, Severity::style, "redundantIfRemove", reportError(tok, Severity::style, "redundantIfRemove",
"Redundant checking of STL container element existence before removing it.\n" "Redundant checking of STL container element existence before removing it.\n"
"Redundant checking of STL container element existence before removing it. " "Redundant checking of STL container element existence before removing it. "
"It is safe to call the remove method on a non-existing element.", CWE398, false); "It is safe to call the remove method on a non-existing element.", CWE398, Certainty::normal);
} }
void CheckStl::missingComparison() void CheckStl::missingComparison()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase();
@ -1780,7 +1780,7 @@ void CheckStl::missingComparisonError(const Token *incrementToken1, const Token
<< "There is no comparison between these increments to prevent that the iterator is " << "There is no comparison between these increments to prevent that the iterator is "
<< "incremented beyond the end."; << "incremented beyond the end.";
reportError(callstack, Severity::warning, "StlMissingComparison", errmsg.str(), CWE834, false); reportError(callstack, Severity::warning, "StlMissingComparison", errmsg.str(), CWE834, Certainty::normal);
} }
@ -1798,8 +1798,8 @@ namespace {
void CheckStl::string_c_str() void CheckStl::string_c_str()
{ {
const bool printInconclusive = mSettings->inconclusive; const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive);
const bool printPerformance = mSettings->isEnabled(Settings::PERFORMANCE); const bool printPerformance = mSettings->severity.isEnabled(Severity::performance);
const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase();
@ -1972,13 +1972,13 @@ void CheckStl::string_c_strThrowError(const Token* tok)
void CheckStl::string_c_strError(const Token* tok) void CheckStl::string_c_strError(const Token* tok)
{ {
reportError(tok, Severity::error, "stlcstr", "Dangerous usage of c_str(). The value returned by c_str() is invalid after this call.\n" reportError(tok, Severity::error, "stlcstr", "Dangerous usage of c_str(). The value returned by c_str() is invalid after this call.\n"
"Dangerous usage of c_str(). The c_str() return value is only valid until its string is deleted.", CWE664, false); "Dangerous usage of c_str(). The c_str() return value is only valid until its string is deleted.", CWE664, Certainty::normal);
} }
void CheckStl::string_c_strReturn(const Token* tok) void CheckStl::string_c_strReturn(const Token* tok)
{ {
reportError(tok, Severity::performance, "stlcstrReturn", "Returning the result of c_str() in a function that returns std::string is slow and redundant.\n" reportError(tok, Severity::performance, "stlcstrReturn", "Returning the result of c_str() in a function that returns std::string is slow and redundant.\n"
"The conversion from const char* as returned by c_str() to std::string creates an unnecessary string copy. Solve that by directly returning the string.", CWE704, false); "The conversion from const char* as returned by c_str() to std::string creates an unnecessary string copy. Solve that by directly returning the string.", CWE704, Certainty::normal);
} }
void CheckStl::string_c_strParam(const Token* tok, nonneg int number) void CheckStl::string_c_strParam(const Token* tok, nonneg int number)
@ -1986,7 +1986,7 @@ void CheckStl::string_c_strParam(const Token* tok, nonneg int number)
std::ostringstream oss; std::ostringstream oss;
oss << "Passing the result of c_str() to a function that takes std::string as argument no. " << number << " is slow and redundant.\n" oss << "Passing the result of c_str() to a function that takes std::string as argument no. " << number << " is slow and redundant.\n"
"The conversion from const char* as returned by c_str() to std::string creates an unnecessary string copy. Solve that by directly passing the string."; "The conversion from const char* as returned by c_str() to std::string creates an unnecessary string copy. Solve that by directly passing the string.";
reportError(tok, Severity::performance, "stlcstrParam", oss.str(), CWE704, false); reportError(tok, Severity::performance, "stlcstrParam", oss.str(), CWE704, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -2005,8 +2005,8 @@ namespace {
void CheckStl::uselessCalls() void CheckStl::uselessCalls()
{ {
const bool printPerformance = mSettings->isEnabled(Settings::PERFORMANCE); const bool printPerformance = mSettings->severity.isEnabled(Severity::performance);
const bool printWarning = mSettings->isEnabled(Settings::WARNING); const bool printWarning = mSettings->severity.isEnabled(Severity::warning);
if (!printPerformance && !printWarning) if (!printPerformance && !printWarning)
return; return;
@ -2055,7 +2055,7 @@ void CheckStl::uselessCallsReturnValueError(const Token *tok, const std::string
<< "(" << varname << "." << function << "(" << varname << ")). As it is currently the " << "(" << varname << "." << function << "(" << varname << ")). As it is currently the "
<< "code is inefficient. It is possible either the string searched ('" << "code is inefficient. It is possible either the string searched ('"
<< varname << "') or searched for ('" << varname << "') is wrong."; << varname << "') or searched for ('" << varname << "') is wrong.";
reportError(tok, Severity::warning, "uselessCallsCompare", errmsg.str(), CWE628, false); reportError(tok, Severity::warning, "uselessCallsCompare", errmsg.str(), CWE628, Certainty::normal);
} }
void CheckStl::uselessCallsSwapError(const Token *tok, const std::string &varname) void CheckStl::uselessCallsSwapError(const Token *tok, const std::string &varname)
@ -2065,20 +2065,20 @@ void CheckStl::uselessCallsSwapError(const Token *tok, const std::string &varnam
"It is inefficient to swap a object with itself by calling '$symbol.swap($symbol)'\n" "It is inefficient to swap a object with itself by calling '$symbol.swap($symbol)'\n"
"The 'swap()' function has no logical effect when given itself as parameter " "The 'swap()' function has no logical effect when given itself as parameter "
"($symbol.swap($symbol)). As it is currently the " "($symbol.swap($symbol)). As it is currently the "
"code is inefficient. Is the object or the parameter wrong here?", CWE628, false); "code is inefficient. Is the object or the parameter wrong here?", CWE628, Certainty::normal);
} }
void CheckStl::uselessCallsSubstrError(const Token *tok, bool empty) void CheckStl::uselessCallsSubstrError(const Token *tok, bool empty)
{ {
if (empty) if (empty)
reportError(tok, Severity::performance, "uselessCallsSubstr", "Ineffective call of function 'substr' because it returns an empty string.", CWE398, false); reportError(tok, Severity::performance, "uselessCallsSubstr", "Ineffective call of function 'substr' because it returns an empty string.", CWE398, Certainty::normal);
else else
reportError(tok, Severity::performance, "uselessCallsSubstr", "Ineffective call of function 'substr' because it returns a copy of the object. Use operator= instead.", CWE398, false); reportError(tok, Severity::performance, "uselessCallsSubstr", "Ineffective call of function 'substr' because it returns a copy of the object. Use operator= instead.", CWE398, Certainty::normal);
} }
void CheckStl::uselessCallsEmptyError(const Token *tok) void CheckStl::uselessCallsEmptyError(const Token *tok)
{ {
reportError(tok, Severity::warning, "uselessCallsEmpty", "Ineffective call of function 'empty()'. Did you intend to call 'clear()' instead?", CWE398, false); reportError(tok, Severity::warning, "uselessCallsEmpty", "Ineffective call of function 'empty()'. Did you intend to call 'clear()' instead?", CWE398, Certainty::normal);
} }
void CheckStl::uselessCallsRemoveError(const Token *tok, const std::string& function) void CheckStl::uselessCallsRemoveError(const Token *tok, const std::string& function)
@ -2087,14 +2087,14 @@ void CheckStl::uselessCallsRemoveError(const Token *tok, const std::string& func
"$symbol:" + function + "\n" "$symbol:" + function + "\n"
"Return value of std::$symbol() ignored. Elements remain in container.\n" "Return value of std::$symbol() ignored. Elements remain in container.\n"
"The return value of std::$symbol() is ignored. This function returns an iterator to the end of the range containing those elements that should be kept. " "The return value of std::$symbol() is ignored. This function returns an iterator to the end of the range containing those elements that should be kept. "
"Elements past new end remain valid but with unspecified values. Use the erase method of the container to delete them.", CWE762, false); "Elements past new end remain valid but with unspecified values. Use the erase method of the container to delete them.", CWE762, Certainty::normal);
} }
// Check for iterators being dereferenced before being checked for validity. // Check for iterators being dereferenced before being checked for validity.
// E.g. if (*i && i != str.end()) { } // E.g. if (*i && i != str.end()) { }
void CheckStl::checkDereferenceInvalidIterator() void CheckStl::checkDereferenceInvalidIterator()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
// Iterate over "if", "while", and "for" conditions where there may // Iterate over "if", "while", and "for" conditions where there may
@ -2156,7 +2156,7 @@ void CheckStl::checkDereferenceInvalidIterator()
void CheckStl::checkDereferenceInvalidIterator2() void CheckStl::checkDereferenceInvalidIterator2()
{ {
const bool printInconclusive = (mSettings->inconclusive); const bool printInconclusive = (mSettings->certainty.isEnabled(Certainty::inconclusive));
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
if (Token::Match(tok, "sizeof|decltype|typeid|typeof (")) { if (Token::Match(tok, "sizeof|decltype|typeid|typeof (")) {
@ -2218,8 +2218,8 @@ void CheckStl::dereferenceInvalidIteratorError(const Token* tok, const ValueFlow
const std::string& varname = tok ? tok->expressionString() : "var"; const std::string& varname = tok ? tok->expressionString() : "var";
const std::string errmsgcond("$symbol:" + varname + '\n' + ValueFlow::eitherTheConditionIsRedundant(value ? value->condition : nullptr) + " or there is possible dereference of an invalid iterator: $symbol."); const std::string errmsgcond("$symbol:" + varname + '\n' + ValueFlow::eitherTheConditionIsRedundant(value ? value->condition : nullptr) + " or there is possible dereference of an invalid iterator: $symbol.");
if (!tok || !value) { if (!tok || !value) {
reportError(tok, Severity::error, "derefInvalidIterator", "Dereference of an invalid iterator", CWE825, false); reportError(tok, Severity::error, "derefInvalidIterator", "Dereference of an invalid iterator", CWE825, Certainty::normal);
reportError(tok, Severity::warning, "derefInvalidIteratorRedundantCheck", errmsgcond, CWE825, false); reportError(tok, Severity::warning, "derefInvalidIteratorRedundantCheck", errmsgcond, CWE825, Certainty::normal);
return; return;
} }
if (!mSettings->isEnabled(value, inconclusive)) if (!mSettings->isEnabled(value, inconclusive))
@ -2228,7 +2228,7 @@ void CheckStl::dereferenceInvalidIteratorError(const Token* tok, const ValueFlow
const ErrorPath errorPath = getErrorPath(tok, value, "Dereference of an invalid iterator"); const ErrorPath errorPath = getErrorPath(tok, value, "Dereference of an invalid iterator");
if (value->condition) { if (value->condition) {
reportError(errorPath, Severity::warning, "derefInvalidIteratorRedundantCheck", errmsgcond, CWE825, inconclusive || value->isInconclusive()); reportError(errorPath, Severity::warning, "derefInvalidIteratorRedundantCheck", errmsgcond, CWE825, (inconclusive || value->isInconclusive()) ? Certainty::inconclusive : Certainty::normal);
} else { } else {
std::string errmsg; std::string errmsg;
errmsg = std::string(value->isKnown() ? "Dereference" : "Possible dereference") + " of an invalid iterator"; errmsg = std::string(value->isKnown() ? "Dereference" : "Possible dereference") + " of an invalid iterator";
@ -2239,7 +2239,7 @@ void CheckStl::dereferenceInvalidIteratorError(const Token* tok, const ValueFlow
value->isKnown() ? Severity::error : Severity::warning, value->isKnown() ? Severity::error : Severity::warning,
"derefInvalidIterator", "derefInvalidIterator",
errmsg, errmsg,
CWE825, inconclusive || value->isInconclusive()); CWE825, (inconclusive || value->isInconclusive()) ? Certainty::inconclusive : Certainty::normal);
} }
} }
@ -2249,7 +2249,7 @@ void CheckStl::dereferenceInvalidIteratorError(const Token* deref, const std::st
"derefInvalidIterator", "derefInvalidIterator",
"$symbol:" + iterName + "\n" "$symbol:" + iterName + "\n"
"Possible dereference of an invalid iterator: $symbol\n" "Possible dereference of an invalid iterator: $symbol\n"
"Possible dereference of an invalid iterator: $symbol. Make sure to check that the iterator is valid before dereferencing it - not after.", CWE825, false); "Possible dereference of an invalid iterator: $symbol. Make sure to check that the iterator is valid before dereferencing it - not after.", CWE825, Certainty::normal);
} }
@ -2265,9 +2265,9 @@ void CheckStl::readingEmptyStlContainer2()
const ValueFlow::Value *value = tok->getContainerSizeValue(0); const ValueFlow::Value *value = tok->getContainerSizeValue(0);
if (!value) if (!value)
continue; continue;
if (value->isInconclusive() && !mSettings->inconclusive) if (value->isInconclusive() && !mSettings->certainty.isEnabled(Certainty::inconclusive))
continue; continue;
if (!value->errorSeverity() && !mSettings->isEnabled(Settings::WARNING)) if (!value->errorSeverity() && !mSettings->severity.isEnabled(Severity::warning))
continue; continue;
if (Token::Match(tok, "%name% . %name% (")) { if (Token::Match(tok, "%name% . %name% (")) {
if (container->getYield(tok->strAt(2)) == Library::Container::Yield::ITEM) if (container->getYield(tok->strAt(2)) == Library::Container::Yield::ITEM)
@ -2289,13 +2289,13 @@ void CheckStl::readingEmptyStlContainerError(const Token *tok, const ValueFlow::
const ErrorPath errorPath = getErrorPath(tok, value, "Reading from empty container"); const ErrorPath errorPath = getErrorPath(tok, value, "Reading from empty container");
reportError(errorPath, value ? (value->errorSeverity() ? Severity::error : Severity::warning) : Severity::style, "reademptycontainer", "$symbol:" + varname +"\n" + errmsg, CWE398, !value); reportError(errorPath, value ? (value->errorSeverity() ? Severity::error : Severity::warning) : Severity::style, "reademptycontainer", "$symbol:" + varname +"\n" + errmsg, CWE398, !value ? Certainty::inconclusive : Certainty::normal);
} }
void CheckStl::useStlAlgorithmError(const Token *tok, const std::string &algoName) void CheckStl::useStlAlgorithmError(const Token *tok, const std::string &algoName)
{ {
reportError(tok, Severity::style, "useStlAlgorithm", reportError(tok, Severity::style, "useStlAlgorithm",
"Consider using " + algoName + " algorithm instead of a raw loop.", CWE398, false); "Consider using " + algoName + " algorithm instead of a raw loop.", CWE398, Certainty::normal);
} }
static bool isEarlyExit(const Token *start) static bool isEarlyExit(const Token *start)
@ -2481,7 +2481,7 @@ static std::string minmaxCompare(const Token *condTok, nonneg int loopVar, nonne
void CheckStl::useStlAlgorithm() void CheckStl::useStlAlgorithm()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
for (const Scope *function : mTokenizer->getSymbolDatabase()->functionScopes) { for (const Scope *function : mTokenizer->getSymbolDatabase()->functionScopes) {
for (const Token *tok = function->bodyStart; tok != function->bodyEnd; tok = tok->next()) { for (const Token *tok = function->bodyStart; tok != function->bodyEnd; tok = tok->next()) {
@ -2643,7 +2643,7 @@ void CheckStl::knownEmptyContainerError(const Token *tok, const std::string& alg
reportError(tok, Severity::style, reportError(tok, Severity::style,
"knownEmptyContainer", "knownEmptyContainer",
msg, CWE398, false); msg, CWE398, Certainty::normal);
} }
static bool isKnownEmptyContainer(const Token* tok) static bool isKnownEmptyContainer(const Token* tok)
@ -2664,7 +2664,7 @@ static bool isKnownEmptyContainer(const Token* tok)
void CheckStl::knownEmptyContainer() void CheckStl::knownEmptyContainer()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
for (const Scope *function : mTokenizer->getSymbolDatabase()->functionScopes) { for (const Scope *function : mTokenizer->getSymbolDatabase()->functionScopes) {
for (const Token *tok = function->bodyStart; tok != function->bodyEnd; tok = tok->next()) { for (const Token *tok = function->bodyStart; tok != function->bodyEnd; tok = tok->next()) {
@ -2727,14 +2727,14 @@ void CheckStl::globalLockGuardError(const Token* tok)
{ {
reportError(tok, Severity::warning, reportError(tok, Severity::warning,
"globalLockGuard", "globalLockGuard",
"Lock guard is defined globally. Lock guards are intended to be local. A global lock guard could lead to a deadlock since it won't unlock until the end of the program.", CWE833, false); "Lock guard is defined globally. Lock guards are intended to be local. A global lock guard could lead to a deadlock since it won't unlock until the end of the program.", CWE833, Certainty::normal);
} }
void CheckStl::localMutexError(const Token* tok) void CheckStl::localMutexError(const Token* tok)
{ {
reportError(tok, Severity::warning, reportError(tok, Severity::warning,
"localMutex", "localMutex",
"The lock is ineffective because the mutex is locked at the same scope as the mutex itself.", CWE667, false); "The lock is ineffective because the mutex is locked at the same scope as the mutex itself.", CWE667, Certainty::normal);
} }
void CheckStl::checkMutexes() void CheckStl::checkMutexes()

View File

@ -87,7 +87,7 @@ void CheckString::stringLiteralWriteError(const Token *tok, const Token *strValu
} }
errmsg += " directly or indirectly is undefined behaviour."; errmsg += " directly or indirectly is undefined behaviour.";
reportError(callstack, Severity::error, "stringLiteralWrite", errmsg, CWE758, false); reportError(callstack, Severity::error, "stringLiteralWrite", errmsg, CWE758, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -96,7 +96,7 @@ void CheckString::stringLiteralWriteError(const Token *tok, const Token *strValu
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckString::checkAlwaysTrueOrFalseStringCompare() void CheckString::checkAlwaysTrueOrFalseStringCompare()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
for (const Token* tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token* tok = mTokenizer->tokens(); tok; tok = tok->next()) {
@ -145,7 +145,7 @@ void CheckString::alwaysTrueFalseStringCompareError(const Token *tok, const std:
reportError(tok, Severity::warning, "staticStringCompare", reportError(tok, Severity::warning, "staticStringCompare",
"Unnecessary comparison of static strings.\n" "Unnecessary comparison of static strings.\n"
"The compared strings, '" + string1 + "' and '" + string2 + "', are always " + (str1==str2?"identical":"unequal") + ". " "The compared strings, '" + string1 + "' and '" + string2 + "', are always " + (str1==str2?"identical":"unequal") + ". "
"Therefore the comparison is unnecessary and looks suspicious.", (str1==str2)?CWE571:CWE570, false); "Therefore the comparison is unnecessary and looks suspicious.", (str1==str2)?CWE571:CWE570, Certainty::normal);
} }
void CheckString::alwaysTrueStringVariableCompareError(const Token *tok, const std::string& str1, const std::string& str2) void CheckString::alwaysTrueStringVariableCompareError(const Token *tok, const std::string& str1, const std::string& str2)
@ -153,7 +153,7 @@ void CheckString::alwaysTrueStringVariableCompareError(const Token *tok, const s
reportError(tok, Severity::warning, "stringCompare", reportError(tok, Severity::warning, "stringCompare",
"Comparison of identical string variables.\n" "Comparison of identical string variables.\n"
"The compared strings, '" + str1 + "' and '" + str2 + "', are identical. " "The compared strings, '" + str1 + "' and '" + str2 + "', are identical. "
"This could be a logic bug.", CWE571, false); "This could be a logic bug.", CWE571, Certainty::normal);
} }
@ -163,7 +163,7 @@ void CheckString::alwaysTrueStringVariableCompareError(const Token *tok, const s
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CheckString::checkSuspiciousStringCompare() void CheckString::checkSuspiciousStringCompare()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase();
@ -202,13 +202,13 @@ void CheckString::suspiciousStringCompareError(const Token* tok, const std::stri
{ {
const std::string cmpFunc = isLong ? "wcscmp" : "strcmp"; const std::string cmpFunc = isLong ? "wcscmp" : "strcmp";
reportError(tok, Severity::warning, "literalWithCharPtrCompare", reportError(tok, Severity::warning, "literalWithCharPtrCompare",
"$symbol:" + var + "\nString literal compared with variable '$symbol'. Did you intend to use " + cmpFunc + "() instead?", CWE595, false); "$symbol:" + var + "\nString literal compared with variable '$symbol'. Did you intend to use " + cmpFunc + "() instead?", CWE595, Certainty::normal);
} }
void CheckString::suspiciousStringCompareError_char(const Token* tok, const std::string& var) void CheckString::suspiciousStringCompareError_char(const Token* tok, const std::string& var)
{ {
reportError(tok, Severity::warning, "charLiteralWithCharPtrCompare", reportError(tok, Severity::warning, "charLiteralWithCharPtrCompare",
"$symbol:" + var + "\nChar literal compared with pointer '$symbol'. Did you intend to dereference it?", CWE595, false); "$symbol:" + var + "\nChar literal compared with pointer '$symbol'. Did you intend to dereference it?", CWE595, Certainty::normal);
} }
@ -243,7 +243,7 @@ void CheckString::strPlusCharError(const Token *tok)
charType = tok->astOperand2()->variable()->typeStartToken()->str(); charType = tok->astOperand2()->variable()->typeStartToken()->str();
else if (tok && tok->astOperand2() && tok->astOperand2()->tokType() == Token::eChar && tok->astOperand2()->isLong()) else if (tok && tok->astOperand2() && tok->astOperand2()->tokType() == Token::eChar && tok->astOperand2()->isLong())
charType = "wchar_t"; charType = "wchar_t";
reportError(tok, Severity::error, "strPlusChar", "Unusual pointer arithmetic. A value of type '" + charType +"' is added to a string literal.", CWE665, false); reportError(tok, Severity::error, "strPlusChar", "Unusual pointer arithmetic. A value of type '" + charType +"' is added to a string literal.", CWE665, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -252,7 +252,7 @@ void CheckString::strPlusCharError(const Token *tok)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckString::checkIncorrectStringCompare() void CheckString::checkIncorrectStringCompare()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -300,7 +300,7 @@ void CheckString::checkIncorrectStringCompare()
void CheckString::incorrectStringCompareError(const Token *tok, const std::string& func, const std::string &string) void CheckString::incorrectStringCompareError(const Token *tok, const std::string& func, const std::string &string)
{ {
reportError(tok, Severity::warning, "incorrectStringCompare", "$symbol:" + func + "\nString literal " + string + " doesn't match length argument for $symbol().", CWE570, false); reportError(tok, Severity::warning, "incorrectStringCompare", "$symbol:" + func + "\nString literal " + string + " doesn't match length argument for $symbol().", CWE570, Certainty::normal);
} }
void CheckString::incorrectStringBooleanError(const Token *tok, const std::string& string) void CheckString::incorrectStringBooleanError(const Token *tok, const std::string& string)
@ -311,7 +311,7 @@ void CheckString::incorrectStringBooleanError(const Token *tok, const std::strin
reportError(tok, reportError(tok,
Severity::warning, Severity::warning,
charLiteral ? "incorrectCharBooleanError" : "incorrectStringBooleanError", charLiteral ? "incorrectCharBooleanError" : "incorrectStringBooleanError",
"Conversion of " + literalType + " literal " + string + " to bool always evaluates to " + result + '.', CWE571, false); "Conversion of " + literalType + " literal " + string + " to bool always evaluates to " + result + '.', CWE571, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -320,7 +320,7 @@ void CheckString::incorrectStringBooleanError(const Token *tok, const std::strin
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckString::overlappingStrcmp() void CheckString::overlappingStrcmp()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -442,5 +442,5 @@ void CheckString::sprintfOverlappingDataError(const Token *funcTok, const Token
func + "(). The origin and destination buffers overlap. Quote from glibc (C-library) " func + "(). The origin and destination buffers overlap. Quote from glibc (C-library) "
"documentation (http://www.gnu.org/software/libc/manual/html_mono/libc.html#Formatted-Output-Functions): " "documentation (http://www.gnu.org/software/libc/manual/html_mono/libc.html#Formatted-Output-Functions): "
"\"If copying takes place between objects that overlap as a result of a call " "\"If copying takes place between objects that overlap as a result of a call "
"to sprintf() or snprintf(), the results are undefined.\"", CWE628, false); "to sprintf() or snprintf(), the results are undefined.\"", CWE628, Certainty::normal);
} }

View File

@ -107,7 +107,7 @@ void CheckType::tooBigBitwiseShiftError(const Token *tok, int lhsbits, const Val
const char id[] = "shiftTooManyBits"; const char id[] = "shiftTooManyBits";
if (!tok) { if (!tok) {
reportError(tok, Severity::error, id, "Shifting 32-bit value by 40 bits is undefined behaviour", CWE758, false); reportError(tok, Severity::error, id, "Shifting 32-bit value by 40 bits is undefined behaviour", CWE758, Certainty::normal);
return; return;
} }
@ -118,7 +118,7 @@ void CheckType::tooBigBitwiseShiftError(const Token *tok, int lhsbits, const Val
if (rhsbits.condition) if (rhsbits.condition)
errmsg << ". See condition at line " << rhsbits.condition->linenr() << "."; errmsg << ". See condition at line " << rhsbits.condition->linenr() << ".";
reportError(errorPath, rhsbits.errorSeverity() ? Severity::error : Severity::warning, id, errmsg.str(), CWE758, rhsbits.isInconclusive()); reportError(errorPath, rhsbits.errorSeverity() ? Severity::error : Severity::warning, id, errmsg.str(), CWE758, rhsbits.isInconclusive() ? Certainty::inconclusive : Certainty::normal);
} }
void CheckType::tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits) void CheckType::tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits)
@ -131,7 +131,7 @@ void CheckType::tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, con
if (cpp14) if (cpp14)
behaviour = "implementation-defined"; behaviour = "implementation-defined";
if (!tok) { if (!tok) {
reportError(tok, Severity::error, id, "Shifting signed 32-bit value by 31 bits is " + behaviour + " behaviour", CWE758, false); reportError(tok, Severity::error, id, "Shifting signed 32-bit value by 31 bits is " + behaviour + " behaviour", CWE758, Certainty::normal);
return; return;
} }
@ -146,9 +146,9 @@ void CheckType::tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, con
if (cpp14) if (cpp14)
severity = Severity::portability; severity = Severity::portability;
if ((severity == Severity::portability) && !mSettings->isEnabled(Settings::PORTABILITY)) if ((severity == Severity::portability) && !mSettings->severity.isEnabled(Severity::portability))
return; return;
reportError(errorPath, severity, id, errmsg.str(), CWE758, rhsbits.isInconclusive()); reportError(errorPath, severity, id, errmsg.str(), CWE758, rhsbits.isInconclusive() ? Certainty::inconclusive : Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -220,7 +220,7 @@ void CheckType::integerOverflowError(const Token *tok, const ValueFlow::Value &v
getMessageId(value, "integerOverflow").c_str(), getMessageId(value, "integerOverflow").c_str(),
msg, msg,
CWE190, CWE190,
value.isInconclusive()); value.isInconclusive() ? Certainty::inconclusive : Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -229,7 +229,7 @@ void CheckType::integerOverflowError(const Token *tok, const ValueFlow::Value &v
void CheckType::checkSignConversion() void CheckType::checkSignConversion()
{ {
if (!mSettings->isEnabled(Settings::WARNING)) if (!mSettings->severity.isEnabled(Severity::warning))
return; return;
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
@ -267,7 +267,7 @@ void CheckType::signConversionError(const Token *tok, const ValueFlow::Value *ne
msg << "Expression '" << expr << "' can have a negative value. That is converted to an unsigned value and used in an unsigned calculation."; msg << "Expression '" << expr << "' can have a negative value. That is converted to an unsigned value and used in an unsigned calculation.";
if (!negativeValue) if (!negativeValue)
reportError(tok, Severity::warning, "signConversion", msg.str(), CWE195, false); reportError(tok, Severity::warning, "signConversion", msg.str(), CWE195, Certainty::normal);
else { else {
const ErrorPath &errorPath = getErrorPath(tok,negativeValue,"Negative value is converted to an unsigned value"); const ErrorPath &errorPath = getErrorPath(tok,negativeValue,"Negative value is converted to an unsigned value");
reportError(errorPath, reportError(errorPath,
@ -275,7 +275,7 @@ void CheckType::signConversionError(const Token *tok, const ValueFlow::Value *ne
Check::getMessageId(*negativeValue, "signConversion").c_str(), Check::getMessageId(*negativeValue, "signConversion").c_str(),
msg.str(), msg.str(),
CWE195, CWE195,
negativeValue->isInconclusive()); negativeValue->isInconclusive() ? Certainty::inconclusive : Certainty::normal);
} }
} }
@ -286,7 +286,7 @@ void CheckType::signConversionError(const Token *tok, const ValueFlow::Value *ne
void CheckType::checkLongCast() void CheckType::checkLongCast()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
// Assignments.. // Assignments..
@ -362,7 +362,7 @@ void CheckType::longCastAssignError(const Token *tok)
Severity::style, Severity::style,
"truncLongCastAssignment", "truncLongCastAssignment",
"int result is assigned to long variable. If the variable is long to avoid loss of information, then you have loss of information.\n" "int result is assigned to long variable. If the variable is long to avoid loss of information, then you have loss of information.\n"
"int result is assigned to long variable. If the variable 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 'l = a * b;' => 'l = (long)a * b;'.", CWE197, false); "int result is assigned to long variable. If the variable 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 'l = a * b;' => 'l = (long)a * b;'.", CWE197, Certainty::normal);
} }
void CheckType::longCastReturnError(const Token *tok) void CheckType::longCastReturnError(const Token *tok)
@ -371,7 +371,7 @@ void CheckType::longCastReturnError(const Token *tok)
Severity::style, Severity::style,
"truncLongCastReturn", "truncLongCastReturn",
"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 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'.", CWE197, false); "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'.", CWE197, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -458,5 +458,5 @@ void CheckType::floatToIntegerOverflowError(const Token *tok, const ValueFlow::V
reportError(getErrorPath(tok, &value, "float to integer conversion"), reportError(getErrorPath(tok, &value, "float to integer conversion"),
value.errorSeverity() ? Severity::error : Severity::warning, value.errorSeverity() ? Severity::error : Severity::warning,
"floatConversionOverflow", "floatConversionOverflow",
errmsg.str(), CWE190, value.isInconclusive()); errmsg.str(), CWE190, value.isInconclusive() ? Certainty::inconclusive : Certainty::normal);
} }

View File

@ -1287,7 +1287,7 @@ bool CheckUninitVar::isMemberVariableUsage(const Token *tok, bool isPointer, All
tok->astParent()->astParent()->astParent()->astOperand2() == tok->astParent()->astParent()) tok->astParent()->astParent()->astParent()->astOperand2() == tok->astParent()->astParent())
return true; return true;
else if (mSettings->experimental && else if (mSettings->certainty.isEnabled(Certainty::experimental) &&
!isPointer && !isPointer &&
Token::Match(tok->tokAt(-2), "[(,] & %name% [,)]") && Token::Match(tok->tokAt(-2), "[(,] & %name% [,)]") &&
isVariableUsage(tok, isPointer, alloc)) isVariableUsage(tok, isPointer, alloc))
@ -1298,18 +1298,18 @@ bool CheckUninitVar::isMemberVariableUsage(const Token *tok, bool isPointer, All
void CheckUninitVar::uninitstringError(const Token *tok, const std::string &varname, bool strncpy_) void CheckUninitVar::uninitstringError(const Token *tok, const std::string &varname, bool strncpy_)
{ {
reportError(tok, Severity::error, "uninitstring", "$symbol:" + varname + "\nDangerous usage of '$symbol'" + (strncpy_ ? " (strncpy doesn't always null-terminate it)." : " (not null-terminated)."), CWE_USE_OF_POTENTIALLY_DANGEROUS_FUNCTION, false); reportError(tok, Severity::error, "uninitstring", "$symbol:" + varname + "\nDangerous usage of '$symbol'" + (strncpy_ ? " (strncpy doesn't always null-terminate it)." : " (not null-terminated)."), CWE_USE_OF_POTENTIALLY_DANGEROUS_FUNCTION, Certainty::normal);
} }
void CheckUninitVar::uninitdataError(const Token *tok, const std::string &varname) void CheckUninitVar::uninitdataError(const Token *tok, const std::string &varname)
{ {
reportError(tok, Severity::error, "uninitdata", "$symbol:" + varname + "\nMemory is allocated but not initialized: $symbol", CWE_USE_OF_UNINITIALIZED_VARIABLE, false); reportError(tok, Severity::error, "uninitdata", "$symbol:" + varname + "\nMemory is allocated but not initialized: $symbol", CWE_USE_OF_UNINITIALIZED_VARIABLE, Certainty::normal);
} }
void CheckUninitVar::uninitvarError(const Token *tok, const std::string &varname, ErrorPath errorPath) void CheckUninitVar::uninitvarError(const Token *tok, const std::string &varname, ErrorPath errorPath)
{ {
errorPath.emplace_back(tok, ""); errorPath.emplace_back(tok, "");
reportError(errorPath, Severity::error, "uninitvar", "$symbol:" + varname + "\nUninitialized variable: $symbol", CWE_USE_OF_UNINITIALIZED_VARIABLE, false); reportError(errorPath, Severity::error, "uninitvar", "$symbol:" + varname + "\nUninitialized variable: $symbol", CWE_USE_OF_UNINITIALIZED_VARIABLE, Certainty::normal);
} }
void CheckUninitVar::uninitStructMemberError(const Token *tok, const std::string &membername) void CheckUninitVar::uninitStructMemberError(const Token *tok, const std::string &membername)
@ -1317,7 +1317,7 @@ void CheckUninitVar::uninitStructMemberError(const Token *tok, const std::string
reportError(tok, reportError(tok,
Severity::error, Severity::error,
"uninitStructMember", "uninitStructMember",
"$symbol:" + membername + "\nUninitialized struct member: $symbol", CWE_USE_OF_UNINITIALIZED_VARIABLE, false); "$symbol:" + membername + "\nUninitialized struct member: $symbol", CWE_USE_OF_UNINITIALIZED_VARIABLE, Certainty::normal);
} }
static bool isLeafDot(const Token* tok) static bool isLeafDot(const Token* tok)
@ -1453,7 +1453,7 @@ bool CheckUninitVar::analyseWholeProgram(const CTU::FileInfo *ctu, const std::li
"Using argument " + unsafeUsage.myArgumentName + " that points at uninitialized variable " + functionCall->callArgumentExpression, "Using argument " + unsafeUsage.myArgumentName + " that points at uninitialized variable " + functionCall->callArgumentExpression,
"ctuuninitvar", "ctuuninitvar",
CWE_USE_OF_UNINITIALIZED_VARIABLE, CWE_USE_OF_UNINITIALIZED_VARIABLE,
false); Certainty::normal);
errorLogger.reportErr(errmsg); errorLogger.reportErr(errmsg);
foundErrors = true; foundErrors = true;

View File

@ -331,7 +331,7 @@ void CheckUnusedFunctions::unusedFunctionError(ErrorLogger * const errorLogger,
locationList.push_back(fileLoc); locationList.push_back(fileLoc);
} }
const ErrorMessage errmsg(locationList, emptyString, Severity::style, "$symbol:" + funcname + "\nThe function '$symbol' is never used.", "unusedFunction", CWE561, false); const ErrorMessage errmsg(locationList, emptyString, Severity::style, "$symbol:" + funcname + "\nThe function '$symbol' is never used.", "unusedFunction", CWE561, Certainty::normal);
if (errorLogger) if (errorLogger)
errorLogger->reportErr(errmsg); errorLogger->reportErr(errmsg);
else else
@ -340,7 +340,7 @@ void CheckUnusedFunctions::unusedFunctionError(ErrorLogger * const errorLogger,
Check::FileInfo *CheckUnusedFunctions::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const Check::FileInfo *CheckUnusedFunctions::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const
{ {
if (!settings->isEnabled(Settings::UNUSED_FUNCTION)) if (!settings->checks.isEnabled(Checks::unusedFunction))
return nullptr; return nullptr;
if (settings->jobs == 1 && settings->buildDir.empty()) if (settings->jobs == 1 && settings->buildDir.empty())
instance.parseTokens(*tokenizer, tokenizer->list.getFiles().front().c_str(), settings); instance.parseTokens(*tokenizer, tokenizer->list.getFiles().front().c_str(), settings);

View File

@ -1142,7 +1142,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
void CheckUnusedVar::checkFunctionVariableUsage() void CheckUnusedVar::checkFunctionVariableUsage()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
if (mSettings->clang) if (mSettings->clang)
@ -1270,7 +1270,7 @@ void CheckUnusedVar::checkFunctionVariableUsage()
FwdAnalysis fwdAnalysis(mTokenizer->isCPP(), mSettings->library); FwdAnalysis fwdAnalysis(mTokenizer->isCPP(), mSettings->library);
if (fwdAnalysis.unusedValue(expr, start, scope->bodyEnd)) { if (fwdAnalysis.unusedValue(expr, start, scope->bodyEnd)) {
if (!bailoutTypeName.empty() && bailoutTypeName != "auto") { if (!bailoutTypeName.empty() && bailoutTypeName != "auto") {
if (mSettings->checkLibrary && mSettings->isEnabled(Settings::INFORMATION)) { if (mSettings->checkLibrary && mSettings->severity.isEnabled(Severity::information)) {
reportError(tok, reportError(tok,
Severity::information, Severity::information,
"checkLibraryCheckType", "checkLibraryCheckType",
@ -1334,25 +1334,25 @@ void CheckUnusedVar::checkFunctionVariableUsage()
void CheckUnusedVar::unusedVariableError(const Token *tok, const std::string &varname) void CheckUnusedVar::unusedVariableError(const Token *tok, const std::string &varname)
{ {
reportError(tok, Severity::style, "unusedVariable", "$symbol:" + varname + "\nUnused variable: $symbol", CWE563, false); reportError(tok, Severity::style, "unusedVariable", "$symbol:" + varname + "\nUnused variable: $symbol", CWE563, Certainty::normal);
} }
void CheckUnusedVar::allocatedButUnusedVariableError(const Token *tok, const std::string &varname) void CheckUnusedVar::allocatedButUnusedVariableError(const Token *tok, const std::string &varname)
{ {
reportError(tok, Severity::style, "unusedAllocatedMemory", "$symbol:" + varname + "\nVariable '$symbol' is allocated memory that is never used.", CWE563, false); reportError(tok, Severity::style, "unusedAllocatedMemory", "$symbol:" + varname + "\nVariable '$symbol' is allocated memory that is never used.", CWE563, Certainty::normal);
} }
void CheckUnusedVar::unreadVariableError(const Token *tok, const std::string &varname, bool modified) void CheckUnusedVar::unreadVariableError(const Token *tok, const std::string &varname, bool modified)
{ {
if (modified) if (modified)
reportError(tok, Severity::style, "unreadVariable", "$symbol:" + varname + "\nVariable '$symbol' is modified but its new value is never used.", CWE563, false); reportError(tok, Severity::style, "unreadVariable", "$symbol:" + varname + "\nVariable '$symbol' is modified but its new value is never used.", CWE563, Certainty::normal);
else else
reportError(tok, Severity::style, "unreadVariable", "$symbol:" + varname + "\nVariable '$symbol' is assigned a value that is never used.", CWE563, false); reportError(tok, Severity::style, "unreadVariable", "$symbol:" + varname + "\nVariable '$symbol' is assigned a value that is never used.", CWE563, Certainty::normal);
} }
void CheckUnusedVar::unassignedVariableError(const Token *tok, const std::string &varname) void CheckUnusedVar::unassignedVariableError(const Token *tok, const std::string &varname)
{ {
reportError(tok, Severity::style, "unassignedVariable", "$symbol:" + varname + "\nVariable '$symbol' is not assigned a value.", CWE665, false); reportError(tok, Severity::style, "unassignedVariable", "$symbol:" + varname + "\nVariable '$symbol' is not assigned a value.", CWE665, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1360,7 +1360,7 @@ void CheckUnusedVar::unassignedVariableError(const Token *tok, const std::string
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckUnusedVar::checkStructMemberUsage() void CheckUnusedVar::checkStructMemberUsage()
{ {
if (!mSettings->isEnabled(Settings::STYLE)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
@ -1466,7 +1466,7 @@ void CheckUnusedVar::checkStructMemberUsage()
void CheckUnusedVar::unusedStructMemberError(const Token *tok, const std::string &structname, const std::string &varname, bool isUnion) void CheckUnusedVar::unusedStructMemberError(const Token *tok, const std::string &structname, const std::string &varname, bool isUnion)
{ {
const std::string prefix = isUnion ? "union member " : "struct member "; const std::string prefix = isUnion ? "union member " : "struct member ";
reportError(tok, Severity::style, "unusedStructMember", "$symbol:" + structname + "::" + varname + '\n' + prefix + "'$symbol' is never used.", CWE563, false); reportError(tok, Severity::style, "unusedStructMember", "$symbol:" + structname + "::" + varname + '\n' + prefix + "'$symbol' is never used.", CWE563, Certainty::normal);
} }
bool CheckUnusedVar::isRecordTypeWithoutSideEffects(const Type* type) bool CheckUnusedVar::isRecordTypeWithoutSideEffects(const Type* type)

View File

@ -48,7 +48,7 @@ void CheckVaarg::va_start_argument()
{ {
const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase();
const std::size_t functions = symbolDatabase->functionScopes.size(); const std::size_t functions = symbolDatabase->functionScopes.size();
const bool printWarnings = mSettings->isEnabled(Settings::WARNING); const bool printWarnings = mSettings->severity.isEnabled(Severity::warning);
for (std::size_t i = 0; i < functions; ++i) { for (std::size_t i = 0; i < functions; ++i) {
const Scope* scope = symbolDatabase->functionScopes[i]; const Scope* scope = symbolDatabase->functionScopes[i];
@ -79,13 +79,13 @@ void CheckVaarg::va_start_argument()
void CheckVaarg::wrongParameterTo_va_start_error(const Token *tok, const std::string& paramIsName, const std::string& paramShouldName) void CheckVaarg::wrongParameterTo_va_start_error(const Token *tok, const std::string& paramIsName, const std::string& paramShouldName)
{ {
reportError(tok, Severity::warning, reportError(tok, Severity::warning,
"va_start_wrongParameter", "'" + paramIsName + "' given to va_start() is not last named argument of the function. Did you intend to pass '" + paramShouldName + "'?", CWE688, false); "va_start_wrongParameter", "'" + paramIsName + "' given to va_start() is not last named argument of the function. Did you intend to pass '" + paramShouldName + "'?", CWE688, Certainty::normal);
} }
void CheckVaarg::referenceAs_va_start_error(const Token *tok, const std::string& paramName) void CheckVaarg::referenceAs_va_start_error(const Token *tok, const std::string& paramName)
{ {
reportError(tok, Severity::error, reportError(tok, Severity::error,
"va_start_referencePassed", "Using reference '" + paramName + "' as parameter for va_start() results in undefined behaviour.", CWE758, false); "va_start_referencePassed", "Using reference '" + paramName + "' as parameter for va_start() results in undefined behaviour.", CWE758, Certainty::normal);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -158,17 +158,17 @@ void CheckVaarg::va_list_usage()
void CheckVaarg::va_end_missingError(const Token *tok, const std::string& varname) void CheckVaarg::va_end_missingError(const Token *tok, const std::string& varname)
{ {
reportError(tok, Severity::error, reportError(tok, Severity::error,
"va_end_missing", "va_list '" + varname + "' was opened but not closed by va_end().", CWE664, false); "va_end_missing", "va_list '" + varname + "' was opened but not closed by va_end().", CWE664, Certainty::normal);
} }
void CheckVaarg::va_list_usedBeforeStartedError(const Token *tok, const std::string& varname) void CheckVaarg::va_list_usedBeforeStartedError(const Token *tok, const std::string& varname)
{ {
reportError(tok, Severity::error, reportError(tok, Severity::error,
"va_list_usedBeforeStarted", "va_list '" + varname + "' used before va_start() was called.", CWE664, false); "va_list_usedBeforeStarted", "va_list '" + varname + "' used before va_start() was called.", CWE664, Certainty::normal);
} }
void CheckVaarg::va_start_subsequentCallsError(const Token *tok, const std::string& varname) void CheckVaarg::va_start_subsequentCallsError(const Token *tok, const std::string& varname)
{ {
reportError(tok, Severity::error, reportError(tok, Severity::error,
"va_start_subsequentCalls", "va_start() or va_copy() called subsequently on '" + varname + "' without va_end() in between.", CWE664, false); "va_start_subsequentCalls", "va_start() or va_copy() called subsequently on '" + varname + "' without va_end() in between.", CWE664, Certainty::normal);
} }

View File

@ -356,7 +356,7 @@ static bool reportClangErrors(std::istream &is, std::function<void(const ErrorMe
Severity::error, Severity::error,
msg, msg,
"syntaxError", "syntaxError",
false); Certainty::normal);
reportErr(errmsg); reportErr(errmsg);
return true; return true;
@ -586,7 +586,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
Severity::error, Severity::error,
output.msg, output.msg,
"syntaxError", "syntaxError",
false); Certainty::normal);
reportErr(errmsg); reportErr(errmsg);
return mExitCode; return mExitCode;
} }
@ -624,11 +624,11 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
// Get toolinfo // Get toolinfo
std::ostringstream toolinfo; std::ostringstream toolinfo;
toolinfo << CPPCHECK_VERSION_STRING; toolinfo << CPPCHECK_VERSION_STRING;
toolinfo << (mSettings.isEnabled(Settings::WARNING) ? 'w' : ' '); toolinfo << (mSettings.severity.isEnabled(Severity::warning) ? 'w' : ' ');
toolinfo << (mSettings.isEnabled(Settings::STYLE) ? 's' : ' '); toolinfo << (mSettings.severity.isEnabled(Severity::style) ? 's' : ' ');
toolinfo << (mSettings.isEnabled(Settings::PERFORMANCE) ? 'p' : ' '); toolinfo << (mSettings.severity.isEnabled(Severity::performance) ? 'p' : ' ');
toolinfo << (mSettings.isEnabled(Settings::PORTABILITY) ? 'p' : ' '); toolinfo << (mSettings.severity.isEnabled(Severity::portability) ? 'p' : ' ');
toolinfo << (mSettings.isEnabled(Settings::INFORMATION) ? 'i' : ' '); toolinfo << (mSettings.severity.isEnabled(Severity::information) ? 'i' : ' ');
toolinfo << mSettings.userDefines; toolinfo << mSettings.userDefines;
mSettings.nomsg.dump(toolinfo); mSettings.nomsg.dump(toolinfo);
@ -684,7 +684,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
} }
if (!mSettings.force && configurations.size() > mSettings.maxConfigs) { if (!mSettings.force && configurations.size() > mSettings.maxConfigs) {
if (mSettings.isEnabled(Settings::INFORMATION)) { if (mSettings.severity.isEnabled(Severity::information)) {
tooManyConfigsError(Path::toNativeSeparators(filename),configurations.size()); tooManyConfigsError(Path::toNativeSeparators(filename),configurations.size());
} else { } else {
mTooManyConfigs = true; mTooManyConfigs = true;
@ -842,14 +842,14 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
Severity::error, Severity::error,
e.errorMessage, e.errorMessage,
e.id, e.id,
false); Certainty::normal);
if (errmsg.severity == Severity::error || mSettings.isEnabled(errmsg.severity)) if (errmsg.severity == Severity::error || mSettings.severity.isEnabled(errmsg.severity))
reportErr(errmsg); reportErr(errmsg);
} }
} }
if (!hasValidConfig && configurations.size() > 1 && mSettings.isEnabled(Settings::INFORMATION)) { if (!hasValidConfig && configurations.size() > 1 && mSettings.severity.isEnabled(Severity::information)) {
std::string msg; std::string msg;
msg = "This file is not analyzed. Cppcheck failed to extract a valid configuration. Use -v for more details."; msg = "This file is not analyzed. Cppcheck failed to extract a valid configuration. Use -v for more details.";
msg += "\nThis file is not analyzed. Cppcheck failed to extract a valid configuration. The tested configurations have these preprocessor errors:"; msg += "\nThis file is not analyzed. Cppcheck failed to extract a valid configuration. The tested configurations have these preprocessor errors:";
@ -865,7 +865,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
Severity::information, Severity::information,
msg, msg,
"noValidConfiguration", "noValidConfiguration",
false); Certainty::normal);
reportErr(errmsg); reportErr(errmsg);
} }
@ -891,7 +891,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
// In jointSuppressionReport mode, unmatched suppressions are // In jointSuppressionReport mode, unmatched suppressions are
// collected after all files are processed // collected after all files are processed
if (!mSettings.jointSuppressionReport && (mSettings.isEnabled(Settings::INFORMATION) || mSettings.checkConfiguration)) { if (!mSettings.jointSuppressionReport && (mSettings.severity.isEnabled(Severity::information) || mSettings.checkConfiguration)) {
reportUnmatchedSuppressions(mSettings.nomsg.getUnmatchedLocalSuppressions(filename, isUnusedFunctionCheckEnabled())); reportUnmatchedSuppressions(mSettings.nomsg.getUnmatchedLocalSuppressions(filename, isUnusedFunctionCheckEnabled()));
} }
@ -905,7 +905,7 @@ void CppCheck::internalError(const std::string &filename, const std::string &msg
const std::string fixedpath = Path::toNativeSeparators(filename); const std::string fixedpath = Path::toNativeSeparators(filename);
const std::string fullmsg("Bailing out from checking " + fixedpath + " since there was an internal error: " + msg); const std::string fullmsg("Bailing out from checking " + fixedpath + " since there was an internal error: " + msg);
if (mSettings.isEnabled(Settings::INFORMATION)) { if (mSettings.severity.isEnabled(Severity::information)) {
const ErrorMessage::FileLocation loc1(filename, 0, 0); const ErrorMessage::FileLocation loc1(filename, 0, 0);
std::list<ErrorMessage::FileLocation> callstack(1, loc1); std::list<ErrorMessage::FileLocation> callstack(1, loc1);
@ -914,7 +914,7 @@ void CppCheck::internalError(const std::string &filename, const std::string &msg
Severity::information, Severity::information,
fullmsg, fullmsg,
"internalError", "internalError",
false); Certainty::normal);
mErrorLogger.reportErr(errmsg); mErrorLogger.reportErr(errmsg);
} else { } else {
@ -1163,7 +1163,7 @@ void CppCheck::executeRules(const std::string &tokenlist, const Tokenizer &token
Severity::error, Severity::error,
msg, msg,
"pcre_compile", "pcre_compile",
false); Certainty::normal);
reportErr(errmsg); reportErr(errmsg);
} }
@ -1184,7 +1184,7 @@ void CppCheck::executeRules(const std::string &tokenlist, const Tokenizer &token
Severity::error, Severity::error,
msg, msg,
"pcre_study", "pcre_study",
false); Certainty::normal);
reportErr(errmsg); reportErr(errmsg);
// pcre_compile() worked, but pcre_study() returned an error. Free the resources allocated by pcre_compile(). // pcre_compile() worked, but pcre_study() returned an error. Free the resources allocated by pcre_compile().
@ -1207,7 +1207,7 @@ void CppCheck::executeRules(const std::string &tokenlist, const Tokenizer &token
Severity::error, Severity::error,
std::string("pcre_exec failed: ") + errorMessage, std::string("pcre_exec failed: ") + errorMessage,
"pcre_exec", "pcre_exec",
false); Certainty::normal);
reportErr(errmsg); reportErr(errmsg);
} }
@ -1242,7 +1242,7 @@ void CppCheck::executeRules(const std::string &tokenlist, const Tokenizer &token
summary = "found '" + str.substr(pos1, pos2 - pos1) + "'"; summary = "found '" + str.substr(pos1, pos2 - pos1) + "'";
else else
summary = rule.summary; summary = rule.summary;
const ErrorMessage errmsg(callStack, tokenizer.list.getSourceFilePath(), rule.severity, summary, rule.id, false); const ErrorMessage errmsg(callStack, tokenizer.list.getSourceFilePath(), rule.severity, summary, rule.id, Certainty::normal);
// Report error // Report error
reportErr(errmsg); reportErr(errmsg);
@ -1320,12 +1320,12 @@ Settings &CppCheck::settings()
void CppCheck::tooManyConfigsError(const std::string &file, const int numberOfConfigurations) void CppCheck::tooManyConfigsError(const std::string &file, const int numberOfConfigurations)
{ {
if (!mSettings.isEnabled(Settings::INFORMATION) && !mTooManyConfigs) if (!mSettings.severity.isEnabled(Severity::information) && !mTooManyConfigs)
return; return;
mTooManyConfigs = false; mTooManyConfigs = false;
if (mSettings.isEnabled(Settings::INFORMATION) && file.empty()) if (mSettings.severity.isEnabled(Severity::information) && file.empty())
return; return;
std::list<ErrorMessage::FileLocation> loclist; std::list<ErrorMessage::FileLocation> loclist;
@ -1354,7 +1354,7 @@ void CppCheck::tooManyConfigsError(const std::string &file, const int numberOfCo
Severity::information, Severity::information,
msg.str(), msg.str(),
"toomanyconfigs", CWE398, "toomanyconfigs", CWE398,
false); Certainty::normal);
reportErr(errmsg); reportErr(errmsg);
} }
@ -1363,7 +1363,7 @@ void CppCheck::purgedConfigurationMessage(const std::string &file, const std::st
{ {
mTooManyConfigs = false; mTooManyConfigs = false;
if (mSettings.isEnabled(Settings::INFORMATION) && file.empty()) if (mSettings.severity.isEnabled(Severity::information) && file.empty())
return; return;
std::list<ErrorMessage::FileLocation> loclist; std::list<ErrorMessage::FileLocation> loclist;
@ -1378,7 +1378,7 @@ void CppCheck::purgedConfigurationMessage(const std::string &file, const std::st
Severity::information, Severity::information,
"The configuration '" + configuration + "' was not checked because its code equals another one.", "The configuration '" + configuration + "' was not checked because its code equals another one.",
"purgedConfiguration", "purgedConfiguration",
false); Certainty::normal);
reportErr(errmsg); reportErr(errmsg);
} }
@ -1457,11 +1457,11 @@ void CppCheck::bughuntingReport(const std::string &str)
void CppCheck::getErrorMessages() void CppCheck::getErrorMessages()
{ {
Settings s(mSettings); Settings s(mSettings);
s.addEnabled("warning"); s.severity.enable(Severity::warning);
s.addEnabled("style"); s.severity.enable(Severity::style);
s.addEnabled("portability"); s.severity.enable(Severity::portability);
s.addEnabled("performance"); s.severity.enable(Severity::performance);
s.addEnabled("information"); s.severity.enable(Severity::information);
purgedConfigurationMessage("",""); purgedConfigurationMessage("","");
@ -1577,7 +1577,7 @@ void CppCheck::analyseWholeProgram(const std::string &buildDir, const std::map<s
(void)files; (void)files;
if (buildDir.empty()) if (buildDir.empty())
return; return;
if (mSettings.isEnabled(Settings::UNUSED_FUNCTION)) if (mSettings.checks.isEnabled(Checks::unusedFunction))
CheckUnusedFunctions::analyseWholeProgram(this, buildDir); CheckUnusedFunctions::analyseWholeProgram(this, buildDir);
std::list<Check::FileInfo*> fileInfoList; std::list<Check::FileInfo*> fileInfoList;
CTU::FileInfo ctuFileInfo; CTU::FileInfo ctuFileInfo;
@ -1635,5 +1635,5 @@ void CppCheck::analyseWholeProgram(const std::string &buildDir, const std::map<s
bool CppCheck::isUnusedFunctionCheckEnabled() const bool CppCheck::isUnusedFunctionCheckEnabled() const
{ {
return (mSettings.jobs == 1 && mSettings.isEnabled(Settings::UNUSED_FUNCTION)); return (mSettings.jobs == 1 && mSettings.checks.isEnabled(Checks::unusedFunction));
} }

View File

@ -67,18 +67,18 @@ static std::size_t calculateWarningHash(const TokenList *tokenList, const std::s
} }
ErrorMessage::ErrorMessage() ErrorMessage::ErrorMessage()
: incomplete(false), severity(Severity::none), cwe(0U), inconclusive(false), hash(0) : incomplete(false), severity(Severity::none), cwe(0U), certainty(Certainty::normal), hash(0)
{ {
} }
ErrorMessage::ErrorMessage(const std::list<FileLocation> &callStack, const std::string& file1, Severity::SeverityType severity, const std::string &msg, const std::string &id, bool inconclusive) : ErrorMessage::ErrorMessage(const std::list<FileLocation> &callStack, const std::string& file1, Severity::SeverityType severity, const std::string &msg, const std::string &id, Certainty::CertaintyLevel certainty) :
callStack(callStack), // locations for this error message callStack(callStack), // locations for this error message
id(id), // set the message id id(id), // set the message id
file0(file1), file0(file1),
incomplete(false), incomplete(false),
severity(severity), // severity for this error message severity(severity), // severity for this error message
cwe(0U), cwe(0U),
inconclusive(inconclusive), certainty(certainty),
hash(0) hash(0)
{ {
// set the summary and verbose messages // set the summary and verbose messages
@ -87,22 +87,22 @@ ErrorMessage::ErrorMessage(const std::list<FileLocation> &callStack, const std::
ErrorMessage::ErrorMessage(const std::list<FileLocation> &callStack, const std::string& file1, Severity::SeverityType severity, const std::string &msg, const std::string &id, const CWE &cwe, bool inconclusive) : ErrorMessage::ErrorMessage(const std::list<FileLocation> &callStack, const std::string& file1, Severity::SeverityType severity, const std::string &msg, const std::string &id, const CWE &cwe, Certainty::CertaintyLevel certainty) :
callStack(callStack), // locations for this error message callStack(callStack), // locations for this error message
id(id), // set the message id id(id), // set the message id
file0(file1), file0(file1),
incomplete(false), incomplete(false),
severity(severity), // severity for this error message severity(severity), // severity for this error message
cwe(cwe.id), cwe(cwe.id),
inconclusive(inconclusive), certainty(certainty),
hash(0) hash(0)
{ {
// set the summary and verbose messages // set the summary and verbose messages
setmsg(msg); setmsg(msg);
} }
ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, bool inconclusive) ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, Certainty::CertaintyLevel certainty)
: id(id), incomplete(false), severity(severity), cwe(0U), inconclusive(inconclusive), hash(0) : id(id), incomplete(false), severity(severity), cwe(0U), certainty(certainty), hash(0)
{ {
// Format callstack // Format callstack
for (std::list<const Token *>::const_iterator it = callstack.begin(); it != callstack.end(); ++it) { for (std::list<const Token *>::const_iterator it = callstack.begin(); it != callstack.end(); ++it) {
@ -120,8 +120,8 @@ ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack, const Token
} }
ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, const CWE &cwe, bool inconclusive, bool bugHunting) ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, const CWE &cwe, Certainty::CertaintyLevel certainty, bool bugHunting)
: id(id), incomplete(false), severity(severity), cwe(cwe.id), inconclusive(inconclusive) : id(id), incomplete(false), severity(severity), cwe(cwe.id), certainty(certainty)
{ {
// Format callstack // Format callstack
for (const Token *tok: callstack) { for (const Token *tok: callstack) {
@ -145,8 +145,8 @@ ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack, const Token
hash = bugHunting ? calculateWarningHash(list, hashWarning.str()) : 0; hash = bugHunting ? calculateWarningHash(list, hashWarning.str()) : 0;
} }
ErrorMessage::ErrorMessage(const ErrorPath &errorPath, const TokenList *tokenList, Severity::SeverityType severity, const char id[], const std::string &msg, const CWE &cwe, bool inconclusive, bool bugHunting) ErrorMessage::ErrorMessage(const ErrorPath &errorPath, const TokenList *tokenList, Severity::SeverityType severity, const char id[], const std::string &msg, const CWE &cwe, Certainty::CertaintyLevel certainty, bool bugHunting)
: id(id), incomplete(false), severity(severity), cwe(cwe.id), inconclusive(inconclusive) : id(id), incomplete(false), severity(severity), cwe(cwe.id), certainty(certainty)
{ {
// Format callstack // Format callstack
for (const ErrorPathItem& e: errorPath) { for (const ErrorPathItem& e: errorPath) {
@ -181,7 +181,7 @@ ErrorMessage::ErrorMessage(const tinyxml2::XMLElement * const errmsg)
: incomplete(false), : incomplete(false),
severity(Severity::none), severity(Severity::none),
cwe(0U), cwe(0U),
inconclusive(false) certainty(Certainty::normal)
{ {
const char * const unknown = "<UNKNOWN>"; const char * const unknown = "<UNKNOWN>";
@ -195,7 +195,7 @@ ErrorMessage::ErrorMessage(const tinyxml2::XMLElement * const errmsg)
std::istringstream(attr ? attr : "0") >> cwe.id; std::istringstream(attr ? attr : "0") >> cwe.id;
attr = errmsg->Attribute("inconclusive"); attr = errmsg->Attribute("inconclusive");
inconclusive = attr && (std::strcmp(attr, "true") == 0); certainty = (attr && (std::strcmp(attr, "true") == 0)) ? Certainty::inconclusive : Certainty::normal;
attr = errmsg->Attribute("msg"); attr = errmsg->Attribute("msg");
mShortMessage = attr ? attr : ""; mShortMessage = attr ? attr : "";
@ -257,7 +257,7 @@ Suppressions::ErrorMessage ErrorMessage::toSuppressionsErrorMessage() const
ret.setFileName(callStack.back().getfile(false)); ret.setFileName(callStack.back().getfile(false));
ret.lineNumber = callStack.back().line; ret.lineNumber = callStack.back().line;
} }
ret.inconclusive = inconclusive; ret.certainty = certainty;
ret.symbolNames = mSymbolNames; ret.symbolNames = mSymbolNames;
return ret; return ret;
} }
@ -271,7 +271,7 @@ std::string ErrorMessage::serialize() const
oss << Severity::toString(severity).length() << " " << Severity::toString(severity); oss << Severity::toString(severity).length() << " " << Severity::toString(severity);
oss << MathLib::toString(cwe.id).length() << " " << MathLib::toString(cwe.id); oss << MathLib::toString(cwe.id).length() << " " << MathLib::toString(cwe.id);
oss << MathLib::toString(hash).length() << " " << MathLib::toString(hash); oss << MathLib::toString(hash).length() << " " << MathLib::toString(hash);
if (inconclusive) { if (certainty == Certainty::inconclusive) {
const std::string text("inconclusive"); const std::string text("inconclusive");
oss << text.length() << " " << text; oss << text.length() << " " << text;
} }
@ -294,7 +294,7 @@ std::string ErrorMessage::serialize() const
bool ErrorMessage::deserialize(const std::string &data) bool ErrorMessage::deserialize(const std::string &data)
{ {
inconclusive = false; certainty = Certainty::normal;
callStack.clear(); callStack.clear();
std::istringstream iss(data); std::istringstream iss(data);
std::array<std::string, 6> results; std::array<std::string, 6> results;
@ -312,7 +312,7 @@ bool ErrorMessage::deserialize(const std::string &data)
} }
if (temp == "inconclusive") { if (temp == "inconclusive") {
inconclusive = true; certainty = Certainty::inconclusive;
continue; continue;
} }
@ -436,7 +436,7 @@ std::string ErrorMessage::toXML() const
printer.PushAttribute("cwe", cwe.id); printer.PushAttribute("cwe", cwe.id);
if (hash) if (hash)
printer.PushAttribute("hash", MathLib::toString(hash).c_str()); printer.PushAttribute("hash", MathLib::toString(hash).c_str());
if (inconclusive) if (certainty == Certainty::inconclusive)
printer.PushAttribute("inconclusive", "true"); printer.PushAttribute("inconclusive", "true");
for (std::list<FileLocation>::const_reverse_iterator it = callStack.rbegin(); it != callStack.rend(); ++it) { for (std::list<FileLocation>::const_reverse_iterator it = callStack.rbegin(); it != callStack.rend(); ++it) {
@ -505,7 +505,7 @@ std::string ErrorMessage::toString(bool verbose, const std::string &templateForm
text << ErrorLogger::callStackToString(callStack) << ": "; text << ErrorLogger::callStackToString(callStack) << ": ";
if (severity != Severity::none) { if (severity != Severity::none) {
text << '(' << Severity::toString(severity); text << '(' << Severity::toString(severity);
if (inconclusive) if (certainty == Certainty::inconclusive)
text << ", inconclusive"; text << ", inconclusive";
text << ") "; text << ") ";
} }
@ -527,7 +527,7 @@ std::string ErrorMessage::toString(bool verbose, const std::string &templateForm
const std::string::size_type pos1 = result.find("{inconclusive:"); const std::string::size_type pos1 = result.find("{inconclusive:");
const std::string::size_type pos2 = result.find('}', pos1+1); const std::string::size_type pos2 = result.find('}', pos1+1);
const std::string replaceFrom = result.substr(pos1,pos2-pos1+1); const std::string replaceFrom = result.substr(pos1,pos2-pos1+1);
const std::string replaceWith = inconclusive ? result.substr(pos1+14, pos2-pos1-14) : std::string(); const std::string replaceWith = (certainty == Certainty::inconclusive) ? result.substr(pos1+14, pos2-pos1-14) : std::string();
findAndReplace(result, replaceFrom, replaceWith); findAndReplace(result, replaceFrom, replaceWith);
} }
findAndReplace(result, "{severity}", Severity::toString(severity)); findAndReplace(result, "{severity}", Severity::toString(severity));
@ -614,7 +614,7 @@ bool ErrorLogger::reportUnmatchedSuppressions(const std::list<Suppressions::Supp
std::list<ErrorMessage::FileLocation> callStack; std::list<ErrorMessage::FileLocation> callStack;
if (!s.fileName.empty()) if (!s.fileName.empty())
callStack.emplace_back(s.fileName, s.lineNumber, 0); callStack.emplace_back(s.fileName, s.lineNumber, 0);
reportErr(ErrorMessage(callStack, emptyString, Severity::information, "Unmatched suppression: " + s.errorId, "unmatchedSuppression", false)); reportErr(ErrorMessage(callStack, emptyString, Severity::information, "Unmatched suppression: " + s.errorId, "unmatchedSuppression", Certainty::normal));
err = true; err = true;
} }
return err; return err;

View File

@ -70,11 +70,11 @@ public:
: fileIndex(0), line(0), column(0) { : fileIndex(0), line(0), column(0) {
} }
FileLocation(const std::string &file, int line, int column) FileLocation(const std::string &file, int line, unsigned int column)
: fileIndex(0), line(line), column(column), mOrigFileName(file), mFileName(file) { : fileIndex(0), line(line), column(column), mOrigFileName(file), mFileName(file) {
} }
FileLocation(const std::string &file, const std::string &info, int line, int column) FileLocation(const std::string &file, const std::string &info, int line, unsigned int column)
: fileIndex(0), line(line), column(column), mOrigFileName(file), mFileName(file), mInfo(info) { : fileIndex(0), line(line), column(column), mOrigFileName(file), mFileName(file), mInfo(info) {
} }
@ -127,27 +127,27 @@ public:
const std::string& file1, const std::string& file1,
Severity::SeverityType severity, Severity::SeverityType severity,
const std::string &msg, const std::string &msg,
const std::string &id, bool inconclusive); const std::string &id, Certainty::CertaintyLevel certainty);
ErrorMessage(const std::list<FileLocation> &callStack, ErrorMessage(const std::list<FileLocation> &callStack,
const std::string& file1, const std::string& file1,
Severity::SeverityType severity, Severity::SeverityType severity,
const std::string &msg, const std::string &msg,
const std::string &id, const std::string &id,
const CWE &cwe, const CWE &cwe,
bool inconclusive); Certainty::CertaintyLevel certainty);
ErrorMessage(const std::list<const Token*>& callstack, ErrorMessage(const std::list<const Token*>& callstack,
const TokenList* list, const TokenList* list,
Severity::SeverityType severity, Severity::SeverityType severity,
const std::string& id, const std::string& id,
const std::string& msg, const std::string& msg,
bool inconclusive); Certainty::CertaintyLevel certainty);
ErrorMessage(const std::list<const Token*>& callstack, ErrorMessage(const std::list<const Token*>& callstack,
const TokenList* list, const TokenList* list,
Severity::SeverityType severity, Severity::SeverityType severity,
const std::string& id, const std::string& id,
const std::string& msg, const std::string& msg,
const CWE &cwe, const CWE &cwe,
bool inconclusive, Certainty::CertaintyLevel certainty,
bool bugHunting); bool bugHunting);
ErrorMessage(const ErrorPath &errorPath, ErrorMessage(const ErrorPath &errorPath,
const TokenList *tokenList, const TokenList *tokenList,
@ -155,7 +155,7 @@ public:
const char id[], const char id[],
const std::string &msg, const std::string &msg,
const CWE &cwe, const CWE &cwe,
bool inconclusive, Certainty::CertaintyLevel certainty,
bool bugHunting); bool bugHunting);
ErrorMessage(); ErrorMessage();
explicit ErrorMessage(const tinyxml2::XMLElement * const errmsg); explicit ErrorMessage(const tinyxml2::XMLElement * const errmsg);
@ -196,7 +196,7 @@ public:
Severity::SeverityType severity; Severity::SeverityType severity;
CWE cwe; CWE cwe;
bool inconclusive; Certainty::CertaintyLevel certainty;
/** Warning hash */ /** Warning hash */
std::size_t hash; std::size_t hash;

View File

@ -40,6 +40,20 @@ struct InternalError {
std::string id; std::string id;
}; };
class CPPCHECKLIB Certainty {
public:
enum CertaintyLevel {
normal, inconclusive, experimental
};
};
class CPPCHECKLIB Checks {
public:
enum CheckList {
unusedFunction, missingInclude, internalCheck
};
};
/** @brief enum class for severity. Used when reporting errors. */ /** @brief enum class for severity. Used when reporting errors. */
class CPPCHECKLIB Severity { class CPPCHECKLIB Severity {
public: public:

View File

@ -642,7 +642,7 @@ namespace {
ErrorPath e = errorPath; ErrorPath e = errorPath;
e.push_back(ErrorPathItem(tok, text)); e.push_back(ErrorPathItem(tok, text));
ErrorMessage errmsg(e, &tokenizer->list, severity, id, text, cwe, inconclusive, true); ErrorMessage errmsg(e, &tokenizer->list, severity, id, text, cwe, inconclusive ? Certainty::inconclusive : Certainty::normal, true);
errmsg.incomplete = incomplete; errmsg.incomplete = incomplete;
errmsg.function = functionName.empty() ? currentFunction : functionName; errmsg.function = functionName.empty() ? currentFunction : functionName;
errorLogger->reportErr(errmsg); errorLogger->reportErr(errmsg);

View File

@ -822,7 +822,7 @@ void Preprocessor::error(const std::string &filename, unsigned int linenr, const
Severity::error, Severity::error,
msg, msg,
"preprocessorErrorDirective", "preprocessorErrorDirective",
false)); Certainty::normal));
} }
// Report that include is missing // Report that include is missing
@ -857,7 +857,7 @@ void Preprocessor::missingInclude(const std::string &filename, unsigned int line
"Include file: <" + header + "> not found. Please note: Cppcheck does not need standard library headers to get proper results." : "Include file: <" + header + "> not found. Please note: Cppcheck does not need standard library headers to get proper results." :
"Include file: \"" + header + "\" not found.", "Include file: \"" + header + "\" not found.",
(headerType==SystemHeader) ? "missingIncludeSystem" : "missingInclude", (headerType==SystemHeader) ? "missingIncludeSystem" : "missingInclude",
false); Certainty::normal);
mErrorLogger->reportInfo(errmsg); mErrorLogger->reportInfo(errmsg);
} }
} }
@ -882,7 +882,7 @@ bool Preprocessor::validateCfg(const std::string &cfg, const std::list<simplecpp
}); });
if (!directiveLocation) { if (!directiveLocation) {
if (mSettings.isEnabled(Settings::INFORMATION)) if (mSettings.severity.isEnabled(Severity::information))
validateCfgError(mu.useLocation.file(), mu.useLocation.line, cfg, macroName); validateCfgError(mu.useLocation.file(), mu.useLocation.line, cfg, macroName);
ret = false; ret = false;
} }
@ -898,7 +898,7 @@ void Preprocessor::validateCfgError(const std::string &file, const unsigned int
std::list<ErrorMessage::FileLocation> locationList; std::list<ErrorMessage::FileLocation> locationList;
const ErrorMessage::FileLocation loc(file, line, 0); const ErrorMessage::FileLocation loc(file, line, 0);
locationList.push_back(loc); locationList.push_back(loc);
const ErrorMessage errmsg(locationList, mFile0, Severity::information, "Skipping configuration '" + cfg + "' since the value of '" + macro + "' is unknown. Use -D if you want to check it. You can use -U to skip it explicitly.", id, false); const ErrorMessage errmsg(locationList, mFile0, Severity::information, "Skipping configuration '" + cfg + "' since the value of '" + macro + "' is unknown. Use -D if you want to check it. You can use -U to skip it explicitly.", id, Certainty::normal);
mErrorLogger->reportInfo(errmsg); mErrorLogger->reportInfo(errmsg);
} }

View File

@ -29,8 +29,7 @@ const char Settings::SafeChecks::XmlInternalFunctions[] = "internal-functions";
const char Settings::SafeChecks::XmlExternalVariables[] = "external-variables"; const char Settings::SafeChecks::XmlExternalVariables[] = "external-variables";
Settings::Settings() Settings::Settings()
: mEnabled(0), : bugHunting(false),
bugHunting(false),
bugHuntingCheckFunctionMaxTime(60), bugHuntingCheckFunctionMaxTime(60),
checkAllConfigurations(true), checkAllConfigurations(true),
checkConfiguration(false), checkConfiguration(false),
@ -50,9 +49,7 @@ Settings::Settings()
enforcedLang(None), enforcedLang(None),
exceptionHandling(false), exceptionHandling(false),
exitCode(0), exitCode(0),
experimental(false),
force(false), force(false),
inconclusive(false),
inlineSuppressions(false), inlineSuppressions(false),
jobs(1), jobs(1),
jointSuppressionReport(false), jointSuppressionReport(false),
@ -69,6 +66,8 @@ Settings::Settings()
xml(false), xml(false),
xml_version(2) xml_version(2)
{ {
severity.setEnabled(Severity::error, true);
certainty.setEnabled(Certainty::normal, true);
} }
std::string Settings::addEnabled(const std::string &str) std::string Settings::addEnabled(const std::string &str)
@ -92,25 +91,28 @@ std::string Settings::addEnabled(const std::string &str)
} }
if (str == "all") { if (str == "all") {
mEnabled |= WARNING | STYLE | PERFORMANCE | PORTABILITY | INFORMATION | UNUSED_FUNCTION | MISSING_INCLUDE; severity.fill();
checks.enable(Checks::missingInclude);
checks.enable(Checks::unusedFunction);
} else if (str == "warning") { } else if (str == "warning") {
mEnabled |= WARNING; severity.enable(Severity::warning);
} else if (str == "style") { } else if (str == "style") {
mEnabled |= STYLE; severity.enable(Severity::style);
} else if (str == "performance") { } else if (str == "performance") {
mEnabled |= PERFORMANCE; severity.enable(Severity::performance);
} else if (str == "portability") { } else if (str == "portability") {
mEnabled |= PORTABILITY; severity.enable(Severity::portability);
} else if (str == "information") { } else if (str == "information") {
mEnabled |= INFORMATION | MISSING_INCLUDE; severity.enable(Severity::information);
checks.enable(Checks::missingInclude);
} else if (str == "unusedFunction") { } else if (str == "unusedFunction") {
mEnabled |= UNUSED_FUNCTION; checks.enable(Checks::unusedFunction);
} else if (str == "missingInclude") { } else if (str == "missingInclude") {
mEnabled |= MISSING_INCLUDE; checks.enable(Checks::missingInclude);
} }
#ifdef CHECK_INTERNAL #ifdef CHECK_INTERNAL
else if (str == "internal") { else if (str == "internal") {
mEnabled |= INTERNAL; checks.enable(Checks::internalCheck);
} }
#endif #endif
else { else {
@ -123,35 +125,11 @@ std::string Settings::addEnabled(const std::string &str)
return std::string(); return std::string();
} }
bool Settings::isEnabled(Severity::SeverityType severity) const
{
switch (severity) {
case Severity::none:
return true;
case Severity::error:
return true;
case Severity::warning:
return isEnabled(WARNING);
case Severity::style:
return isEnabled(STYLE);
case Severity::performance:
return isEnabled(PERFORMANCE);
case Severity::portability:
return isEnabled(PORTABILITY);
case Severity::information:
return isEnabled(INFORMATION);
case Severity::debug:
return false;
default:
return false;
}
}
bool Settings::isEnabled(const ValueFlow::Value *value, bool inconclusiveCheck) const bool Settings::isEnabled(const ValueFlow::Value *value, bool inconclusiveCheck) const
{ {
if (!isEnabled(Settings::WARNING) && (value->condition || value->defaultArg)) if (!severity.isEnabled(Severity::warning) && (value->condition || value->defaultArg))
return false; return false;
if (!inconclusive && (inconclusiveCheck || value->isInconclusive())) if (!certainty.isEnabled(Certainty::inconclusive) && (inconclusiveCheck || value->isInconclusive()))
return false; return false;
return true; return true;
} }

View File

@ -35,6 +35,7 @@
#include <set> #include <set>
#include <string> #include <string>
#include <vector> #include <vector>
#include <unordered_map>
namespace ValueFlow { namespace ValueFlow {
class Value; class Value;
@ -43,27 +44,50 @@ namespace ValueFlow {
/// @addtogroup Core /// @addtogroup Core
/// @{ /// @{
template<typename T>
class SimpleEnableGroup {
uint32_t flags = 0;
public:
uint32_t intValue() const {
return flags;
}
void clear() {
flags = 0;
}
void fill() {
flags = 0xFFFFFFFF;
}
void setEnabledAll(bool enabled) {
if (enabled)
fill();
else
clear();
}
bool isEnabled(T flag) const {
return (flags & (1U << (uint32_t)flag)) != 0;
}
void enable(T flag) {
flags |= (1U << (uint32_t)flag);
}
void disable(T flag) {
flags &= ~(1U << (uint32_t)flag);
}
void setEnabled(T flag, bool enabled) {
if (enabled)
enable(flag);
else
disable(flag);
}
};
/** /**
* @brief This is just a container for general settings so that we don't need * @brief This is just a container for general settings so that we don't need
* to pass individual values to functions or constructors now or in the * to pass individual values to functions or constructors now or in the
* future when we might have even more detailed settings. * future when we might have even more detailed settings.
*/ */
class CPPCHECKLIB Settings : public cppcheck::Platform { class CPPCHECKLIB Settings : public cppcheck::Platform {
public:
enum EnabledGroup {
WARNING = 0x1,
STYLE = 0x2,
PERFORMANCE = 0x4,
PORTABILITY = 0x8,
INFORMATION = 0x10,
UNUSED_FUNCTION = 0x20,
MISSING_INCLUDE = 0x40,
INTERNAL = 0x80
};
private: private:
/** @brief enable extra checks by id */
int mEnabled;
/** @brief terminate checking */ /** @brief terminate checking */
static std::atomic<bool> mTerminated; static std::atomic<bool> mTerminated;
@ -167,14 +191,6 @@ public:
Default value is 0. */ Default value is 0. */
int exitCode; int exitCode;
/**
* When this flag is false (default) then experimental
* heuristics and checks are disabled.
*
* It should not be possible to enable this from any client.
*/
bool experimental;
/** @brief --file-filter for analyzing special files */ /** @brief --file-filter for analyzing special files */
std::string fileFilter; std::string fileFilter;
@ -193,9 +209,6 @@ public:
for finding include files inside source files. (-I) */ for finding include files inside source files. (-I) */
std::list<std::string> includePaths; std::list<std::string> includePaths;
/** @brief Inconclusive checks */
bool inconclusive;
/** @brief Is --inline-suppr given? */ /** @brief Is --inline-suppr given? */
bool inlineSuppressions; bool inlineSuppressions;
@ -319,6 +332,10 @@ public:
SafeChecks safeChecks; SafeChecks safeChecks;
SimpleEnableGroup<Severity::SeverityType> severity;
SimpleEnableGroup<Certainty::CertaintyLevel> certainty;
SimpleEnableGroup<Checks::CheckList> checks;
/** @brief show timing information (--showtime=file|summary|top5) */ /** @brief show timing information (--showtime=file|summary|top5) */
SHOWTIME_MODES showtime; SHOWTIME_MODES showtime;
@ -372,29 +389,6 @@ public:
*/ */
std::string addEnabled(const std::string &str); std::string addEnabled(const std::string &str);
/**
* @brief Disables all severities, except from error.
*/
void clearEnabled() {
mEnabled = 0;
}
/**
* @brief Returns true if given id is in the list of
* enabled extra checks (--enable)
* @param group group to be enabled
* @return true if the check is enabled.
*/
bool isEnabled(EnabledGroup group) const {
return (mEnabled & group) == group;
}
/**
* @brief Returns true if given severity is enabled
* @return true if the check is enabled.
*/
bool isEnabled(Severity::SeverityType severity) const;
/** /**
* @brief Returns true if given value can be shown * @brief Returns true if given value can be shown
* @return true if the value can be shown * @return true if the value can be shown

View File

@ -21,6 +21,7 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include "config.h" #include "config.h"
#include "errortypes.h"
#include <istream> #include <istream>
#include <list> #include <list>
@ -42,7 +43,7 @@ public:
return mFileName; return mFileName;
} }
int lineNumber; int lineNumber;
bool inconclusive; Certainty::CertaintyLevel certainty;
std::string symbolNames; std::string symbolNames;
private: private:
std::string mFileName; std::string mFileName;

View File

@ -1775,7 +1775,7 @@ void SymbolDatabase::validateExecutableScopes() const
const ErrorMessage errmsg(callstack, &mTokenizer->list, Severity::debug, const ErrorMessage errmsg(callstack, &mTokenizer->list, Severity::debug,
"symbolDatabaseWarning", "symbolDatabaseWarning",
msg, msg,
false); Certainty::normal);
mErrorLogger->reportErr(errmsg); mErrorLogger->reportErr(errmsg);
} }
} }
@ -3091,7 +3091,7 @@ void SymbolDatabase::debugMessage(const Token *tok, const std::string &type, con
Severity::debug, Severity::debug,
type, type,
msg, msg,
false); Certainty::normal);
if (mErrorLogger) if (mErrorLogger)
mErrorLogger->reportErr(errmsg); mErrorLogger->reportErr(errmsg);
} }

View File

@ -1107,7 +1107,7 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration)
Severity::debug, Severity::debug,
"noparamend", "noparamend",
"TemplateSimplifier couldn't find end of template parameter.", "TemplateSimplifier couldn't find end of template parameter.",
false); Certainty::normal);
} }
break; break;
} }
@ -2973,8 +2973,8 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
"TemplateSimplifier: max template recursion (" "TemplateSimplifier: max template recursion ("
+ MathLib::toString(mSettings->maxTemplateRecursion) + MathLib::toString(mSettings->maxTemplateRecursion)
+ ") reached for template '"+typeForNewName+"'. You might want to limit Cppcheck recursion.", + ") reached for template '"+typeForNewName+"'. You might want to limit Cppcheck recursion.",
false); Certainty::normal);
if (mErrorLogger && mSettings->isEnabled(Settings::INFORMATION)) if (mErrorLogger && mSettings->severity.isEnabled(Severity::information))
mErrorLogger->reportErr(errmsg); mErrorLogger->reportErr(errmsg);
// bail out.. // bail out..
@ -3078,7 +3078,7 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
if (printDebug && mErrorLogger) { if (printDebug && mErrorLogger) {
std::list<const Token *> callstack(1, tok2); std::list<const Token *> callstack(1, tok2);
mErrorLogger->reportErr(ErrorMessage(callstack, &mTokenList, Severity::debug, "debug", mErrorLogger->reportErr(ErrorMessage(callstack, &mTokenList, Severity::debug, "debug",
"Failed to instantiate template \"" + instantiation.name() + "\". The checking continues anyway.", false)); "Failed to instantiate template \"" + instantiation.name() + "\". The checking continues anyway.", Certainty::normal));
} }
if (typeForNewName.empty()) if (typeForNewName.empty())
continue; continue;
@ -3146,7 +3146,7 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
if (printDebug && mErrorLogger) { if (printDebug && mErrorLogger) {
std::list<const Token *> callstack(1, tok2); std::list<const Token *> callstack(1, tok2);
mErrorLogger->reportErr(ErrorMessage(callstack, &mTokenList, Severity::debug, "debug", mErrorLogger->reportErr(ErrorMessage(callstack, &mTokenList, Severity::debug, "debug",
"Failed to instantiate template \"" + templateDeclaration.name() + "\". The checking continues anyway.", false)); "Failed to instantiate template \"" + templateDeclaration.name() + "\". The checking continues anyway.", Certainty::normal));
} }
return false; return false;
} }
@ -3778,7 +3778,7 @@ void TemplateSimplifier::simplifyTemplates(
Severity::debug, Severity::debug,
"debug", "debug",
"TemplateSimplifier: pass count limit hit before simplifications were finished.", "TemplateSimplifier: pass count limit hit before simplifications were finished.",
false); Certainty::normal);
if (mErrorLogger) if (mErrorLogger)
mErrorLogger->reportErr(errmsg); mErrorLogger->reportErr(errmsg);
} }

View File

@ -1810,9 +1810,9 @@ const ValueFlow::Value * Token::getValueLE(const MathLib::bigint val, const Sett
} }
} }
if (settings && ret) { if (settings && ret) {
if (ret->isInconclusive() && !settings->inconclusive) if (ret->isInconclusive() && !settings->certainty.isEnabled(Certainty::inconclusive))
return nullptr; return nullptr;
if (ret->condition && !settings->isEnabled(Settings::WARNING)) if (ret->condition && !settings->severity.isEnabled(Severity::warning))
return nullptr; return nullptr;
} }
return ret; return ret;
@ -1835,9 +1835,9 @@ const ValueFlow::Value * Token::getValueGE(const MathLib::bigint val, const Sett
} }
} }
if (settings && ret) { if (settings && ret) {
if (ret->isInconclusive() && !settings->inconclusive) if (ret->isInconclusive() && !settings->certainty.isEnabled(Certainty::inconclusive))
return nullptr; return nullptr;
if (ret->condition && !settings->isEnabled(Settings::WARNING)) if (ret->condition && !settings->severity.isEnabled(Severity::warning))
return nullptr; return nullptr;
} }
return ret; return ret;
@ -1861,9 +1861,9 @@ const ValueFlow::Value * Token::getInvalidValue(const Token *ftok, nonneg int ar
} }
} }
if (ret) { if (ret) {
if (ret->isInconclusive() && !settings->inconclusive) if (ret->isInconclusive() && !settings->certainty.isEnabled(Certainty::inconclusive))
return nullptr; return nullptr;
if (ret->condition && !settings->isEnabled(Settings::WARNING)) if (ret->condition && !settings->severity.isEnabled(Severity::warning))
return nullptr; return nullptr;
} }
return ret; return ret;

View File

@ -2598,7 +2598,7 @@ bool Tokenizer::simplifyUsing()
str += " ;"; str += " ;";
std::list<const Token *> callstack(1, usingStart); std::list<const Token *> callstack(1, usingStart);
mErrorLogger->reportErr(ErrorMessage(callstack, &list, Severity::debug, "debug", mErrorLogger->reportErr(ErrorMessage(callstack, &list, Severity::debug, "debug",
"Failed to parse \'" + str + "\'. The checking continues anyway.", false)); "Failed to parse \'" + str + "\'. The checking continues anyway.", Certainty::normal));
} }
} }
tok1 = after; tok1 = after;
@ -4975,7 +4975,7 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
} }
// class x y { // class x y {
if (isCPP() && mSettings->isEnabled(Settings::INFORMATION)) { if (isCPP() && mSettings->severity.isEnabled(Severity::information)) {
for (const Token *tok = list.front(); tok; tok = tok->next()) { for (const Token *tok = list.front(); tok; tok = tok->next()) {
if (Token::Match(tok, "class %type% %type% [:{]")) { if (Token::Match(tok, "class %type% %type% [:{]")) {
unhandled_macro_class_x_y(tok); unhandled_macro_class_x_y(tok);
@ -9103,7 +9103,7 @@ bool Tokenizer::isScopeNoReturn(const Token *endScopeToken, bool *unknown) const
} }
if (unknown) if (unknown)
*unknown = !unknownFunc.empty(); *unknown = !unknownFunc.empty();
if (!unknownFunc.empty() && mSettings->checkLibrary && mSettings->isEnabled(Settings::INFORMATION)) { if (!unknownFunc.empty() && mSettings->checkLibrary && mSettings->severity.isEnabled(Severity::information)) {
// Is function global? // Is function global?
bool globalFunction = true; bool globalFunction = true;
if (Token::simpleMatch(endScopeToken->tokAt(-2), ") ; }")) { if (Token::simpleMatch(endScopeToken->tokAt(-2), ") ; }")) {
@ -12196,7 +12196,7 @@ void Tokenizer::reportError(const Token* tok, const Severity::SeverityType sever
void Tokenizer::reportError(const std::list<const Token*>& callstack, Severity::SeverityType severity, const std::string& id, const std::string& msg, bool inconclusive) const void Tokenizer::reportError(const std::list<const Token*>& callstack, Severity::SeverityType severity, const std::string& id, const std::string& msg, bool inconclusive) const
{ {
const ErrorMessage errmsg(callstack, &list, severity, id, msg, inconclusive); const ErrorMessage errmsg(callstack, &list, severity, id, msg, inconclusive ? Certainty::inconclusive : Certainty::normal);
if (mErrorLogger) if (mErrorLogger)
mErrorLogger->reportErr(errmsg); mErrorLogger->reportErr(errmsg);
else else

View File

@ -118,7 +118,7 @@ static void bailoutInternal(const std::string& type, TokenList *tokenlist, Error
function = "(valueFlow)"; function = "(valueFlow)";
std::list<ErrorMessage::FileLocation> callstack(1, ErrorMessage::FileLocation(tok, tokenlist)); std::list<ErrorMessage::FileLocation> callstack(1, ErrorMessage::FileLocation(tok, tokenlist));
ErrorMessage errmsg(callstack, tokenlist->getSourceFilePath(), Severity::debug, ErrorMessage errmsg(callstack, tokenlist->getSourceFilePath(), Severity::debug,
Path::stripDirectoryPart(file) + ":" + MathLib::toString(line) + ":" + function + " bailout: " + what, type, false); Path::stripDirectoryPart(file) + ":" + MathLib::toString(line) + ":" + function + " bailout: " + what, type, Certainty::normal);
errorLogger->reportErr(errmsg); errorLogger->reportErr(errmsg);
} }
@ -3108,7 +3108,7 @@ struct LifetimeStore {
return false; return false;
bool update = false; bool update = false;
for (const LifetimeToken& lt : getLifetimeTokens(argtok)) { for (const LifetimeToken& lt : getLifetimeTokens(argtok)) {
if (!settings->inconclusive && lt.inconclusive) if (!settings->certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive)
continue; continue;
ErrorPath er = errorPath; ErrorPath er = errorPath;
er.insert(er.end(), lt.errorPath.begin(), lt.errorPath.end()); er.insert(er.end(), lt.errorPath.begin(), lt.errorPath.end());
@ -3171,7 +3171,7 @@ struct LifetimeStore {
continue; continue;
const Token *tok3 = v.tokvalue; const Token *tok3 = v.tokvalue;
for (const LifetimeToken& lt : getLifetimeTokens(tok3)) { for (const LifetimeToken& lt : getLifetimeTokens(tok3)) {
if (!settings->inconclusive && lt.inconclusive) if (!settings->certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive)
continue; continue;
ErrorPath er = v.errorPath; ErrorPath er = v.errorPath;
er.insert(er.end(), lt.errorPath.begin(), lt.errorPath.end()); er.insert(er.end(), lt.errorPath.begin(), lt.errorPath.end());
@ -3210,7 +3210,7 @@ struct LifetimeStore {
template <class Predicate> template <class Predicate>
void byDerefCopy(Token *tok, TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings, Predicate pred) const { void byDerefCopy(Token *tok, TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings, Predicate pred) const {
if (!settings->inconclusive && inconclusive) if (!settings->certainty.isEnabled(Certainty::inconclusive) && inconclusive)
return; return;
if (!argtok) if (!argtok)
return; return;
@ -3573,7 +3573,7 @@ static void valueFlowLifetime(TokenList *tokenlist, SymbolDatabase*, ErrorLogger
// address of // address of
else if (tok->isUnaryOp("&")) { else if (tok->isUnaryOp("&")) {
for (const LifetimeToken& lt : getLifetimeTokens(tok->astOperand1())) { for (const LifetimeToken& lt : getLifetimeTokens(tok->astOperand1())) {
if (!settings->inconclusive && lt.inconclusive) if (!settings->certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive)
continue; continue;
ErrorPath errorPath = lt.errorPath; ErrorPath errorPath = lt.errorPath;
errorPath.emplace_back(tok, "Address of variable taken here."); errorPath.emplace_back(tok, "Address of variable taken here.");

View File

@ -32,7 +32,7 @@ private:
Settings settings; Settings settings;
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("portability"); settings.severity.enable(Severity::portability);
TEST_CASE(novardecl); TEST_CASE(novardecl);
TEST_CASE(functionpar); TEST_CASE(functionpar);

View File

@ -45,7 +45,7 @@ private:
} }
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
TEST_CASE(assignmentInAssert); TEST_CASE(assignmentInAssert);
TEST_CASE(functionCallInAssert); TEST_CASE(functionCallInAssert);

View File

@ -35,7 +35,7 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
settings.inconclusive = inconclusive; settings.certainty.setEnabled(Certainty::inconclusive, inconclusive);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
@ -47,8 +47,8 @@ private:
} }
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
settings.addEnabled("style"); settings.severity.enable(Severity::style);
LOAD_LIB_2(settings.library, "std.cfg"); LOAD_LIB_2(settings.library, "std.cfg");
LOAD_LIB_2(settings.library, "qt.cfg"); LOAD_LIB_2(settings.library, "qt.cfg");

View File

@ -32,9 +32,9 @@ private:
Settings settings; Settings settings;
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("style"); settings.severity.enable(Severity::style);
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
settings.inconclusive = true; settings.certainty.enable(Certainty::inconclusive);
TEST_CASE(bitwiseOnBoolean); // if (bool & bool) TEST_CASE(bitwiseOnBoolean); // if (bool & bool)
TEST_CASE(incrementBoolean); TEST_CASE(incrementBoolean);
@ -80,7 +80,7 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
settings.experimental = experimental; settings.certainty.setEnabled(Certainty::experimental, experimental);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);

View File

@ -32,8 +32,8 @@ private:
Settings settings; Settings settings;
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("style"); settings.severity.enable(Severity::style);
settings.addEnabled("performance"); settings.severity.enable(Severity::performance);
TEST_CASE(BoostForeachContainerModification); TEST_CASE(BoostForeachContainerModification);
} }

View File

@ -45,8 +45,8 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
settings0.inconclusive = true; settings0.certainty.enable(Certainty::inconclusive);
settings0.experimental = experimental; settings0.certainty.setEnabled(Certainty::experimental, experimental);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings0, this); Tokenizer tokenizer(&settings0, this);
@ -74,9 +74,9 @@ private:
void run() OVERRIDE { void run() OVERRIDE {
LOAD_LIB_2(settings0.library, "std.cfg"); LOAD_LIB_2(settings0.library, "std.cfg");
settings0.addEnabled("warning"); settings0.severity.enable(Severity::warning);
settings0.addEnabled("style"); settings0.severity.enable(Severity::style);
settings0.addEnabled("portability"); settings0.severity.enable(Severity::portability);
TEST_CASE(noerr1); TEST_CASE(noerr1);
TEST_CASE(noerr2); TEST_CASE(noerr2);
@ -3324,7 +3324,7 @@ private:
tinyxml2::XMLDocument doc; tinyxml2::XMLDocument doc;
doc.Parse(xmldata, sizeof(xmldata)); doc.Parse(xmldata, sizeof(xmldata));
settings.library.load(doc); settings.library.load(doc);
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
settings.sizeof_wchar_t = 4; settings.sizeof_wchar_t = 4;
check("void f() {\n" check("void f() {\n"

View File

@ -34,8 +34,8 @@ private:
void run() OVERRIDE { void run() OVERRIDE {
settings.platform(Settings::Unspecified); settings.platform(Settings::Unspecified);
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
settings.addEnabled("portability"); settings.severity.enable(Severity::portability);
TEST_CASE(array_index_1); TEST_CASE(array_index_1);
TEST_CASE(array_index_2); TEST_CASE(array_index_2);

View File

@ -36,8 +36,8 @@ private:
Settings settings1; Settings settings1;
void run() OVERRIDE { void run() OVERRIDE {
settings0.addEnabled("style"); settings0.severity.enable(Severity::style);
settings1.addEnabled("warning"); settings1.severity.enable(Severity::warning);
// Load std.cfg configuration // Load std.cfg configuration
{ {
@ -231,7 +231,7 @@ private:
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
Settings settings; Settings settings;
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
@ -2427,8 +2427,8 @@ private:
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
settings0.inconclusive = inconclusive; settings0.certainty.setEnabled(Certainty::inconclusive, inconclusive);
settings0.addEnabled("warning"); settings0.severity.enable(Severity::warning);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings0, this); Tokenizer tokenizer(&settings0, this);
@ -2719,8 +2719,8 @@ private:
void checkNoMemset(const char code[]) { void checkNoMemset(const char code[]) {
Settings settings; Settings settings;
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
settings.addEnabled("portability"); settings.severity.enable(Severity::portability);
checkNoMemset(code,settings); checkNoMemset(code,settings);
} }
@ -3353,7 +3353,7 @@ private:
// Check.. // Check..
if (!s) if (!s)
s = &settings0; s = &settings0;
s->inconclusive = inconclusive; s->certainty.setEnabled(Certainty::inconclusive, inconclusive);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(s, this); Tokenizer tokenizer(s, this);
@ -6539,7 +6539,7 @@ private:
errout.str(""); errout.str("");
// Check.. // Check..
settings0.inconclusive = true; settings0.certainty.setEnabled(Certainty::inconclusive, true);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings0, this); Tokenizer tokenizer(&settings0, this);
@ -6574,7 +6574,7 @@ private:
// Check.. // Check..
Settings settings; Settings settings;
settings.addEnabled("performance"); settings.severity.enable(Severity::performance);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
@ -6884,9 +6884,9 @@ private:
if (!s) { if (!s) {
static Settings settings_; static Settings settings_;
s = &settings_; s = &settings_;
s->addEnabled("warning"); s->severity.enable(Severity::warning);
} }
s->inconclusive = inconclusive; s->certainty.setEnabled(Certainty::inconclusive, inconclusive);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(s, this); Tokenizer tokenizer(s, this);
@ -7137,7 +7137,7 @@ private:
// Clear the error log // Clear the error log
errout.str(""); errout.str("");
Settings settings; Settings settings;
settings.addEnabled("style"); settings.severity.enable(Severity::style);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
@ -7220,7 +7220,7 @@ private:
errout.str(""); errout.str("");
Settings settings; Settings settings;
settings.safeChecks.classes = true; settings.safeChecks.classes = true;
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);

View File

@ -470,11 +470,11 @@ private:
const char * const argv[] = {"cppcheck", "--enable=all", "file.cpp"}; const char * const argv[] = {"cppcheck", "--enable=all", "file.cpp"};
settings = Settings(); settings = Settings();
ASSERT(defParser.parseFromArgs(3, argv)); ASSERT(defParser.parseFromArgs(3, argv));
ASSERT(settings.isEnabled(Settings::STYLE)); ASSERT(settings.severity.isEnabled(Severity::style));
ASSERT(settings.isEnabled(Settings::WARNING)); ASSERT(settings.severity.isEnabled(Severity::warning));
ASSERT(settings.isEnabled(Settings::UNUSED_FUNCTION)); ASSERT(settings.checks.isEnabled(Checks::unusedFunction));
ASSERT(settings.isEnabled(Settings::MISSING_INCLUDE)); ASSERT(settings.checks.isEnabled(Checks::missingInclude));
ASSERT(!settings.isEnabled(Settings::INTERNAL)); ASSERT(!settings.checks.isEnabled(Checks::internalCheck));
} }
void enabledStyle() { void enabledStyle() {
@ -482,12 +482,12 @@ private:
const char * const argv[] = {"cppcheck", "--enable=style", "file.cpp"}; const char * const argv[] = {"cppcheck", "--enable=style", "file.cpp"};
settings = Settings(); settings = Settings();
ASSERT(defParser.parseFromArgs(3, argv)); ASSERT(defParser.parseFromArgs(3, argv));
ASSERT(settings.isEnabled(Settings::STYLE)); ASSERT(settings.severity.isEnabled(Severity::style));
ASSERT(settings.isEnabled(Settings::WARNING)); ASSERT(settings.severity.isEnabled(Severity::warning));
ASSERT(settings.isEnabled(Settings::PERFORMANCE)); ASSERT(settings.severity.isEnabled(Severity::performance));
ASSERT(settings.isEnabled(Settings::PORTABILITY)); ASSERT(settings.severity.isEnabled(Severity::portability));
ASSERT(!settings.isEnabled(Settings::UNUSED_FUNCTION)); ASSERT(!settings.checks.isEnabled(Checks::unusedFunction));
ASSERT(!settings.isEnabled(Settings::MISSING_INCLUDE)); ASSERT(!settings.checks.isEnabled(Checks::internalCheck));
} }
void enabledPerformance() { void enabledPerformance() {
@ -495,12 +495,12 @@ private:
const char * const argv[] = {"cppcheck", "--enable=performance", "file.cpp"}; const char * const argv[] = {"cppcheck", "--enable=performance", "file.cpp"};
settings = Settings(); settings = Settings();
ASSERT(defParser.parseFromArgs(3, argv)); ASSERT(defParser.parseFromArgs(3, argv));
ASSERT(!settings.isEnabled(Settings::STYLE)); ASSERT(!settings.severity.isEnabled(Severity::style));
ASSERT(!settings.isEnabled(Settings::WARNING)); ASSERT(!settings.severity.isEnabled(Severity::warning));
ASSERT(settings.isEnabled(Settings::PERFORMANCE)); ASSERT(settings.severity.isEnabled(Severity::performance));
ASSERT(!settings.isEnabled(Settings::PORTABILITY)); ASSERT(!settings.severity.isEnabled(Severity::portability));
ASSERT(!settings.isEnabled(Settings::UNUSED_FUNCTION)); ASSERT(!settings.checks.isEnabled(Checks::unusedFunction));
ASSERT(!settings.isEnabled(Settings::MISSING_INCLUDE)); ASSERT(!settings.checks.isEnabled(Checks::missingInclude));
} }
void enabledPortability() { void enabledPortability() {
@ -508,12 +508,12 @@ private:
const char * const argv[] = {"cppcheck", "--enable=portability", "file.cpp"}; const char * const argv[] = {"cppcheck", "--enable=portability", "file.cpp"};
settings = Settings(); settings = Settings();
ASSERT(defParser.parseFromArgs(3, argv)); ASSERT(defParser.parseFromArgs(3, argv));
ASSERT(!settings.isEnabled(Settings::STYLE)); ASSERT(!settings.severity.isEnabled(Severity::style));
ASSERT(!settings.isEnabled(Settings::WARNING)); ASSERT(!settings.severity.isEnabled(Severity::warning));
ASSERT(!settings.isEnabled(Settings::PERFORMANCE)); ASSERT(!settings.severity.isEnabled(Severity::performance));
ASSERT(settings.isEnabled(Settings::PORTABILITY)); ASSERT(settings.severity.isEnabled(Severity::portability));
ASSERT(!settings.isEnabled(Settings::UNUSED_FUNCTION)); ASSERT(!settings.checks.isEnabled(Checks::unusedFunction));
ASSERT(!settings.isEnabled(Settings::MISSING_INCLUDE)); ASSERT(!settings.checks.isEnabled(Checks::missingInclude));
} }
void enabledUnusedFunction() { void enabledUnusedFunction() {
@ -521,7 +521,7 @@ private:
const char * const argv[] = {"cppcheck", "--enable=unusedFunction", "file.cpp"}; const char * const argv[] = {"cppcheck", "--enable=unusedFunction", "file.cpp"};
settings = Settings(); settings = Settings();
ASSERT(defParser.parseFromArgs(3, argv)); ASSERT(defParser.parseFromArgs(3, argv));
ASSERT(settings.isEnabled(Settings::UNUSED_FUNCTION)); ASSERT(settings.checks.isEnabled(Checks::unusedFunction));
} }
void enabledMissingInclude() { void enabledMissingInclude() {
@ -529,7 +529,7 @@ private:
const char * const argv[] = {"cppcheck", "--enable=missingInclude", "file.cpp"}; const char * const argv[] = {"cppcheck", "--enable=missingInclude", "file.cpp"};
settings = Settings(); settings = Settings();
ASSERT(defParser.parseFromArgs(3, argv)); ASSERT(defParser.parseFromArgs(3, argv));
ASSERT(settings.isEnabled(Settings::MISSING_INCLUDE)); ASSERT(settings.checks.isEnabled(Checks::missingInclude));
} }
#ifdef CHECK_INTERNAL #ifdef CHECK_INTERNAL
@ -547,20 +547,20 @@ private:
const char * const argv[] = {"cppcheck", "--enable=missingInclude,portability,warning", "file.cpp"}; const char * const argv[] = {"cppcheck", "--enable=missingInclude,portability,warning", "file.cpp"};
settings = Settings(); settings = Settings();
ASSERT(defParser.parseFromArgs(3, argv)); ASSERT(defParser.parseFromArgs(3, argv));
ASSERT(!settings.isEnabled(Settings::STYLE)); ASSERT(!settings.severity.isEnabled(Severity::style));
ASSERT(settings.isEnabled(Settings::WARNING)); ASSERT(settings.severity.isEnabled(Severity::warning));
ASSERT(!settings.isEnabled(Settings::PERFORMANCE)); ASSERT(!settings.severity.isEnabled(Severity::performance));
ASSERT(settings.isEnabled(Settings::PORTABILITY)); ASSERT(settings.severity.isEnabled(Severity::portability));
ASSERT(!settings.isEnabled(Settings::UNUSED_FUNCTION)); ASSERT(!settings.checks.isEnabled(Checks::unusedFunction));
ASSERT(settings.isEnabled(Settings::MISSING_INCLUDE)); ASSERT(settings.checks.isEnabled(Checks::missingInclude));
} }
void inconclusive() { void inconclusive() {
REDIRECT; REDIRECT;
const char * const argv[] = {"cppcheck", "--inconclusive"}; const char * const argv[] = {"cppcheck", "--inconclusive"};
settings.inconclusive = false; settings.certainty.clear();
ASSERT(defParser.parseFromArgs(2, argv)); ASSERT(defParser.parseFromArgs(2, argv));
ASSERT_EQUALS(true, settings.inconclusive); ASSERT_EQUALS(true, settings.certainty.isEnabled(Certainty::inconclusive));
} }
void errorExitcode() { void errorExitcode() {

View File

@ -41,8 +41,8 @@ private:
LOAD_LIB_2(settings0.library, "qt.cfg"); LOAD_LIB_2(settings0.library, "qt.cfg");
LOAD_LIB_2(settings0.library, "std.cfg"); LOAD_LIB_2(settings0.library, "std.cfg");
settings0.addEnabled("style"); settings0.severity.enable(Severity::style);
settings0.addEnabled("warning"); settings0.severity.enable(Severity::warning);
const char cfg[] = "<?xml version=\"1.0\"?>\n" const char cfg[] = "<?xml version=\"1.0\"?>\n"
"<def>\n" "<def>\n"
@ -50,8 +50,8 @@ private:
"</def>"; "</def>";
tinyxml2::XMLDocument xmldoc; tinyxml2::XMLDocument xmldoc;
xmldoc.Parse(cfg, sizeof(cfg)); xmldoc.Parse(cfg, sizeof(cfg));
settings1.addEnabled("style"); settings1.severity.enable(Severity::style);
settings1.addEnabled("warning"); settings1.severity.enable(Severity::warning);
settings1.library.load(xmldoc); settings1.library.load(xmldoc);
TEST_CASE(assignAndCompare); // assignment and comparison don't match TEST_CASE(assignAndCompare); // assignment and comparison don't match
@ -126,7 +126,7 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
settings0.inconclusive = inconclusive; settings0.certainty.setEnabled(Certainty::inconclusive, inconclusive);
// Raw tokens.. // Raw tokens..
std::vector<std::string> files(1, filename); std::vector<std::string> files(1, filename);

View File

@ -35,7 +35,7 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
settings.inconclusive = inconclusive; settings.certainty.setEnabled(Certainty::inconclusive, inconclusive);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
@ -48,8 +48,8 @@ private:
} }
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("style"); settings.severity.enable(Severity::style);
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
TEST_CASE(simple1); TEST_CASE(simple1);
TEST_CASE(simple2); TEST_CASE(simple2);

View File

@ -112,7 +112,7 @@ private:
void ErrorMessageConstruct() const { void ErrorMessageConstruct() const {
std::list<ErrorMessage::FileLocation> locs(1, fooCpp5); std::list<ErrorMessage::FileLocation> locs(1, fooCpp5);
ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.", "errorId", false); ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.", "errorId", Certainty::normal);
ASSERT_EQUALS(1, msg.callStack.size()); ASSERT_EQUALS(1, msg.callStack.size());
ASSERT_EQUALS("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Programming error.", msg.shortMessage());
ASSERT_EQUALS("Programming error.", msg.verboseMessage()); ASSERT_EQUALS("Programming error.", msg.verboseMessage());
@ -122,7 +122,7 @@ private:
void ErrorMessageConstructLocations() const { void ErrorMessageConstructLocations() const {
std::list<ErrorMessage::FileLocation> locs = { fooCpp5, barCpp8 }; std::list<ErrorMessage::FileLocation> locs = { fooCpp5, barCpp8 };
ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.", "errorId", false); ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.", "errorId", Certainty::normal);
ASSERT_EQUALS(2, msg.callStack.size()); ASSERT_EQUALS(2, msg.callStack.size());
ASSERT_EQUALS("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Programming error.", msg.shortMessage());
ASSERT_EQUALS("Programming error.", msg.verboseMessage()); ASSERT_EQUALS("Programming error.", msg.verboseMessage());
@ -132,7 +132,7 @@ private:
void ErrorMessageVerbose() const { void ErrorMessageVerbose() const {
std::list<ErrorMessage::FileLocation> locs(1, fooCpp5); std::list<ErrorMessage::FileLocation> locs(1, fooCpp5);
ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.\nVerbose error", "errorId", false); ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.\nVerbose error", "errorId", Certainty::normal);
ASSERT_EQUALS(1, msg.callStack.size()); ASSERT_EQUALS(1, msg.callStack.size());
ASSERT_EQUALS("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Programming error.", msg.shortMessage());
ASSERT_EQUALS("Verbose error", msg.verboseMessage()); ASSERT_EQUALS("Verbose error", msg.verboseMessage());
@ -142,7 +142,7 @@ private:
void ErrorMessageVerboseLocations() const { void ErrorMessageVerboseLocations() const {
std::list<ErrorMessage::FileLocation> locs = { fooCpp5, barCpp8 }; std::list<ErrorMessage::FileLocation> locs = { fooCpp5, barCpp8 };
ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.\nVerbose error", "errorId", false); ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.\nVerbose error", "errorId", Certainty::normal);
ASSERT_EQUALS(2, msg.callStack.size()); ASSERT_EQUALS(2, msg.callStack.size());
ASSERT_EQUALS("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Programming error.", msg.shortMessage());
ASSERT_EQUALS("Verbose error", msg.verboseMessage()); ASSERT_EQUALS("Verbose error", msg.verboseMessage());
@ -152,7 +152,7 @@ private:
void CustomFormat() const { void CustomFormat() const {
std::list<ErrorMessage::FileLocation> locs(1, fooCpp5); std::list<ErrorMessage::FileLocation> locs(1, fooCpp5);
ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.\nVerbose error", "errorId", false); ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.\nVerbose error", "errorId", Certainty::normal);
ASSERT_EQUALS(1, msg.callStack.size()); ASSERT_EQUALS(1, msg.callStack.size());
ASSERT_EQUALS("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Programming error.", msg.shortMessage());
ASSERT_EQUALS("Verbose error", msg.verboseMessage()); ASSERT_EQUALS("Verbose error", msg.verboseMessage());
@ -162,7 +162,7 @@ private:
void CustomFormat2() const { void CustomFormat2() const {
std::list<ErrorMessage::FileLocation> locs(1, fooCpp5); std::list<ErrorMessage::FileLocation> locs(1, fooCpp5);
ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.\nVerbose error", "errorId", false); ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.\nVerbose error", "errorId", Certainty::normal);
ASSERT_EQUALS(1, msg.callStack.size()); ASSERT_EQUALS(1, msg.callStack.size());
ASSERT_EQUALS("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Programming error.", msg.shortMessage());
ASSERT_EQUALS("Verbose error", msg.verboseMessage()); ASSERT_EQUALS("Verbose error", msg.verboseMessage());
@ -173,7 +173,7 @@ private:
void CustomFormatLocations() const { void CustomFormatLocations() const {
// Check that first location from location stack is used in template // Check that first location from location stack is used in template
std::list<ErrorMessage::FileLocation> locs = { fooCpp5, barCpp8 }; std::list<ErrorMessage::FileLocation> locs = { fooCpp5, barCpp8 };
ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.\nVerbose error", "errorId", false); ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.\nVerbose error", "errorId", Certainty::normal);
ASSERT_EQUALS(2, msg.callStack.size()); ASSERT_EQUALS(2, msg.callStack.size());
ASSERT_EQUALS("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Programming error.", msg.shortMessage());
ASSERT_EQUALS("Verbose error", msg.verboseMessage()); ASSERT_EQUALS("Verbose error", msg.verboseMessage());
@ -183,7 +183,7 @@ private:
void ToXmlV2() const { void ToXmlV2() const {
std::list<ErrorMessage::FileLocation> locs(1, fooCpp5); std::list<ErrorMessage::FileLocation> locs(1, fooCpp5);
ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.\nVerbose error", "errorId", false); ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.\nVerbose error", "errorId", Certainty::normal);
std::string header("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results version=\"2\">\n"); std::string header("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results version=\"2\">\n");
header += " <cppcheck version=\""; header += " <cppcheck version=\"";
header += CppCheck::version(); header += CppCheck::version();
@ -199,7 +199,7 @@ private:
void ToXmlV2Locations() const { void ToXmlV2Locations() const {
std::list<ErrorMessage::FileLocation> locs = { fooCpp5, barCpp8 }; std::list<ErrorMessage::FileLocation> locs = { fooCpp5, barCpp8 };
locs.back().setinfo("ä"); locs.back().setinfo("ä");
ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.\nVerbose error", "errorId", false); ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.\nVerbose error", "errorId", Certainty::normal);
std::string header("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results version=\"2\">\n"); std::string header("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results version=\"2\">\n");
header += " <cppcheck version=\""; header += " <cppcheck version=\"";
header += CppCheck::version(); header += CppCheck::version();
@ -216,7 +216,7 @@ private:
void ToXmlV2Encoding() const { void ToXmlV2Encoding() const {
{ {
std::list<ErrorMessage::FileLocation> locs; std::list<ErrorMessage::FileLocation> locs;
ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.\nComparing \"\203\" with \"\003\"", "errorId", false); ErrorMessage msg(locs, emptyString, Severity::error, "Programming error.\nComparing \"\203\" with \"\003\"", "errorId", Certainty::normal);
const std::string expected(" <error id=\"errorId\" severity=\"error\" msg=\"Programming error.\" verbose=\"Comparing &quot;\\203&quot; with &quot;\\003&quot;\"/>"); const std::string expected(" <error id=\"errorId\" severity=\"error\" msg=\"Programming error.\" verbose=\"Comparing &quot;\\203&quot; with &quot;\\003&quot;\"/>");
ASSERT_EQUALS(expected, msg.toXML()); ASSERT_EQUALS(expected, msg.toXML());
} }
@ -224,9 +224,9 @@ private:
const char code1[]="äöü"; const char code1[]="äöü";
const char code2[]="\x12\x00\x00\x01"; const char code2[]="\x12\x00\x00\x01";
std::list<ErrorMessage::FileLocation> locs; std::list<ErrorMessage::FileLocation> locs;
ErrorMessage msg1(locs, emptyString, Severity::error, std::string("Programming error.\nReading \"")+code1+"\"", "errorId", false); ErrorMessage msg1(locs, emptyString, Severity::error, std::string("Programming error.\nReading \"")+code1+"\"", "errorId", Certainty::normal);
ASSERT_EQUALS(" <error id=\"errorId\" severity=\"error\" msg=\"Programming error.\" verbose=\"Reading &quot;\\303\\244\\303\\266\\303\\274&quot;\"/>", msg1.toXML()); ASSERT_EQUALS(" <error id=\"errorId\" severity=\"error\" msg=\"Programming error.\" verbose=\"Reading &quot;\\303\\244\\303\\266\\303\\274&quot;\"/>", msg1.toXML());
ErrorMessage msg2(locs, emptyString, Severity::error, std::string("Programming error.\nReading \"")+code2+"\"", "errorId", false); ErrorMessage msg2(locs, emptyString, Severity::error, std::string("Programming error.\nReading \"")+code2+"\"", "errorId", Certainty::normal);
ASSERT_EQUALS(" <error id=\"errorId\" severity=\"error\" msg=\"Programming error.\" verbose=\"Reading &quot;\\022&quot;\"/>", msg2.toXML()); ASSERT_EQUALS(" <error id=\"errorId\" severity=\"error\" msg=\"Programming error.\" verbose=\"Reading &quot;\\022&quot;\"/>", msg2.toXML());
} }
} }
@ -236,7 +236,7 @@ private:
std::list<ErrorMessage::FileLocation> locs(1, fooCpp5); std::list<ErrorMessage::FileLocation> locs(1, fooCpp5);
// Inconclusive error message // Inconclusive error message
ErrorMessage msg(locs, emptyString, Severity::error, "Programming error", "errorId", true); ErrorMessage msg(locs, emptyString, Severity::error, "Programming error", "errorId", Certainty::inconclusive);
// xml version 2 error message // xml version 2 error message
ASSERT_EQUALS(" <error id=\"errorId\" severity=\"error\" msg=\"Programming error\" verbose=\"Programming error\" inconclusive=\"true\">\n" ASSERT_EQUALS(" <error id=\"errorId\" severity=\"error\" msg=\"Programming error\" verbose=\"Programming error\" inconclusive=\"true\">\n"
@ -248,7 +248,7 @@ private:
void SerializeInconclusiveMessage() const { void SerializeInconclusiveMessage() const {
// Inconclusive error message // Inconclusive error message
std::list<ErrorMessage::FileLocation> locs; std::list<ErrorMessage::FileLocation> locs;
ErrorMessage msg(locs, emptyString, Severity::error, "Programming error", "errorId", true); ErrorMessage msg(locs, emptyString, Severity::error, "Programming error", "errorId", Certainty::inconclusive);
ASSERT_EQUALS("7 errorId" ASSERT_EQUALS("7 errorId"
"5 error" "5 error"
"1 0" "1 0"
@ -262,7 +262,7 @@ private:
msg2.deserialize(msg.serialize()); msg2.deserialize(msg.serialize());
ASSERT_EQUALS("errorId", msg2.id); ASSERT_EQUALS("errorId", msg2.id);
ASSERT_EQUALS(Severity::error, msg2.severity); ASSERT_EQUALS(Severity::error, msg2.severity);
ASSERT_EQUALS(true, msg2.inconclusive); ASSERT_EQUALS(Certainty::inconclusive, msg2.certainty);
ASSERT_EQUALS("Programming error", msg2.shortMessage()); ASSERT_EQUALS("Programming error", msg2.shortMessage());
ASSERT_EQUALS("Programming error", msg2.verboseMessage()); ASSERT_EQUALS("Programming error", msg2.verboseMessage());
} }
@ -274,7 +274,7 @@ private:
void SerializeSanitize() const { void SerializeSanitize() const {
std::list<ErrorMessage::FileLocation> locs; std::list<ErrorMessage::FileLocation> locs;
ErrorMessage msg(locs, emptyString, Severity::error, std::string("Illegal character in \"foo\001bar\""), "errorId", false); ErrorMessage msg(locs, emptyString, Severity::error, std::string("Illegal character in \"foo\001bar\""), "errorId", Certainty::normal);
ASSERT_EQUALS("7 errorId" ASSERT_EQUALS("7 errorId"
"5 error" "5 error"
@ -299,7 +299,7 @@ private:
std::list<ErrorMessage::FileLocation> locs{loc1}; std::list<ErrorMessage::FileLocation> locs{loc1};
ErrorMessage msg(locs, emptyString, Severity::error, "Programming error", "errorId", true); ErrorMessage msg(locs, emptyString, Severity::error, "Programming error", "errorId", Certainty::inconclusive);
ErrorMessage msg2; ErrorMessage msg2;
msg2.deserialize(msg.serialize()); msg2.deserialize(msg.serialize());

View File

@ -32,7 +32,7 @@ private:
Settings settings; Settings settings;
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("all"); settings.severity.fill();
TEST_CASE(destructors); TEST_CASE(destructors);
TEST_CASE(deallocThrow1); TEST_CASE(deallocThrow1);
@ -57,7 +57,7 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
settings.inconclusive = inconclusive; settings.certainty.setEnabled(Certainty::inconclusive, inconclusive);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);

View File

@ -35,9 +35,9 @@ private:
Settings settings; Settings settings;
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("style"); settings.severity.enable(Severity::style);
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
settings.addEnabled("portability"); settings.severity.enable(Severity::portability);
settings.libraries.emplace_back("posix"); settings.libraries.emplace_back("posix");
settings.standards.c = Standards::C11; settings.standards.c = Standards::C11;
settings.standards.cpp = Standards::CPP11; settings.standards.cpp = Standards::CPP11;
@ -1092,7 +1092,7 @@ private:
void checkIgnoredReturnValue() { void checkIgnoredReturnValue() {
Settings settings2; Settings settings2;
settings2.addEnabled("warning"); settings2.severity.enable(Severity::warning);
const char xmldata[] = "<?xml version=\"1.0\"?>\n" const char xmldata[] = "<?xml version=\"1.0\"?>\n"
"<def version=\"2\">\n" "<def version=\"2\">\n"
" <function name=\"mystrcmp,foo::mystrcmp\">\n" " <function name=\"mystrcmp,foo::mystrcmp\">\n"

View File

@ -35,13 +35,8 @@ private:
void run() OVERRIDE { void run() OVERRIDE {
settings.debugwarnings = true; settings.debugwarnings = true;
settings.addEnabled("style"); settings.severity.fill();
settings.addEnabled("warning"); settings.certainty.fill();
settings.addEnabled("portability");
settings.addEnabled("performance");
settings.addEnabled("information");
settings.inconclusive = true;
settings.experimental = true;
// don't freak out when the syntax is wrong // don't freak out when the syntax is wrong

View File

@ -37,7 +37,7 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
settings.inconclusive = inconclusive; settings.certainty.setEnabled(Certainty::inconclusive, inconclusive);
// Raw tokens.. // Raw tokens..
std::vector<std::string> files(1, "test.cpp"); std::vector<std::string> files(1, "test.cpp");
@ -60,7 +60,7 @@ private:
} }
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
TEST_CASE(test1); TEST_CASE(test1);
TEST_CASE(test2); TEST_CASE(test2);

View File

@ -80,12 +80,12 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
settings.clearEnabled(); settings.severity.clear();
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
settings.addEnabled("style"); settings.severity.enable(Severity::style);
if (portability) if (portability)
settings.addEnabled("portability"); settings.severity.enable(Severity::portability);
settings.inconclusive = inconclusive; settings.certainty.setEnabled(Certainty::inconclusive, inconclusive);
settings.platform(platform); settings.platform(platform);
// Tokenize.. // Tokenize..

View File

@ -208,7 +208,7 @@ private:
// Check for leaks.. // Check for leaks..
CheckLeakAutoVar c; CheckLeakAutoVar c;
settings.checkLibrary = true; settings.checkLibrary = true;
settings.addEnabled("information"); settings.severity.enable(Severity::information);
c.runChecks(&tokenizer, &settings, this); c.runChecks(&tokenizer, &settings, this);
} }
@ -224,7 +224,7 @@ private:
// Check for leaks.. // Check for leaks..
CheckLeakAutoVar c; CheckLeakAutoVar c;
settings.checkLibrary = true; settings.checkLibrary = true;
settings.addEnabled("information"); settings.severity.enable(Severity::information);
c.runChecks(&tokenizer, &settings, this); c.runChecks(&tokenizer, &settings, this);
} }
@ -2245,7 +2245,7 @@ private:
// Check for leaks.. // Check for leaks..
CheckLeakAutoVar checkLeak; CheckLeakAutoVar checkLeak;
settings.checkLibrary = true; settings.checkLibrary = true;
settings.addEnabled("information"); settings.severity.enable(Severity::information);
checkLeak.runChecks(&tokenizer, &settings, this); checkLeak.runChecks(&tokenizer, &settings, this);
} }

View File

@ -486,8 +486,8 @@ private:
} }
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
settings.addEnabled("style"); settings.severity.enable(Severity::style);
LOAD_LIB_2(settings.library, "std.cfg"); LOAD_LIB_2(settings.library, "std.cfg");
@ -2141,9 +2141,9 @@ private:
} }
void run() OVERRIDE { void run() OVERRIDE {
settings.inconclusive = true; settings.certainty.setEnabled(Certainty::inconclusive, true);
settings.libraries.emplace_back("posix"); settings.libraries.emplace_back("posix");
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
LOAD_LIB_2(settings.library, "std.cfg"); LOAD_LIB_2(settings.library, "std.cfg");
LOAD_LIB_2(settings.library, "posix.cfg"); LOAD_LIB_2(settings.library, "posix.cfg");

View File

@ -42,7 +42,7 @@ private:
void run() OVERRIDE { void run() OVERRIDE {
LOAD_LIB_2(settings.library, "std.cfg"); LOAD_LIB_2(settings.library, "std.cfg");
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
TEST_CASE(nullpointerAfterLoop); TEST_CASE(nullpointerAfterLoop);
TEST_CASE(nullpointer1); TEST_CASE(nullpointer1);
@ -149,7 +149,7 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
settings.inconclusive = inconclusive; settings.certainty.setEnabled(Certainty::inconclusive, inconclusive);
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
@ -166,7 +166,7 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
settings.inconclusive = false; settings.certainty.setEnabled(Certainty::inconclusive, false);
// Raw tokens.. // Raw tokens..
std::vector<std::string> files(1, "test.cpp"); std::vector<std::string> files(1, "test.cpp");

View File

@ -260,14 +260,14 @@ private:
if (!settings) { if (!settings) {
settings = &_settings; settings = &_settings;
} }
settings->addEnabled("style"); settings->severity.enable(Severity::style);
settings->addEnabled("warning"); settings->severity.enable(Severity::warning);
settings->addEnabled("portability"); settings->severity.enable(Severity::portability);
settings->addEnabled("performance"); settings->severity.enable(Severity::performance);
settings->standards.c = Standards::CLatest; settings->standards.c = Standards::CLatest;
settings->standards.cpp = Standards::CPPLatest; settings->standards.cpp = Standards::CPPLatest;
settings->inconclusive = inconclusive; settings->certainty.setEnabled(Certainty::inconclusive, inconclusive);
settings->experimental = experimental; settings->certainty.setEnabled(Certainty::experimental, experimental);
settings->verbose = verbose; settings->verbose = verbose;
// Tokenize.. // Tokenize..
@ -291,14 +291,14 @@ private:
errout.str(""); errout.str("");
Settings* settings = &_settings; Settings* settings = &_settings;
settings->addEnabled("style"); settings->severity.enable(Severity::style);
settings->addEnabled("warning"); settings->severity.enable(Severity::warning);
settings->addEnabled("portability"); settings->severity.enable(Severity::portability);
settings->addEnabled("performance"); settings->severity.enable(Severity::performance);
settings->standards.c = Standards::CLatest; settings->standards.c = Standards::CLatest;
settings->standards.cpp = Standards::CPPLatest; settings->standards.cpp = Standards::CPPLatest;
settings->inconclusive = true; settings->certainty.enable(Certainty::inconclusive);
settings->experimental = false; settings->certainty.disable(Certainty::experimental);
// Raw tokens.. // Raw tokens..
std::vector<std::string> files(1, filename); std::vector<std::string> files(1, filename);
@ -326,7 +326,7 @@ private:
void checkposix(const char code[]) { void checkposix(const char code[]) {
static Settings settings; static Settings settings;
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
settings.libraries.emplace_back("posix"); settings.libraries.emplace_back("posix");
check(code, check(code,
@ -1298,7 +1298,7 @@ private:
errout.str(""); errout.str("");
static Settings settings; static Settings settings;
settings.addEnabled("style"); settings.severity.enable(Severity::style);
settings.standards.cpp = Standards::CPP03; // #5560 settings.standards.cpp = Standards::CPP03; // #5560
// Tokenize.. // Tokenize..
@ -1439,10 +1439,10 @@ private:
errout.str(""); errout.str("");
Settings settings; Settings settings;
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
if (portability) if (portability)
settings.addEnabled("portability"); settings.severity.enable(Severity::portability);
settings.inconclusive = inconclusive; settings.certainty.setEnabled(Certainty::inconclusive, inconclusive);
settings.defaultSign = 's'; settings.defaultSign = 's';
// Tokenize.. // Tokenize..

View File

@ -47,7 +47,7 @@ private:
} }
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("performance"); settings.severity.enable(Severity::performance);
TEST_CASE(testsimple); TEST_CASE(testsimple);
TEST_CASE(testfor); TEST_CASE(testfor);

View File

@ -40,7 +40,7 @@ public:
TestPreprocessor() TestPreprocessor()
: TestFixture("TestPreprocessor") : TestFixture("TestPreprocessor")
, preprocessor0(settings0, this) { , preprocessor0(settings0, this) {
settings0.addEnabled("information"); settings0.severity.enable(Severity::information);
} }
class OurPreprocessor : public Preprocessor { class OurPreprocessor : public Preprocessor {
@ -1929,7 +1929,7 @@ private:
Preprocessor::missingIncludeFlag = false; Preprocessor::missingIncludeFlag = false;
Settings settings; Settings settings;
settings.inlineSuppressions = true; settings.inlineSuppressions = true;
settings.addEnabled("all"); settings.severity.fill();
Preprocessor preprocessor(settings, this); Preprocessor preprocessor(settings, this);
std::istringstream src("// cppcheck-suppress missingInclude\n" std::istringstream src("// cppcheck-suppress missingInclude\n"

View File

@ -39,7 +39,7 @@ private:
Settings settings; Settings settings;
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("portability"); settings.severity.enable(Severity::portability);
// If there are unused templates, keep those // If there are unused templates, keep those
settings.checkUnusedTemplates = true; settings.checkUnusedTemplates = true;

View File

@ -42,9 +42,9 @@ private:
void run() OVERRIDE { void run() OVERRIDE {
LOAD_LIB_2(settings_std.library, "std.cfg"); LOAD_LIB_2(settings_std.library, "std.cfg");
LOAD_LIB_2(settings_windows.library, "windows.cfg"); LOAD_LIB_2(settings_windows.library, "windows.cfg");
settings0.addEnabled("portability"); settings0.severity.enable(Severity::portability);
settings1.addEnabled("style"); settings1.severity.enable(Severity::style);
settings_windows.addEnabled("portability"); settings_windows.severity.enable(Severity::portability);
// If there are unused templates, keep those // If there are unused templates, keep those
settings0.checkUnusedTemplates = true; settings0.checkUnusedTemplates = true;

View File

@ -39,8 +39,8 @@ private:
Settings settings2; Settings settings2;
void run() OVERRIDE { void run() OVERRIDE {
settings0.addEnabled("style"); settings0.severity.enable(Severity::style);
settings2.addEnabled("style"); settings2.severity.enable(Severity::style);
// If there are unused templates, keep those // If there are unused templates, keep those
settings0.checkUnusedTemplates = true; settings0.checkUnusedTemplates = true;
@ -196,7 +196,7 @@ private:
std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Native, bool debugwarnings = true) { std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Native, bool debugwarnings = true) {
errout.str(""); errout.str("");
settings0.inconclusive = true; settings0.certainty.enable(Certainty::inconclusive);
settings0.debugwarnings = debugwarnings; // show warnings about unhandled typedef settings0.debugwarnings = debugwarnings; // show warnings about unhandled typedef
settings0.platform(type); settings0.platform(type);
Tokenizer tokenizer(&settings0, this); Tokenizer tokenizer(&settings0, this);
@ -223,7 +223,7 @@ private:
void checkSimplifyTypedef(const char code[]) { void checkSimplifyTypedef(const char code[]) {
errout.str(""); errout.str("");
// Tokenize.. // Tokenize..
settings2.inconclusive = true; settings2.certainty.enable(Certainty::inconclusive);
settings2.debugwarnings = true; // show warnings about unhandled typedef settings2.debugwarnings = true; // show warnings about unhandled typedef
Tokenizer tokenizer(&settings2, this); Tokenizer tokenizer(&settings2, this);
std::istringstream istr(code); std::istringstream istr(code);

View File

@ -39,8 +39,8 @@ private:
Settings settings2; Settings settings2;
void run() OVERRIDE { void run() OVERRIDE {
settings0.addEnabled("style"); settings0.severity.enable(Severity::style);
settings2.addEnabled("style"); settings2.severity.enable(Severity::style);
// If there are unused templates, keep those // If there are unused templates, keep those
settings0.checkUnusedTemplates = true; settings0.checkUnusedTemplates = true;
@ -93,7 +93,7 @@ private:
std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Native, bool debugwarnings = true) { std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Native, bool debugwarnings = true) {
errout.str(""); errout.str("");
settings0.inconclusive = true; settings0.certainty.enable(Certainty::inconclusive);
settings0.debugwarnings = debugwarnings; settings0.debugwarnings = debugwarnings;
settings0.platform(type); settings0.platform(type);
Tokenizer tokenizer(&settings0, this); Tokenizer tokenizer(&settings0, this);

View File

@ -34,9 +34,9 @@ private:
Settings settings; Settings settings;
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
settings.addEnabled("portability"); settings.severity.enable(Severity::portability);
settings.inconclusive = true; settings.certainty.enable(Certainty::inconclusive);
TEST_CASE(sizeofsizeof); TEST_CASE(sizeofsizeof);
TEST_CASE(sizeofCalculation); TEST_CASE(sizeofCalculation);

View File

@ -35,9 +35,9 @@ private:
Settings settings; Settings settings;
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
settings.addEnabled("style"); settings.severity.enable(Severity::style);
settings.addEnabled("performance"); settings.severity.enable(Severity::performance);
LOAD_LIB_2(settings.library, "std.cfg"); LOAD_LIB_2(settings.library, "std.cfg");
TEST_CASE(outOfBounds); TEST_CASE(outOfBounds);
@ -175,7 +175,7 @@ private:
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
settings.inconclusive = inconclusive; settings.certainty.setEnabled(Certainty::inconclusive, inconclusive);
settings.standards.cpp = cppstandard; settings.standards.cpp = cppstandard;

View File

@ -32,8 +32,8 @@ private:
Settings settings; Settings settings;
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
settings.addEnabled("style"); settings.severity.enable(Severity::style);
TEST_CASE(stringLiteralWrite); TEST_CASE(stringLiteralWrite);

View File

@ -184,8 +184,8 @@ private:
settings.exitCode = 1; settings.exitCode = 1;
settings.inlineSuppressions = true; settings.inlineSuppressions = true;
if (suppression == "unusedFunction") if (suppression == "unusedFunction")
settings.addEnabled("unusedFunction"); settings.checks.setEnabled(Checks::unusedFunction, true);
settings.addEnabled("information"); settings.severity.enable(Severity::information);
settings.jointSuppressionReport = true; settings.jointSuppressionReport = true;
if (!suppression.empty()) { if (!suppression.empty()) {
std::string r = settings.nomsg.addSuppressionLine(suppression); std::string r = settings.nomsg.addSuppressionLine(suppression);
@ -214,7 +214,7 @@ private:
Settings settings; Settings settings;
settings.jobs = 1; settings.jobs = 1;
settings.inlineSuppressions = true; settings.inlineSuppressions = true;
settings.addEnabled("information"); settings.severity.enable(Severity::information);
if (!suppression.empty()) { if (!suppression.empty()) {
EXPECT_EQ("", settings.nomsg.addSuppressionLine(suppression)); EXPECT_EQ("", settings.nomsg.addSuppressionLine(suppression));
} }
@ -680,7 +680,7 @@ private:
CppCheck cppCheck(*this, true, nullptr); CppCheck cppCheck(*this, true, nullptr);
Settings& settings = cppCheck.settings(); Settings& settings = cppCheck.settings();
settings.addEnabled("style"); settings.severity.enable(Severity::style);
settings.inlineSuppressions = true; settings.inlineSuppressions = true;
settings.relativePaths = true; settings.relativePaths = true;
settings.basePaths.emplace_back("/somewhere"); settings.basePaths.emplace_back("/somewhere");

View File

@ -49,8 +49,8 @@ private:
static Settings _settings; static Settings _settings;
settings = &_settings; settings = &_settings;
} }
settings->addEnabled("warning"); settings->severity.enable(Severity::warning);
settings->addEnabled("portability"); settings->severity.enable(Severity::portability);
settings->standards.setCPP(standard); settings->standards.setCPP(standard);
// Tokenize.. // Tokenize..
@ -209,7 +209,7 @@ private:
void checkIntegerOverflow() { void checkIntegerOverflow() {
Settings settings; Settings settings;
settings.platform(Settings::Unix32); settings.platform(Settings::Unix32);
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
check("x = (int)0x10000 * (int)0x10000;", &settings); check("x = (int)0x10000 * (int)0x10000;", &settings);
ASSERT_EQUALS("[test.cpp:1]: (error) Signed integer overflow for expression '(int)0x10000*(int)0x10000'.\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) Signed integer overflow for expression '(int)0x10000*(int)0x10000'.\n", errout.str());
@ -298,7 +298,7 @@ private:
void longCastAssign() { void longCastAssign() {
Settings settings; Settings settings;
settings.addEnabled("style"); settings.severity.enable(Severity::style);
settings.platform(Settings::Unix64); settings.platform(Settings::Unix64);
check("long f(int x, int y) {\n" check("long f(int x, int y) {\n"
@ -330,7 +330,7 @@ private:
void longCastReturn() { void longCastReturn() {
Settings settings; Settings settings;
settings.addEnabled("style"); settings.severity.enable(Severity::style);
check("long f(int x, int y) {\n" check("long f(int x, int y) {\n"
" return x * y;\n" " return x * y;\n"

View File

@ -108,7 +108,7 @@ private:
checkuninitvar.check(); checkuninitvar.check();
settings.debugwarnings = false; settings.debugwarnings = false;
settings.experimental = true; settings.certainty.enable(Certainty::experimental);
} }
void uninitvar1() { void uninitvar1() {
@ -4069,7 +4069,7 @@ private:
// Tokenize.. // Tokenize..
settings.debugwarnings = false; settings.debugwarnings = false;
settings.experimental = false; settings.certainty.disable(Certainty::experimental);
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
std::istringstream istr(code); std::istringstream istr(code);

View File

@ -34,7 +34,7 @@ private:
Settings settings; Settings settings;
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("style"); settings.severity.enable(Severity::style);
TEST_CASE(incondition); TEST_CASE(incondition);
TEST_CASE(return1); TEST_CASE(return1);

View File

@ -35,7 +35,7 @@ private:
Settings settings; Settings settings;
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("style"); settings.severity.enable(Severity::style);
TEST_CASE(test1); TEST_CASE(test1);
TEST_CASE(test2); TEST_CASE(test2);

View File

@ -33,8 +33,8 @@ private:
Settings settings; Settings settings;
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("style"); settings.severity.enable(Severity::style);
settings.addEnabled("information"); settings.severity.enable(Severity::information);
settings.checkLibrary = true; settings.checkLibrary = true;
LOAD_LIB_2(settings.library, "std.cfg"); LOAD_LIB_2(settings.library, "std.cfg");

View File

@ -45,7 +45,7 @@ private:
} }
void run() OVERRIDE { void run() OVERRIDE {
settings.addEnabled("warning"); settings.severity.enable(Severity::warning);
TEST_CASE(wrongParameterTo_va_start); TEST_CASE(wrongParameterTo_va_start);
TEST_CASE(referenceAs_va_start); TEST_CASE(referenceAs_va_start);