diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 6f651a2d6..2f9463afb 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -309,7 +309,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) return false; } // 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("performance"); mSettings->addEnabled("portability"); @@ -430,7 +430,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) // Inconclusive checking else if (std::strcmp(argv[i], "--inconclusive") == 0) - mSettings->inconclusive = true; + mSettings->certainty.enable(Certainty::inconclusive); // Enables inline suppressions. 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) 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."); } diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index a0dc0a8df..69c6ded93 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -130,7 +130,7 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c ++iter; else { // 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; 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())) { const std::string msg("Failed to load the library " + lib); const std::list callstack; - ErrorMessage errmsg(callstack, emptyString, Severity::information, msg, "failedToLoadCfg", false); + ErrorMessage errmsg(callstack, emptyString, Severity::information, msg, "failedToLoadCfg", Certainty::normal); reportErr(errmsg); 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 " "should be configured."); #endif - ErrorMessage errmsg(callstack, emptyString, Severity::information, msg+" "+details, "failedToLoadCfg", false); + ErrorMessage errmsg(callstack, emptyString, Severity::information, msg+" "+details, "failedToLoadCfg", Certainty::normal); reportErr(errmsg); return EXIT_FAILURE; } @@ -963,7 +963,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck, int /*argc*/, const cha 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(); if (settings.jointSuppressionReport) { @@ -982,7 +982,7 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck, int /*argc*/, const cha if (!settings.checkConfiguration) { 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 callStack; ErrorMessage msg(callStack, 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 " "--check-config.", Preprocessor::missingIncludeFlag ? "missingInclude" : "missingIncludeSystem", - false); + Certainty::normal); reportInfo(msg); } } diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp index af4b15e48..357a8410e 100644 --- a/gui/checkthread.cpp +++ b/gui/checkthread.cpp @@ -396,7 +396,7 @@ void CheckThread::parseClangErrors(const QString &tool, const QString &file0, QS const std::string f0 = file0.toStdString(); const std::string msg = e.message.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); } } diff --git a/gui/erroritem.cpp b/gui/erroritem.cpp index b09e5e5b7..4fa53ce35 100644 --- a/gui/erroritem.cpp +++ b/gui/erroritem.cpp @@ -47,7 +47,7 @@ ErrorItem::ErrorItem(const ErrorMessage &errmsg) , errorId(QString::fromStdString(errmsg.id)) , severity(errmsg.severity) , incomplete(errmsg.incomplete) - , inconclusive(errmsg.inconclusive) + , inconclusive(errmsg.certainty == Certainty::inconclusive) , summary(QString::fromStdString(errmsg.shortMessage())) , message(QString::fromStdString(errmsg.verboseMessage())) , cwe(errmsg.cwe.id) diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index e3ecdfb4d..93b325d85 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -974,14 +974,14 @@ Settings MainWindow::getCppcheckSettings() addIncludeDirs(includes, result); } - result.addEnabled("warning"); - result.addEnabled("style"); - result.addEnabled("performance"); - result.addEnabled("portability"); - result.addEnabled("information"); - result.addEnabled("missingInclude"); + result.severity.enable(Severity::warning); + result.severity.enable(Severity::style); + result.severity.enable(Severity::performance); + result.severity.enable(Severity::portability); + result.severity.enable(Severity::information); + result.checks.enable(Checks::missingInclude); if (!result.buildDir.empty()) - result.addEnabled("unusedFunction"); + result.checks.enable(Checks::unusedFunction); result.debugwarnings = mSettings->value(SETTINGS_SHOW_DEBUG_WARNINGS, false).toBool(); result.quiet = false; result.verbose = true; @@ -989,7 +989,7 @@ Settings MainWindow::getCppcheckSettings() result.xml = false; result.jobs = mSettings->value(SETTINGS_CHECK_THREADS, 1).toInt(); 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) result.platform((cppcheck::Platform::PlatformType) mSettings->value(SETTINGS_CHECKED_PLATFORM, 0).toInt()); result.standards.setCPP(mSettings->value(SETTINGS_STD_CPP, QString()).toString().toStdString()); diff --git a/lib/bughuntingchecks.cpp b/lib/bughuntingchecks.cpp index 5ca7a4733..f75ff1a90 100644 --- a/lib/bughuntingchecks.cpp +++ b/lib/bughuntingchecks.cpp @@ -474,7 +474,7 @@ static void uninit(const Token *tok, const ExprEngine::Value &value, ExprEngine: return; } - if (inconclusive && !dataBase->settings->inconclusive) + if (inconclusive && !dataBase->settings->certainty.isEnabled(Certainty::inconclusive)) return; // Avoid FP for array declaration diff --git a/lib/check.cpp b/lib/check.cpp index fb3f6b054..7ef2281f0 100644 --- a/lib/check.cpp +++ b/lib/check.cpp @@ -46,18 +46,18 @@ void Check::reportError(const ErrorMessage &errmsg) } -void Check::reportError(const std::list &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg, const CWE &cwe, bool inconclusive) +void Check::reportError(const std::list &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) mErrorLogger->reportErr(errmsg); else 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) mErrorLogger->reportErr(errmsg); else diff --git a/lib/check.h b/lib/check.h index a5ebb3c90..039c587bc 100644 --- a/lib/check.h +++ b/lib/check.h @@ -133,24 +133,24 @@ protected: /** report an error */ 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 */ - 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 callstack(1, tok); - reportError(callstack, severity, id, msg, cwe, inconclusive); + reportError(callstack, severity, id, msg, cwe, certainty); } /** report an error */ void reportError(const std::list &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 */ - void reportError(const std::list &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg, const CWE &cwe, bool inconclusive); + void reportError(const std::list &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; diff --git a/lib/check64bit.cpp b/lib/check64bit.cpp index 2ea021dc2..2a0bb0465 100644 --- a/lib/check64bit.cpp +++ b/lib/check64bit.cpp @@ -42,7 +42,7 @@ namespace { void Check64BitPortability::pointerassignment() { - if (!mSettings->isEnabled(Settings::PORTABILITY)) + if (!mSettings->severity.isEnabled(Severity::portability)) return; 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 " "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 " - "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) @@ -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 " "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 " - "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) @@ -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 " "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 " - "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) @@ -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 " "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. " - "The safe way is to always return a pointer.", CWE758, false); + "The safe way is to always return a pointer.", CWE758, Certainty::normal); } diff --git a/lib/checkassert.cpp b/lib/checkassert.cpp index 35ef6b462..2c41e9c00 100644 --- a/lib/checkassert.cpp +++ b/lib/checkassert.cpp @@ -40,7 +40,7 @@ namespace { void CheckAssert::assertWithSideEffects() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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. " "Assert statements are removed from release builds so the code inside " "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) @@ -116,7 +116,7 @@ void CheckAssert::assignmentInAssertError(const Token *tok, const std::string& v "Variable '$symbol' is modified inside assert statement. " "Assert statements are removed from release builds so the code inside " "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 diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index b0ae5f27b..fc25837c0 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -202,8 +202,8 @@ static bool variableIsUsedInScope(const Token* start, nonneg int varId, const Sc void CheckAutoVariables::assignFunctionArg() { - const bool printStyle = mSettings->isEnabled(Settings::STYLE); - const bool printWarning = mSettings->isEnabled(Settings::WARNING); + const bool printStyle = mSettings->severity.isEnabled(Severity::style); + const bool printWarning = mSettings->severity.isEnabled(Severity::warning); if (!printStyle && !printWarning) return; @@ -231,7 +231,7 @@ void CheckAutoVariables::assignFunctionArg() void CheckAutoVariables::autoVariables() { - const bool printInconclusive = mSettings->inconclusive; + const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { 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) { - 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) { - 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) { - 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) @@ -352,7 +352,7 @@ void CheckAutoVariables::errorAutoVariableAssignment(const Token *tok, bool inco "Dangerous assignment - the function parameter is assigned the address of a local " "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 invalid after the function ends.", CWE562, false); + "is invalid after the function ends.", CWE562, Certainty::normal); } else { reportError(tok, Severity::error, "autoVariables", "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 " "might 'leak' from the function through the parameter.", CWE562, - true); + Certainty::inconclusive); } } @@ -372,7 +372,7 @@ void CheckAutoVariables::errorReturnAddressOfFunctionParameter(const Token *tok, "Address of function parameter '$symbol' returned.\n" "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 " - "value is invalid.", CWE562, false); + "value is invalid.", CWE562, Certainty::normal); } void CheckAutoVariables::errorUselessAssignmentArg(const Token *tok) @@ -380,7 +380,7 @@ void CheckAutoVariables::errorUselessAssignmentArg(const Token *tok) reportError(tok, Severity::style, "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) @@ -388,7 +388,7 @@ void CheckAutoVariables::errorUselessAssignmentPtrArg(const Token *tok) reportError(tok, Severity::warning, "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) { - const bool printInconclusive = (mSettings->inconclusive); + const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); if (!start) return; const Scope * scope = start->scope(); @@ -630,7 +630,7 @@ void CheckAutoVariables::errorReturnDanglingLifetime(const Token *tok, const Val ErrorPath errorPath = val ? val->errorPath : ErrorPath(); std::string msg = "Returning " + lifetimeMessage(tok, val, errorPath); 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) @@ -639,7 +639,7 @@ void CheckAutoVariables::errorInvalidLifetime(const Token *tok, const ValueFlow: ErrorPath errorPath = val ? val->errorPath : ErrorPath(); std::string msg = "Using " + lifetimeMessage(tok, val, errorPath); 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) @@ -648,7 +648,7 @@ void CheckAutoVariables::errorDanglingTemporaryLifetime(const Token* tok, const ErrorPath errorPath = val ? val->errorPath : ErrorPath(); std::string msg = "Using " + lifetimeMessage(tok, val, errorPath); 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) @@ -658,21 +658,21 @@ void CheckAutoVariables::errorDanglngLifetime(const Token *tok, const ValueFlow: std::string tokName = tok ? tok->expressionString() : "x"; std::string msg = "Non-local variable '" + tokName + "' will use " + lifetimeMessage(tok, val, errorPath); 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) { errorPath.emplace_back(tok, ""); 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) { errorPath.emplace_back(tok, ""); 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) @@ -681,14 +681,14 @@ void CheckAutoVariables::errorDanglingReference(const Token *tok, const Variable std::string varName = var ? var->name() : "y"; std::string msg = "Non-local reference variable '" + tokName + "' to local variable '" + varName + "'"; 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) { errorPath.emplace_back(tok, ""); 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) @@ -711,5 +711,5 @@ void CheckAutoVariables::errorInvalidDeallocation(const Token *tok, const ValueF "autovarInvalidDeallocation", "Deallocation of an " + type + " results in undefined behaviour.\n" "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); } diff --git a/lib/checkbool.cpp b/lib/checkbool.cpp index 48a889c58..e801f5559 100644 --- a/lib/checkbool.cpp +++ b/lib/checkbool.cpp @@ -49,7 +49,7 @@ static bool isBool(const Variable* var) //--------------------------------------------------------------------------- void CheckBool::checkIncrementBoolean() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -70,7 +70,7 @@ void CheckBool::incrementBooleanError(const Token *tok) "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" "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() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; // danmar: this is inconclusive because I don't like that there are // warnings for calculations. Example: set_flag(a & b); - if (!mSettings->inconclusive) + if (!mSettings->certainty.isEnabled(Certainty::inconclusive)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -108,7 +108,7 @@ void CheckBool::bitwiseOnBooleanError(const Token *tok, const std::string &expre reportError(tok, Severity::style, "bitwiseOnBoolean", "Boolean expression '" + expression + "' is used in bitwise operation. Did you mean '" + op + "'?", CWE398, - true); + Certainty::inconclusive); } //--------------------------------------------------------------------------- @@ -117,7 +117,7 @@ void CheckBool::bitwiseOnBooleanError(const Token *tok, const std::string &expre void CheckBool::checkComparisonOfBoolWithInt() { - if (!mSettings->isEnabled(Settings::WARNING) || !mTokenizer->isCPP()) + if (!mSettings->severity.isEnabled(Severity::warning) || !mTokenizer->isCPP()) return; const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -166,7 +166,7 @@ static bool tokenIsFunctionReturningBool(const Token* tok) void CheckBool::checkComparisonOfFuncReturningBool() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; 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" "The return type of function '" + expression + "' is 'bool' " "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) @@ -214,7 +214,7 @@ void CheckBool::comparisonOfTwoFuncsReturningBoolError(const Token *tok, const s "Comparison of two functions returning boolean value using relational (<, >, <= or >=) operator.\n" "The return type of function '" + expression1 + "' and function '" + expression2 + "' is 'bool' " "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 // when self checking lib/tokenize.cpp (#2617) - if (!mSettings->experimental) + if (!mSettings->certainty.isEnabled(Certainty::experimental)) return; - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; 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" "The variable '" + expression + "' is of type 'bool' " "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) { reportError(tok, Severity::error, "assignBoolToPointer", - "Boolean value assigned to pointer.", CWE587, false); + "Boolean value assigned to pointer.", CWE587, Certainty::normal); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CheckBool::checkComparisonOfBoolExpressionWithInt() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -357,10 +357,10 @@ void CheckBool::comparisonOfBoolExpressionWithIntError(const Token *tok, bool no { if (not0or1) 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 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, "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 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() { if (!mTokenizer->isCPP()) return; - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { @@ -433,12 +433,12 @@ void CheckBool::checkAssignBoolToFloat() void CheckBool::assignBoolToFloatError(const Token *tok) { 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() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase(); diff --git a/lib/checkboost.cpp b/lib/checkboost.cpp index 6dbb81119..a488a6e85 100644 --- a/lib/checkboost.cpp +++ b/lib/checkboost.cpp @@ -59,6 +59,6 @@ void CheckBoost::checkBoostForeachModification() void CheckBoost::boostForeachError(const Token *tok) { 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 ); } diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 5ba752d33..caeb83209 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -370,8 +370,8 @@ static std::string arrayIndexMessage(const Token *tok, const std::vector &dimensions, const std::vector &indexes) { 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::warning, "arrayIndexOutOfBoundsCond", "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, Certainty::normal); return; } @@ -380,7 +380,7 @@ void CheckBufferOverrun::arrayIndexError(const Token *tok, const std::vectorerrorSeverity() && !mSettings->isEnabled(Settings::WARNING)) + if (!indexValue->errorSeverity() && !mSettings->severity.isEnabled(Severity::warning)) return; if (indexValue->condition) condition = indexValue->condition; @@ -393,13 +393,13 @@ void CheckBufferOverrun::arrayIndexError(const Token *tok, const std::vectorcondition ? "arrayIndexOutOfBoundsCond" : "arrayIndexOutOfBounds", arrayIndexMessage(tok, dimensions, indexes, condition), CWE_BUFFER_OVERRUN, - index->isInconclusive()); + index->isInconclusive() ? Certainty::inconclusive : Certainty::normal); } void CheckBufferOverrun::negativeIndexError(const Token *tok, const std::vector &dimensions, const std::vector &indexes) { 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; } @@ -408,7 +408,7 @@ void CheckBufferOverrun::negativeIndexError(const Token *tok, const std::vector< for (const ValueFlow::Value *indexValue: indexes) { if (!indexValue) continue; - if (!indexValue->errorSeverity() && !mSettings->isEnabled(Settings::WARNING)) + if (!indexValue->errorSeverity() && !mSettings->severity.isEnabled(Severity::warning)) return; if (indexValue->condition) condition = indexValue->condition; @@ -421,14 +421,14 @@ void CheckBufferOverrun::negativeIndexError(const Token *tok, const std::vector< "negativeIndex", arrayIndexMessage(tok, dimensions, indexes, condition), CWE_BUFFER_UNDERRUN, - negativeValue->isInconclusive()); + negativeValue->isInconclusive() ? Certainty::inconclusive : Certainty::normal); } //--------------------------------------------------------------------------- void CheckBufferOverrun::pointerArithmetic() { - if (!mSettings->isEnabled(Settings::PORTABILITY)) + if (!mSettings->severity.isEnabled(Severity::portability)) return; 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) { if (!tok) { - reportError(tok, Severity::portability, "pointerOutOfBounds", "Pointer arithmetic overflow.", CWE_POINTER_ARITHMETIC_OVERFLOW, false); - reportError(tok, Severity::portability, "pointerOutOfBoundsCond", "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, Certainty::normal); return; } @@ -496,7 +496,7 @@ void CheckBufferOverrun::pointerArithmeticError(const Token *tok, const Token *i indexValue->condition ? "pointerOutOfBoundsCond" : "pointerOutOfBounds", errmsg, 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) { - 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() { - if (!mSettings->isEnabled(Settings::PORTABILITY)) + if (!mSettings->severity.isEnabled(Severity::portability)) return; 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 " "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 " - "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() { // 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; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * const scope : symbolDatabase->functionScopes) { @@ -724,7 +724,7 @@ void CheckBufferOverrun::terminateStrncpyError(const Token *tok, const std::stri shortMessage + ' ' + "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 " - "assumes buffer is null-terminated.", CWE170, true); + "assumes buffer is null-terminated.", CWE170, Certainty::inconclusive); } @@ -870,7 +870,7 @@ bool CheckBufferOverrun::analyseWholeProgram1(const std::mapisEnabled(Settings::STYLE); - const bool printWarnings = mSettings->isEnabled(Settings::WARNING); + const bool printStyle = mSettings->severity.isEnabled(Severity::style); + const bool printWarnings = mSettings->severity.isEnabled(Severity::warning); if (!printStyle && !printWarnings) return; - const bool printInconclusive = mSettings->inconclusive; + const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { const bool unusedTemplate = Token::simpleMatch(scope->classDef->previous(), ">"); @@ -255,7 +255,7 @@ void CheckClass::constructors() void CheckClass::checkExplicitConstructors() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { @@ -324,7 +324,7 @@ static bool isNonCopyable(const Scope *scope, bool *unknown) void CheckClass::copyconstructors() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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) { 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) @@ -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) { - 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) { - 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) { - 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) @@ -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. 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) { 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."); - 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) @@ -956,12 +956,12 @@ void CheckClass::uninitVarError(const Token *tok, bool isprivate, Function::Type if (derived) message += " Maybe it should be initialized directly in the class " + classname + "?"; 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) { - 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() { - if (!mSettings->isEnabled(Settings::PERFORMANCE)) + if (!mSettings->severity.isEnabled(Severity::performance)) return; 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" "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 " - "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() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; 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) { - 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() { - const bool printWarnings = mSettings->isEnabled(Settings::WARNING); + const bool printWarnings = mSettings->severity.isEnabled(Severity::warning); for (const Scope *scope : mSymbolDatabase->functionScopes) { for (const Token *tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) { if (Token::Match(tok, "memset|memcpy|memmove (")) { @@ -1261,7 +1261,7 @@ void CheckClass::checkMemsetType(const Scope *start, const Token *tok, const Sco return; parsedTypes.insert(type); - const bool printPortability = mSettings->isEnabled(Settings::PORTABILITY); + const bool printPortability = mSettings->severity.isEnabled(Severity::portability); // recursively check all parent classes 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" "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, " - "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) @@ -1338,7 +1338,7 @@ void CheckClass::mallocOnClassError(const Token* tok, const std::string &memfunc "$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 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) @@ -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 + " 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 " - "is created.", CWE762, false); + "is created.", CWE762, Certainty::normal); } void CheckClass::memsetErrorReference(const Token *tok, const std::string &memfunc, const std::string &type) { reportError(tok, Severity::error, "memsetClassReference", "$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) @@ -1365,7 +1365,7 @@ void CheckClass::memsetErrorFloat(const Token *tok, const std::string &type) "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" " 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() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; 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) { - 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) { - 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) { 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 { operatorEqRetRefThisError(tok); } @@ -1514,7 +1514,7 @@ void CheckClass::operatorEqMissingReturnStatementError(const Token *tok, bool er void CheckClass::operatorEqToSelf() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { @@ -1694,7 +1694,7 @@ void CheckClass::operatorEqToSelfError(const Token *tok) 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 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 // unless inconclusive in which case: // * 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 inconclusiveErrors; @@ -1839,8 +1839,8 @@ void CheckClass::virtualDestructor() void CheckClass::virtualDestructorError(const Token *tok, const std::string &Base, const std::string &Derived, bool inconclusive) { if (inconclusive) { - if (mSettings->isEnabled(Settings::WARNING)) - reportError(tok, Severity::warning, "virtualDestructor", "$symbol:" + Base + "\nClass '$symbol' which has virtual members does not have a virtual destructor.", CWE404, true); + 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, Certainty::inconclusive); } else { reportError(tok, Severity::error, "virtualDestructor", "$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. " "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 " - "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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; const Token *tok = mTokenizer->tokens(); @@ -1877,7 +1877,7 @@ void CheckClass::thisSubtraction() 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() { // This is an inconclusive check. False positives: #3322. - if (!mSettings->inconclusive) + if (!mSettings->certainty.isEnabled(Certainty::inconclusive)) return; - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; 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. " "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 " - "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 reportError(toks, Severity::performance, "functionStatic", "$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 " "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 " - "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() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; // 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 // 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. - if (!mSettings->inconclusive) + if (!mSettings->certainty.isEnabled(Certainty::inconclusive)) return; 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 " "order they are in the initializer list. Keeping the initializer list " "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) { - 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() { - if (! mSettings->isEnabled(Settings::WARNING)) + if (! mSettings->severity.isEnabled(Severity::warning)) return; std::map > virtualFunctionCallsMap; for (const Scope *scope : mSymbolDatabase->functionScopes) { @@ -2511,7 +2511,7 @@ void CheckClass::virtualFunctionCallInConstructorError( } 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( @@ -2530,7 +2530,7 @@ void CheckClass::pureVirtualFunctionCallInConstructorError( reportError(errorPath, Severity::warning, "pureVirtualCall", "$symbol:" + purefuncname +"\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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; // 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 + "' defines member variable with name '" + variableName + "' also defined in its parent " + 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; // cppcheck-suppress unreachableCode - remove when code is enabled again - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { @@ -2671,7 +2671,7 @@ void CheckClass::copyCtorAndEqOperatorError(const Token *tok, const std::string void CheckClass::checkOverride() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; if (mSettings->standards.cpp < Standards::CPP11) return; @@ -2703,12 +2703,12 @@ void CheckClass::overrideError(const Function *funcInBase, const Function *funcI "$symbol:" + functionName + "\n" "The " + funcType + " '$symbol' overrides a " + funcType + " in a base class but is not marked with a 'override' specifier.", CWE(0U) /* Unknown CWE! */, - false); + Certainty::normal); } void CheckClass::checkThisUseAfterFree() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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", "$symbol:" + selfPointer + "\n" + usemsg + " when 'this' might be invalid", - CWE(0), false); + CWE(0), Certainty::normal); } void CheckClass::checkUnsafeClassRefMember() { - if (!mSettings->safeChecks.classes || !mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->safeChecks.classes || !mSettings->severity.isEnabled(Severity::warning)) return; for (const Scope * classScope : mSymbolDatabase->classAndStructScopes) { for (const Function &func : classScope->functionList) { @@ -2833,7 +2833,7 @@ void CheckClass::unsafeClassRefMemberError(const Token *tok, const std::string & "$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 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 @@ -2969,7 +2969,7 @@ bool CheckClass::analyseWholeProgram(const CTU::FileInfo *ctu, const std::list &vars) const void CheckCondition::assignIf() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; 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, Severity::style, "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, Severity::style, "mismatchingBitAnd", - msg.str(), CWE398, false); + msg.str(), CWE398, Certainty::normal); } @@ -289,7 +289,7 @@ static bool inBooleanFunction(const Token *tok) void CheckCondition::checkBadBitmaskCheck() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { @@ -312,12 +312,12 @@ void CheckCondition::checkBadBitmaskCheck() 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() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; 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 " "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 @@ -433,7 +433,7 @@ bool CheckCondition::isOverlappingCond(const Token * const cond1, const Token * void CheckCondition::duplicateCondition() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; 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"; - reportError(errorPath, Severity::style, "duplicateCondition", msg, CWE398, false); + reportError(errorPath, Severity::style, "duplicateCondition", msg, CWE398, Certainty::normal); } void CheckCondition::multiCondition() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; 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 " << 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) @@ -540,7 +540,7 @@ void CheckCondition::oppositeElseIfConditionError(const Token *ifCond, const Tok errorPath.emplace_back(ifCond, "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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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" "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) @@ -833,7 +833,7 @@ void CheckCondition::identicalInnerConditionError(const Token *tok1, const Token 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 + "')."); - 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) @@ -856,7 +856,7 @@ void CheckCondition::identicalConditionAfterEarlyExitError(const Token *cond1, c ? ("Identical condition and return expression '" + cond + "', return value is always " + value) : ("Identical condition '" + cond + "', second condition is always false"), CWE398, - false); + Certainty::normal); } //--------------------------------------------------------------------------- @@ -1034,11 +1034,11 @@ static std::string conditionString(const Token * tok) void CheckCondition::checkIncorrectLogicOperator() { - const bool printStyle = mSettings->isEnabled(Settings::STYLE); - const bool printWarning = mSettings->isEnabled(Settings::WARNING); + const bool printStyle = mSettings->severity.isEnabled(Severity::style); + const bool printWarning = mSettings->severity.isEnabled(Severity::warning); if (!printWarning && !printStyle) return; - const bool printInconclusive = mSettings->inconclusive; + const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { @@ -1244,19 +1244,19 @@ void CheckCondition::incorrectLogicOperatorError(const Token *tok, const std::st reportError(errors, Severity::warning, "incorrectLogicOperator", "Logical disjunction always evaluates to true: " + condition + ".\n" "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 reportError(errors, Severity::warning, "incorrectLogicOperator", "Logical conjunction always evaluates to false: " + condition + ".\n" "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) { if (diag(tok)) 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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -1293,7 +1293,7 @@ void CheckCondition::checkModuloAlwaysTrueFalse() void CheckCondition::moduloAlwaysTrueFalseError(const Token* tok, const std::string& maxVal) { 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) @@ -1316,7 +1316,7 @@ static int countPar(const Token *tok1, const Token *tok2) //--------------------------------------------------------------------------- void CheckCondition::clarifyCondition() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; const bool isC = mTokenizer->isC(); @@ -1375,12 +1375,12 @@ void CheckCondition::clarifyConditionError(const Token *tok, bool assign, bool b reportError(tok, Severity::style, "clarifyCondition", - errmsg, CWE398, false); + errmsg, CWE398, Certainty::normal); } void CheckCondition::alwaysTrueFalse() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -1496,7 +1496,7 @@ void CheckCondition::alwaysTrueFalseError(const Token *tok, const ValueFlow::Val Severity::style, "knownConditionTrueFalse", errmsg, - (alwaysTrue ? CWE571 : CWE570), false); + (alwaysTrue ? CWE571 : CWE570), Certainty::normal); } void CheckCondition::checkInvalidTestForOverflow() @@ -1514,7 +1514,7 @@ void CheckCondition::checkInvalidTestForOverflow() // x + y < x -> y < 0 - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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 + "."; else 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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -1648,7 +1648,7 @@ void CheckCondition::pointerAdditionResultNotNullError(const Token *tok, const T void CheckCondition::checkDuplicateConditionalAssign() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -1699,5 +1699,5 @@ void CheckCondition::duplicateConditionalAssignError(const Token *condTok, const } reportError( - errors, Severity::style, "duplicateConditionalAssign", msg, CWE398, false); + errors, Severity::style, "duplicateConditionalAssign", msg, CWE398, Certainty::normal); } diff --git a/lib/checkexceptionsafety.cpp b/lib/checkexceptionsafety.cpp index f6f0051cc..33bb25eac 100644 --- a/lib/checkexceptionsafety.cpp +++ b/lib/checkexceptionsafety.cpp @@ -38,7 +38,7 @@ namespace { void CheckExceptionSafety::destructors() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -78,10 +78,10 @@ void CheckExceptionSafety::destructors() void CheckExceptionSafety::deallocThrow() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; - const bool printInconclusive = mSettings->inconclusive; + const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); // Deallocate a global/member pointer and then throw exception @@ -145,7 +145,7 @@ void CheckExceptionSafety::deallocThrow() //--------------------------------------------------------------------------- void CheckExceptionSafety::checkRethrowCopy() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -179,7 +179,7 @@ void CheckExceptionSafety::checkRethrowCopy() //--------------------------------------------------------------------------- void CheckExceptionSafety::checkCatchExceptionByValue() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -281,7 +281,7 @@ void CheckExceptionSafety::nothrowThrows() //-------------------------------------------------------------------------- void CheckExceptionSafety::unhandledExceptionSpecification() { - if (!mSettings->isEnabled(Settings::STYLE) || !mSettings->inconclusive) + if (!mSettings->severity.isEnabled(Severity::style) || !mSettings->certainty.isEnabled(Certainty::inconclusive)) return; const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); diff --git a/lib/checkexceptionsafety.h b/lib/checkexceptionsafety.h index c6db4b682..d437c9923 100644 --- a/lib/checkexceptionsafety.h +++ b/lib/checkexceptionsafety.h @@ -99,30 +99,30 @@ private: "Class " + className + " is not safe, destructor throws exception\n" "The class " + className + " is not safe because its destructor " "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) { 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) { reportError(tok, Severity::style, "exceptRethrowCopy", "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 + "'. " - "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) { reportError(tok, Severity::style, "catchExceptionByValue", "Exception should be caught by reference.\n" "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) { - 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 */ @@ -132,7 +132,7 @@ private: reportError(locationList, Severity::style, "unhandledExceptionSpecification", "Unhandled exception specification when calling function " + str1 + "().\n" "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) */ diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index a93274c03..838520b2a 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -54,7 +54,7 @@ static const CWE CWE688(688U); // Function Call With Incorrect Variable or Refe 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(); for (const Scope *scope : symbolDatabase->functionScopes) { @@ -84,9 +84,9 @@ void CheckFunctions::checkProhibitedFunctions() const Library::WarnInfo* wi = mSettings->library.getWarnInfo(tok); 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" : ""; - 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", errmsg.str(), CWE628, - invalidValue->isInconclusive()); + invalidValue->isInconclusive() ? Certainty::inconclusive : Certainty::normal); else reportError(tok, Severity::error, "invalidFunctionArg", errmsg.str(), CWE628, - false); + Certainty::normal); } 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; errmsg << "$symbol:" << functionName << '\n'; 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) @@ -184,7 +184,7 @@ void CheckFunctions::invalidFunctionArgStrError(const Token *tok, const std::str std::ostringstream errmsg; errmsg << "$symbol:" << functionName << '\n'; 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() { - if (!mSettings->isEnabled(Settings::WARNING) && !mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::warning) && !mSettings->severity.isEnabled(Severity::style)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -218,11 +218,11 @@ void CheckFunctions::checkIgnoredReturnValue() if ((!tok->function() || !Token::Match(tok->function()->retDef, "void %name%")) && !WRONG_DATA(!tok->next()->astOperand1(), tok)) { const Library::UseRetValType retvalTy = mSettings->library.getUseRetValType(tok); - if (mSettings->isEnabled(Settings::WARNING) && + if (mSettings->severity.isEnabled(Severity::warning) && ((retvalTy == Library::UseRetValType::DEFAULT) || (tok->function() && tok->function()->isAttributeNodiscard()))) ignoredReturnValueError(tok, tok->next()->astOperand1()->expressionString()); - else if (mSettings->isEnabled(Settings::STYLE) && + else if (mSettings->severity.isEnabled(Severity::style) && retvalTy == Library::UseRetValType::ERROR_CODE) ignoredReturnErrorCode(tok, tok->next()->astOperand1()->expressionString()); } @@ -233,13 +233,13 @@ void CheckFunctions::checkIgnoredReturnValue() void CheckFunctions::ignoredReturnValueError(const Token* tok, const std::string& function) { 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) { 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() { - const bool styleC99 = mSettings->isEnabled(Settings::STYLE) && mSettings->standards.c != Standards::C89 && mSettings->standards.cpp != Standards::CPP03; - const bool printWarnings = mSettings->isEnabled(Settings::WARNING); + const bool styleC99 = mSettings->severity.isEnabled(Severity::style) && mSettings->standards.c != Standards::C89 && mSettings->standards.cpp != Standards::CPP03; + const bool printWarnings = mSettings->severity.isEnabled(Severity::warning); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope *scope : symbolDatabase->functionScopes) { @@ -305,16 +305,16 @@ void CheckFunctions::mathfunctionCallWarning(const Token *tok, const nonneg int { if (tok) { 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) - 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 - 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) { - 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() // // - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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." " 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."); - reportError(tok, Severity::warning, "memsetZeroBytes", summary + "\n" + verbose, CWE687, false); + reportError(tok, Severity::warning, "memsetZeroBytes", summary + "\n" + verbose, CWE687, Certainty::normal); } void CheckFunctions::memsetInvalid2ndParam() @@ -366,8 +366,8 @@ void CheckFunctions::memsetInvalid2ndParam() // // - const bool printPortability = mSettings->isEnabled(Settings::PORTABILITY); - const bool printWarning = mSettings->isEnabled(Settings::WARNING); + const bool printPortability = mSettings->severity.isEnabled(Severity::portability); + const bool printWarning = mSettings->severity.isEnabled(Severity::warning); if (!printWarning && !printPortability) return; @@ -408,14 +408,14 @@ void CheckFunctions::memsetFloatError(const Token *tok, const std::string &var_v "' 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" " 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) { 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."); - 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() { - if (!mSettings->checkLibrary || !mSettings->isEnabled(Settings::INFORMATION)) + if (!mSettings->checkLibrary || !mSettings->severity.isEnabled(Severity::information)) return; bool insideNew = false; diff --git a/lib/checkinternal.h b/lib/checkinternal.h index 15bb04510..fb5185492 100644 --- a/lib/checkinternal.h +++ b/lib/checkinternal.h @@ -45,7 +45,7 @@ public: } void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) OVERRIDE { - if (!settings->isEnabled(Settings::INTERNAL)) + if (!settings->checks.isEnabled(Checks::internalCheck)) return; CheckInternal checkInternal(tokenizer, settings, errorLogger); diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 4bf46a6cc..d9e364d1e 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -78,7 +78,7 @@ void CheckIO::checkCoutCerrMisusage() 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() { const bool windows = mSettings->isWindowsPlatform(); - const bool printPortability = mSettings->isEnabled(Settings::PORTABILITY); - const bool printWarnings = mSettings->isEnabled(Settings::WARNING); + const bool printPortability = mSettings->severity.isEnabled(Severity::portability); + const bool printWarnings = mSettings->severity.isEnabled(Severity::warning); std::map filepointers; @@ -337,37 +337,37 @@ void CheckIO::checkFileUsage() void CheckIO::fflushOnInputStreamError(const Token *tok, const std::string &varname) { 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) { 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) { 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) { 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) { 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) { 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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -442,7 +442,7 @@ void CheckIO::invalidScanfError(const Token *tok) "terminating null byte.\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", - CWE119, false); + CWE119, Certainty::normal); } //--------------------------------------------------------------------------- @@ -567,7 +567,7 @@ void CheckIO::checkFormatString(const Token * const tok, const bool scanf_s) { 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(); // Count format string parameters.. @@ -1686,7 +1686,7 @@ void CheckIO::wrongPrintfScanfArgumentsError(const Token* tok, nonneg int numFunction) { 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; std::ostringstream errmsg; @@ -1699,13 +1699,13 @@ void CheckIO::wrongPrintfScanfArgumentsError(const Token* tok, << (numFunction != 1 ? " are" : " is") << " 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, nonneg int index, nonneg int numFunction) { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; std::ostringstream errmsg; errmsg << functionName << ": "; @@ -1714,13 +1714,13 @@ void CheckIO::wrongPrintfScanfPosixParameterPositionError(const Token* tok, cons } else { 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) { const Severity::SeverityType severity = getSeverity(argInfo); - if (!mSettings->isEnabled(severity)) + if (!mSettings->severity.isEnabled(severity)) return; std::ostringstream errmsg; 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 "; argumentType(errmsg, argInfo); 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) { const Severity::SeverityType severity = getSeverity(argInfo); - if (!mSettings->isEnabled(severity)) + if (!mSettings->severity.isEnabled(severity)) return; std::ostringstream errmsg; 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 "; argumentType(errmsg, argInfo); 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) { const Severity::SeverityType severity = getSeverity(argInfo); - if (!mSettings->isEnabled(severity)) + if (!mSettings->severity.isEnabled(severity)) return; std::ostringstream errmsg; 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 "; argumentType(errmsg, argInfo); 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) { const Severity::SeverityType severity = getSeverity(argInfo); - if (!mSettings->isEnabled(severity)) + if (!mSettings->severity.isEnabled(severity)) return; std::ostringstream errmsg; errmsg << "%s in format string (no. " << numFormat << ") requires \'char *\' but the argument type is "; argumentType(errmsg, argInfo); 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) { const Severity::SeverityType severity = getSeverity(argInfo); - if (!mSettings->isEnabled(severity)) + if (!mSettings->severity.isEnabled(severity)) return; std::ostringstream errmsg; errmsg << "%n in format string (no. " << numFormat << ") requires \'int *\' but the argument type is "; argumentType(errmsg, argInfo); 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) { const Severity::SeverityType severity = getSeverity(argInfo); - if (!mSettings->isEnabled(severity)) + if (!mSettings->severity.isEnabled(severity)) return; std::ostringstream errmsg; errmsg << "%p in format string (no. " << numFormat << ") requires an address but the argument type is "; argumentType(errmsg, argInfo); 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) { @@ -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) { const Severity::SeverityType severity = getSeverity(argInfo); - if (!mSettings->isEnabled(severity)) + if (!mSettings->severity.isEnabled(severity)) return; std::ostringstream errmsg; 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 "; argumentType(errmsg, argInfo); 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) { const Severity::SeverityType severity = getSeverity(argInfo); - if (!mSettings->isEnabled(severity)) + if (!mSettings->severity.isEnabled(severity)) return; std::ostringstream errmsg; 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 "; argumentType(errmsg, argInfo); 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) { const Severity::SeverityType severity = getSeverity(argInfo); - if (!mSettings->isEnabled(severity)) + if (!mSettings->severity.isEnabled(severity)) return; std::ostringstream errmsg; 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 "; argumentType(errmsg, argInfo); 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) @@ -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) { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; std::ostringstream errmsg; 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) @@ -1987,14 +1987,14 @@ void CheckIO::invalidScanfFormatWidthError(const Token* tok, nonneg int numForma std::ostringstream errmsg; 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; errmsg << "Width " << width << " given in format string (no. " << numFormat << ") is smaller than destination buffer" << " '" << 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 { 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."; - reportError(tok, Severity::error, "invalidScanfFormatWidth", errmsg.str(), CWE687, false); + reportError(tok, Severity::error, "invalidScanfFormatWidth", errmsg.str(), CWE687, Certainty::normal); } } diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 0b69e1739..093ef5302 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -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) { const std::list 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) { - if (mSettings->checkLibrary && mSettings->isEnabled(Settings::INFORMATION)) { + if (mSettings->checkLibrary && mSettings->severity.isEnabled(Severity::information)) { reportError(tok, Severity::information, "checkLibraryUseIgnore", @@ -170,9 +170,9 @@ void CheckLeakAutoVar::doubleFreeError(const Token *tok, const Token *prevFreeTo const std::list locations = { prevFreeTok, tok }; 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 - 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); } diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 0aa9c4044..0df4acac1 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -297,7 +297,7 @@ void CheckMemoryLeak::reportErr(const Token *tok, Severity::SeverityType severit void CheckMemoryLeak::reportErr(const std::list &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_) mErrorLogger_->reportErr(errmsg); 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) { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; reportError(tok, Severity::style, "unsafeClassCanLeak", "$symbol:" + classname + "\n" "$symbol:" + varname + "\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. // There is no checking how these functions are used and therefore it // isn't established if there is real leaks or not. - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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) { - 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) { // 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; 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) { - 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) { - 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) @@ -1140,5 +1140,5 @@ void CheckMemoryLeakNoVar::unsafeArgAllocError(const Token *tok, const std::stri "$symbol:" + funcName + "\n" "Unsafe allocation. If $symbol() throws, memory could be leaked. Use " + factoryFunc + "<" + objType + ">() instead.", CWE401, - true); // Inconclusive because funcName may never throw + Certainty::inconclusive); // Inconclusive because funcName may never throw } diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index c1fd91ca4..96d61fdfd 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -277,7 +277,7 @@ static bool isNullablePointer(const Token* tok, const Settings* settings) 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()) { 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"); if (!tok) { - reportError(tok, Severity::error, "nullPointer", "Null pointer dereference", CWE_NULL_POINTER_DEREFERENCE, false); - reportError(tok, Severity::warning, "nullPointerDefaultArg", errmsgdefarg, CWE_NULL_POINTER_DEREFERENCE, false); - reportError(tok, Severity::warning, "nullPointerRedundantCheck", errmsgcond, 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, Certainty::normal); + reportError(tok, Severity::warning, "nullPointerRedundantCheck", errmsgcond, CWE_NULL_POINTER_DEREFERENCE, Certainty::normal); return; } 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; } @@ -439,9 +439,9 @@ void CheckNullPointer::nullPointerError(const Token *tok, const std::string &var const ErrorPath errorPath = getErrorPath(tok, value, "Null pointer dereference"); 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) { - 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 { std::string errmsg; 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, "nullPointer", 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); if (!value) continue; - if (!mSettings->inconclusive && value->isInconclusive()) + if (!mSettings->certainty.isEnabled(Certainty::inconclusive) && value->isInconclusive()) continue; - if (value->condition && !mSettings->isEnabled(Settings::WARNING)) + if (value->condition && !mSettings->severity.isEnabled(Severity::warning)) continue; if (value->condition) redundantConditionWarning(tok, value, value->condition, value->isInconclusive()); @@ -515,7 +515,7 @@ void CheckNullPointer::pointerArithmeticError(const Token* tok, const ValueFlow: "nullPointerArithmetic", errmsg, CWE_INCORRECT_CALCULATION, - inconclusive); + inconclusive ? Certainty::inconclusive : Certainty::normal); } 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", errmsg, CWE_INCORRECT_CALCULATION, - inconclusive); + inconclusive ? Certainty::inconclusive : Certainty::normal); } std::string CheckNullPointer::MyFileInfo::toString() const @@ -587,7 +587,7 @@ bool CheckNullPointer::analyseWholeProgram(const CTU::FileInfo *ctu, const std:: continue; for (const CTU::FileInfo::UnsafeUsage &unsafeUsage : fi->unsafeUsage) { for (int warning = 0; warning <= 1; warning++) { - if (warning == 1 && !settings.isEnabled(Settings::WARNING)) + if (warning == 1 && !settings.severity.isEnabled(Severity::warning)) break; const std::list &locationList = @@ -605,7 +605,7 @@ bool CheckNullPointer::analyseWholeProgram(const CTU::FileInfo *ctu, const std:: warning ? Severity::warning : Severity::error, "Null pointer dereference: " + unsafeUsage.myArgumentName, "ctunullpointer", - CWE_NULL_POINTER_DEREFERENCE, false); + CWE_NULL_POINTER_DEREFERENCE, Certainty::normal); errorLogger.reportErr(errmsg); foundErrors = true; diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 6ec9e0706..7db0ccc03 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -80,7 +80,7 @@ static const struct CWE CWE783(783U); // Operator Precedence Logic Error //---------------------------------------------------------------------------------- void CheckOther::checkCastIntToCharAndBack() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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 " "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 " - "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() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -209,7 +209,7 @@ void CheckOther::clarifyCalculationError(const Token *tok, const std::string &op "clarifyCalculation", "Clarify calculation precedence for '" + op + "' and '?'.\n" "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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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" "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() { - if (!mSettings->inconclusive || !mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->certainty.isEnabled(Certainty::inconclusive) || !mSettings->severity.isEnabled(Severity::warning)) return; const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -274,7 +274,7 @@ void CheckOther::checkSuspiciousSemicolon() void CheckOther::suspiciousSemicolonError(const Token* tok) { 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() { // Only valid on C++ code - if (!mSettings->isEnabled(Settings::STYLE) || !mTokenizer->isCPP()) + if (!mSettings->severity.isEnabled(Severity::style) || !mTokenizer->isCPP()) return; 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: " "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 " - "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() { - if (!mSettings->isEnabled(Settings::PORTABILITY)) + if (!mSettings->severity.isEnabled(Severity::portability)) return; - const bool printInconclusive = mSettings->inconclusive; + const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { 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) { 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 - 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" "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 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() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); 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; FwdAnalysis fwdAnalysis(mTokenizer->isCPP(), mSettings->library); @@ -538,7 +538,7 @@ void CheckOther::redundantCopyError(const Token *tok1, const Token* tok2, const const std::list callstack = { tok1, tok2 }; reportError(callstack, Severity::performance, "redundantCopy", "$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) @@ -546,7 +546,7 @@ void CheckOther::redundantCopyInSwitchError(const Token *tok1, const Token* tok2 const std::list callstack = { tok1, tok2 }; reportError(callstack, Severity::style, "redundantCopyInSwitch", "$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) @@ -556,11 +556,11 @@ void CheckOther::redundantAssignmentError(const Token *tok1, const Token* tok2, reportError(errorPath, Severity::style, "redundantAssignment", "$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. 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 reportError(errorPath, Severity::style, "redundantAssignment", "$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) @@ -569,7 +569,7 @@ void CheckOther::redundantInitializationError(const Token *tok1, const Token* to reportError(errorPath, Severity::style, "redundantInitialization", "$symbol:" + var + "\nRedundant initialization for '$symbol'. The initialized value is overwritten before it is read.", CWE563, - inconclusive); + inconclusive ? Certainty::inconclusive : Certainty::normal); } 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") }; reportError(errorPath, Severity::style, "redundantAssignInSwitch", "$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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -727,7 +727,7 @@ void CheckOther::redundantBitwiseOperationInSwitchError(const Token *tok, const //--------------------------------------------------------------------------- void CheckOther::checkSuspiciousCaseInSwitch() { - if (!mSettings->inconclusive || !mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->certainty.isEnabled(Certainty::inconclusive) || !mSettings->severity.isEnabled(Severity::warning)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -761,7 +761,7 @@ void CheckOther::suspiciousCaseInSwitchError(const Token* tok, const std::string { reportError(tok, Severity::warning, "suspiciousCase", "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() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; - const bool printInconclusive = mSettings->inconclusive; + const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { 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", "Consecutive return, break, continue, goto or throw statements are unnecessary.\n" "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) { 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) return; - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -1082,7 +1082,7 @@ void CheckOther::variableScopeError(const Token *tok, const std::string &varname " }\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() { // This is experimental for now. See #5076 - if (!mSettings->experimental) + if (!mSettings->certainty.isEnabled(Certainty::experimental)) return; - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { @@ -1130,7 +1130,7 @@ void CheckOther::commaSeparatedReturnError(const Token *tok) " return a + 1,\n" " b++;\n" "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() { - if (!mSettings->isEnabled(Settings::PERFORMANCE) || mTokenizer->isC()) + if (!mSettings->severity.isEnabled(Severity::performance) || mTokenizer->isC()) return; const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -1275,7 +1275,7 @@ void CheckOther::checkPassByReference() } else continue; - if (inconclusive && !mSettings->inconclusive) + if (inconclusive && !mSettings->certainty.isEnabled(Certainty::inconclusive)) continue; const bool isConst = var->isConst(); @@ -1300,7 +1300,7 @@ void CheckOther::passedByValueError(const Token *tok, const std::string &parname "$symbol:" + parname + "\n" "Function parameter '$symbol' should be passed by const reference.\n" "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) @@ -1349,7 +1349,7 @@ static bool isVariableMutableInInitializer(const Token* start, const Token * end void CheckOther::checkConstVariable() { - if (!mSettings->isEnabled(Settings::STYLE) || mTokenizer->isC()) + if (!mSettings->severity.isEnabled(Severity::style) || mTokenizer->isC()) return; 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)."; } - 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() { - const bool warning = mSettings->isEnabled(Settings::WARNING); - const bool portability = mSettings->isEnabled(Settings::PORTABILITY); + const bool warning = mSettings->severity.isEnabled(Severity::warning); + const bool portability = mSettings->severity.isEnabled(Severity::portability); if (!warning && !portability) 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. If the value " "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) @@ -1541,7 +1541,7 @@ void CheckOther::unknownSignCharArrayIndexError(const Token *tok) "unknownSignCharArrayIndex", "'char' type used as array index.\n" "'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) @@ -1555,7 +1555,7 @@ void CheckOther::charBitOpError(const Token *tok) " int i = 0 | c;\n" " if (i & 0x8000)\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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { @@ -1693,7 +1693,7 @@ void CheckOther::checkIncompleteStatement() // Possible archive continue; bool inconclusive = Token::Match(tok, "%cop%"); - if (mSettings->inconclusive || !inconclusive) + if (mSettings->certainty.isEnabled(Certainty::inconclusive) || !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."; else 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) { if (!tok && !value) { - reportError(tok, Severity::error, "zerodiv", "Division by zero.", CWE369, false); - reportError(tok, Severity::error, "zerodivcond", ValueFlow::eitherTheConditionIsRedundant(nullptr) + " or there is 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, Certainty::normal); return; } @@ -1761,7 +1761,7 @@ void CheckOther::zerodivError(const Token *tok, const ValueFlow::Value *value) reportError(errorPath, value->errorSeverity() ? Severity::error : Severity::warning, 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() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { if (tok->str() != "/") @@ -1788,7 +1788,7 @@ void CheckOther::nanInArithmeticExpressionError(const Token *tok) reportError(tok, Severity::style, "nanInArithmeticExpression", "Using NaN/Inf in a computation.\n" "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()) return; - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -1824,7 +1824,7 @@ void CheckOther::misusedScopeObjectError(const Token *tok, const std::string& va reportError(tok, Severity::style, "unusedScopedObject", "$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) @@ -1854,7 +1854,7 @@ void CheckOther::checkDuplicateBranch() // and their conditional code is a duplicate of the condition that // is always true just in case it would be false. See for instance // abiword. - if (!mSettings->isEnabled(Settings::STYLE) || !mSettings->inconclusive) + if (!mSettings->severity.isEnabled(Severity::style) || !mSettings->certainty.isEnabled(Certainty::inconclusive)) return; 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" "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 " - "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 inconclusive; std::map allocation; - const bool printInconclusive = mSettings->inconclusive; + const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { 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") alloc += "()"; 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() { - const bool styleEnabled = mSettings->isEnabled(Settings::STYLE); - const bool warningEnabled = mSettings->isEnabled(Settings::WARNING); + const bool styleEnabled = mSettings->severity.isEnabled(Severity::style); + const bool warningEnabled = mSettings->severity.isEnabled(Severity::warning); if (!styleEnabled && !warningEnabled) return; @@ -2113,7 +2113,7 @@ void CheckOther::checkDuplicateExpression() } if (!differentDomain && !isUniqueExpression(tok->astOperand2())) duplicateAssignExpressionError(var1, var2, false); - else if (mSettings->inconclusive) + else if (mSettings->certainty.isEnabled(Certainty::inconclusive)) 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" "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 " - "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) @@ -2242,7 +2242,7 @@ void CheckOther::duplicateExpressionError(const Token *tok1, const Token *tok2, reportError(errors, Severity::style, id, msg + ".\n" "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 " - "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) @@ -2256,7 +2256,7 @@ void CheckOther::duplicateAssignExpressionError(const Token *tok1, const Token * "Same expression used in consecutive assignments of '" + var1 + "' and '" + var2 + "'.\n" "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 " - "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) @@ -2264,14 +2264,14 @@ void CheckOther::duplicateExpressionTernaryError(const Token *tok, ErrorPath err errors.emplace_back(tok, ""); 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 " - "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) { 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 " - "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) @@ -2279,7 +2279,7 @@ void CheckOther::selfAssignmentError(const Token *tok, const std::string &varnam reportError(tok, Severity::warning, "selfAssignment", "$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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -2328,7 +2328,7 @@ void CheckOther::checkComparisonFunctionIsAlwaysTrueOrFalseError(const Token* to "$symbol:" + functionName + "\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 + ") " - "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() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -2385,26 +2385,26 @@ void CheckOther::unsignedLessThanZeroError(const Token *tok, const ValueFlow::Va "$symbol:" + varname + "\n" "Checking if unsigned expression '$symbol' is less than zero.\n" "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) { 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) { reportError(getErrorPath(tok, v, "Unsigned positive"), Severity::style, "unsignedPositive", "$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) { 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 */ @@ -2429,7 +2429,7 @@ static bool constructorTakesReference(const Scope * const classScope) //--------------------------------------------------------------------------- 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; 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 unnecessary data copying by converting '$symbol' to const reference.", 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() { - 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()) { 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 // is used often in a project and works as expected then this is // 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 - 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() { - if (!mSettings->inconclusive) + if (!mSettings->certainty.isEnabled(Certainty::inconclusive)) return; - const bool printWarning = mSettings->isEnabled(Settings::WARNING); - const bool printPortability = mSettings->isEnabled(Settings::PORTABILITY); + const bool printWarning = mSettings->severity.isEnabled(Severity::warning); + const bool printPortability = mSettings->severity.isEnabled(Severity::portability); if (!printPortability && !printWarning) return; @@ -2576,13 +2576,13 @@ void CheckOther::incompleteArrayFillError(const Token* tok, const std::string& b "$symbol:" + buffer + "\n" "$symbol:" + function + "\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 reportError(tok, Severity::warning, "incompleteArrayFill", "$symbol:" + buffer + "\n" "$symbol:" + function + "\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() { - if (!mSettings->isEnabled(Settings::PORTABILITY)) + if (!mSettings->severity.isEnabled(Severity::portability)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -2669,12 +2669,12 @@ void CheckOther::varFuncNullUBError(const Token *tok) " h();\n" " g();\n" " return 0;\n" - "}", CWE475, false); + "}", CWE475, Certainty::normal); } void CheckOther::checkRedundantPointerOp() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; 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", "$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() @@ -2745,12 +2745,12 @@ void CheckOther::checkInterlockedDecrement() void CheckOther::raceAfterInterlockedDecrementError(const Token* tok) { 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() { - if (!mSettings->isEnabled(Settings::STYLE) && !mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->severity.isEnabled(Severity::warning)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -2771,7 +2771,7 @@ void CheckOther::checkUnusedLabel() 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; std::string id = "unusedLabel"; @@ -2791,7 +2791,7 @@ void CheckOther::unusedLabelError(const Token* tok, bool inSwitch, bool hasIfdef id, msg, CWE398, - false); + Certainty::normal); } @@ -2840,7 +2840,7 @@ void CheckOther::checkEvaluationOrder() tok->str() == "=" && parent->str() == "=" && 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)) selfAssignmentError(parent, tok->astOperand1()->expressionString()); break; @@ -2871,15 +2871,15 @@ void CheckOther::checkEvaluationOrder() void CheckOther::unknownEvaluationOrder(const Token* tok) { 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() { - 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; CheckUninitVar checkUninitVar(mTokenizer, mSettings, mErrorLogger); - const bool reportInconclusive = mSettings->inconclusive; + const bool reportInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { 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) { if (!tok) { - reportError(tok, Severity::warning, "accessMoved", "Access of moved variable 'v'.", CWE672, false); - reportError(tok, Severity::warning, "accessForwarded", "Access of forwarded 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, Certainty::normal); 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 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() { - const bool style = mSettings->isEnabled(Settings::STYLE); - const bool inconclusive = mSettings->inconclusive; - const bool warning = mSettings->isEnabled(Settings::WARNING); + const bool style = mSettings->severity.isEnabled(Severity::style); + const bool inconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); + const bool warning = mSettings->severity.isEnabled(Severity::warning); if (!(warning || (style && inconclusive))) return; @@ -3048,7 +3048,7 @@ void CheckOther::funcArgNamesDifferent(const std::string & functionName, nonneg "$symbol:" + functionName + "\n" "Function '$symbol' argument " + MathLib::toString(index + 1) + " names different: declaration '" + (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, @@ -3075,7 +3075,7 @@ void CheckOther::funcArgOrderDifferent(const std::string & functionName, msg += definitions[i]->str(); } 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) @@ -3099,7 +3099,7 @@ static const Token *findShadowed(const Scope *scope, const std::string &varname, void CheckOther::checkShadowVariables() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); 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 id = "shadow" + 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) @@ -3162,7 +3162,7 @@ static bool isVariableExpression(const Token* tok) void CheckOther::checkKnownArgument() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); 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); - reportError(errorPath, Severity::style, id, errmsg, CWE570, false); + reportError(errorPath, Severity::style, id, errmsg, CWE570, Certainty::normal); } void CheckOther::checkComparePointers() @@ -3303,12 +3303,12 @@ void CheckOther::comparePointersError(const Token *tok, const ValueFlow::Value * } errorPath.emplace_back(tok, ""); 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() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { diff --git a/lib/checkpostfixoperator.cpp b/lib/checkpostfixoperator.cpp index e0c11b07d..b66a84009 100644 --- a/lib/checkpostfixoperator.cpp +++ b/lib/checkpostfixoperator.cpp @@ -44,7 +44,7 @@ static const struct CWE CWE398(398U); // Indicator of Poor Code Quality void CheckPostfixOperator::postfixOperator() { - if (!mSettings->isEnabled(Settings::PERFORMANCE)) + if (!mSettings->severity.isEnabled(Severity::performance)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -82,5 +82,5 @@ void CheckPostfixOperator::postfixOperatorError(const Token *tok) "Pre-increment/decrement can be more efficient than " "post-increment/decrement. Post-increment/decrement usually " "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); } diff --git a/lib/checksizeof.cpp b/lib/checksizeof.cpp index c7f144c14..f9496620f 100644 --- a/lib/checksizeof.cpp +++ b/lib/checksizeof.cpp @@ -41,7 +41,7 @@ static const struct CWE CWE682(682U); // Incorrect Calculation //--------------------------------------------------------------------------- void CheckSizeof::checkSizeofForNumericParameter() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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" "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')'" - " 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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { @@ -101,13 +101,13 @@ void CheckSizeof::sizeofForArrayParameterError(const Token *tok) " return sizeof(a);\n" " }\n" "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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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. " "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) { 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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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" "Calling sizeof for 'sizeof looks like a suspicious code and " "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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; - const bool printInconclusive = mSettings->inconclusive; + const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { if (!Token::simpleMatch(tok, "sizeof (")) @@ -319,14 +319,14 @@ void CheckSizeof::sizeofCalculation() void CheckSizeof::sizeofCalculationError(const Token *tok, bool inconclusive) { 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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { @@ -359,7 +359,7 @@ void CheckSizeof::sizeofFunction() void CheckSizeof::sizeofFunctionError(const Token *tok) { 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() { - if (!mSettings->isEnabled(Settings::WARNING) || !mSettings->inconclusive) + if (!mSettings->severity.isEnabled(Severity::warning) || !mSettings->certainty.isEnabled(Certainty::inconclusive)) return; // 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) { 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) @@ -395,12 +395,12 @@ void CheckSizeof::divideSizeofError(const Token *tok) reportError(tok, Severity::warning, "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, " - "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() { - if (!mSettings->isEnabled(Settings::PORTABILITY)) + if (!mSettings->severity.isEnabled(Severity::portability)) return; 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 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) { 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."; - 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) { 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."; - 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); } diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 32f5e4715..aa54104d1 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -80,9 +80,9 @@ void CheckStl::outOfBounds() continue; if (value.isImpossible()) continue; - if (value.isInconclusive() && !mSettings->inconclusive) + if (value.isInconclusive() && !mSettings->certainty.isEnabled(Certainty::inconclusive)) continue; - if (!value.errorSeverity() && !mSettings->isEnabled(Settings::WARNING)) + if (!value.errorSeverity() && !mSettings->severity.isEnabled(Severity::warning)) continue; if (Token::Match(parent, ". %name% (") && isElementAccessYield(container->getYield(parent->strAt(1)))) { if (value.intvalue == 0) { @@ -98,7 +98,7 @@ void CheckStl::outOfBounds() parent, tok->expressionString(), &value, indexTok->expressionString(), indexValue); continue; } - if (mSettings->isEnabled(Settings::WARNING)) { + if (mSettings->severity.isEnabled(Severity::warning)) { indexValue = indexTok->getMaxValue(true); if (indexValue && indexValue->intvalue >= value.intvalue) { outOfBoundsError( @@ -134,7 +134,7 @@ void CheckStl::outOfBounds() outOfBoundsError(parent, tok->expressionString(), &value, parent->astOperand2()->expressionString(), indexValue); continue; } - if (mSettings->isEnabled(Settings::WARNING)) { + if (mSettings->severity.isEnabled(Severity::warning)) { indexValue = parent->astOperand2() ? parent->astOperand2()->getMaxValue(true) : nullptr; if (indexValue && indexValue->intvalue >= value.intvalue) { outOfBoundsError(parent, tok->expressionString(), &value, parent->astOperand2()->expressionString(), indexValue); @@ -207,7 +207,7 @@ void CheckStl::outOfBoundsError(const Token *tok, const std::string &containerNa "containerOutOfBounds", "$symbol:" + containerName +"\n" + errmsg, 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 @@ -281,7 +281,7 @@ void CheckStl::outOfBoundsIndexExpressionError(const Token *tok, const Token *in "containerOutOfBoundsIndexExpression", "$symbol:" + varname +"\n" + errmsg, CWE398, - false); + Certainty::normal); } @@ -289,7 +289,7 @@ void CheckStl::outOfBoundsIndexExpressionError(const Token *tok, const Token *in // Error message for bad iterator usage.. 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) @@ -297,7 +297,7 @@ void CheckStl::iteratorsError(const Token* tok, const std::string& containerName reportError(tok, Severity::error, "iterators1", "$symbol:" + containerName1 + "\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) @@ -306,7 +306,7 @@ void CheckStl::iteratorsError(const Token* tok, const Token* containerTok, const reportError(callstack, Severity::error, "iterators2", "$symbol:" + containerName1 + "\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) @@ -314,7 +314,7 @@ void CheckStl::iteratorsError(const Token* tok, const Token* containerTok, const std::list callstack = { tok, containerTok }; reportError(callstack, Severity::error, "iterators3", "$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.. @@ -326,13 +326,13 @@ void CheckStl::dereferenceErasedError(const Token *erased, const Token* deref, c "$symbol:" + itername + "\n" "Iterator '$symbol' used after element has been erased.\n" "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 { reportError(deref, Severity::error, "eraseDereference", "$symbol:" + itername + "\n" "Invalid iterator '$symbol' used.\n" "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; if (!isIterator(var, inconclusiveType)) continue; - if (inconclusiveType && !mSettings->inconclusive) + if (inconclusiveType && !mSettings->certainty.isEnabled(Certainty::inconclusive)) continue; const int iteratorId = var->declarationId(); @@ -586,7 +586,7 @@ void CheckStl::mismatchingContainerIteratorError(const Token* tok, const Token* "mismatchingContainerIterator", "Iterator '" + iter + "' from different container '" + container + "' are used together.", CWE664, - false); + Certainty::normal); } // Error message for bad iterator usage.. @@ -599,7 +599,7 @@ void CheckStl::mismatchingContainersError(const Token* tok1, const Token* tok2) "mismatchingContainers", "Iterators of different containers '" + expr1 + "' and '" + expr2 + "' are used together.", CWE664, - false); + Certainty::normal); } 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")); reportError(tok1, Severity::warning, "mismatchingContainerExpression", "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) { - 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 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."; 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) @@ -1112,7 +1112,7 @@ void CheckStl::invalidContainerError(const Token *tok, const Token * /*contTok*/ errorPath.insert(errorPath.begin(), val->errorPath.begin(), val->errorPath.end()); std::string msg = "Using " + lifetimeMessage(tok, val, errorPath); 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) @@ -1120,7 +1120,7 @@ void CheckStl::invalidContainerReferenceError(const Token* tok, const Token* con std::string name = contTok ? contTok->expressionString() : "x"; std::string msg = "Reference to " + name; 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() @@ -1207,9 +1207,9 @@ void CheckStl::stlOutOfBounds() void CheckStl::stlOutOfBoundsError(const Token *tok, const std::string &num, const std::string &var, bool 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 - 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() @@ -1243,7 +1243,7 @@ void CheckStl::negativeIndexError(const Token *tok, const ValueFlow::Value &inde << ", otherwise there is negative array index " << index.intvalue << "."; else 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() @@ -1337,7 +1337,7 @@ void CheckStl::stlBoundariesError(const Token *tok) reportError(tok, Severity::error, "stlBoundaries", "Dangerous comparison using operator< on iterator.\n" "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) @@ -1363,8 +1363,8 @@ static bool if_findCompare(const Token * const tokBack, bool stdStringLike) void CheckStl::if_find() { - const bool printWarning = mSettings->isEnabled(Settings::WARNING); - const bool printPerformance = mSettings->isEnabled(Settings::PERFORMANCE); + const bool printWarning = mSettings->severity.isEnabled(Severity::warning); + const bool printPerformance = mSettings->severity.isEnabled(Severity::performance); if (!printWarning && !printPerformance) 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 " "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, " - "you should compare with std::string::npos.", CWE597, false); + "you should compare with std::string::npos.", CWE597, Certainty::normal); 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 isMapFind(const Token *tok) @@ -1545,7 +1545,7 @@ static const Token *findInsertValue(const Token *tok, const Token *containerTok, void CheckStl::checkFindInsert() { - if (!mSettings->isEnabled(Settings::PERFORMANCE)) + if (!mSettings->severity.isEnabled(Severity::performance)) return; const SymbolDatabase *const symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -1590,7 +1590,7 @@ void CheckStl::checkFindInsert() void CheckStl::checkFindInsertError(const Token *tok) { 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() { - if (!mSettings->isEnabled(Settings::PERFORMANCE)) + if (!mSettings->severity.isEnabled(Severity::performance)) return; if (mSettings->standards.cpp >= Standards::CPP11) @@ -1660,12 +1660,12 @@ void CheckStl::sizeError(const Token *tok) "Checking for '$symbol' emptiness might be inefficient. " "Using $symbol.empty() instead of $symbol.size() can be faster. " "$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() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); @@ -1699,12 +1699,12 @@ void CheckStl::redundantIfRemoveError(const Token *tok) 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. " - "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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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 " << "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() { - const bool printInconclusive = mSettings->inconclusive; - const bool printPerformance = mSettings->isEnabled(Settings::PERFORMANCE); + const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); + const bool printPerformance = mSettings->severity.isEnabled(Severity::performance); 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) { 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) { 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) @@ -1986,7 +1986,7 @@ void CheckStl::string_c_strParam(const Token* tok, nonneg int number) 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" "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() { - const bool printPerformance = mSettings->isEnabled(Settings::PERFORMANCE); - const bool printWarning = mSettings->isEnabled(Settings::WARNING); + const bool printPerformance = mSettings->severity.isEnabled(Severity::performance); + const bool printWarning = mSettings->severity.isEnabled(Severity::warning); if (!printPerformance && !printWarning) return; @@ -2055,7 +2055,7 @@ void CheckStl::uselessCallsReturnValueError(const Token *tok, const std::string << "(" << varname << "." << function << "(" << varname << ")). As it is currently the " << "code is inefficient. It is possible either the string searched ('" << 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) @@ -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" "The 'swap()' function has no logical effect when given itself as parameter " "($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) { 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 - 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) { - 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) @@ -2087,14 +2087,14 @@ void CheckStl::uselessCallsRemoveError(const Token *tok, const std::string& func "$symbol:" + function + "\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. " - "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. // E.g. if (*i && i != str.end()) { } void CheckStl::checkDereferenceInvalidIterator() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; // Iterate over "if", "while", and "for" conditions where there may @@ -2156,7 +2156,7 @@ void CheckStl::checkDereferenceInvalidIterator() 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()) { 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 errmsgcond("$symbol:" + varname + '\n' + ValueFlow::eitherTheConditionIsRedundant(value ? value->condition : nullptr) + " or there is possible dereference of an invalid iterator: $symbol."); if (!tok || !value) { - reportError(tok, Severity::error, "derefInvalidIterator", "Dereference of an invalid iterator", CWE825, false); - reportError(tok, Severity::warning, "derefInvalidIteratorRedundantCheck", errmsgcond, CWE825, false); + reportError(tok, Severity::error, "derefInvalidIterator", "Dereference of an invalid iterator", CWE825, Certainty::normal); + reportError(tok, Severity::warning, "derefInvalidIteratorRedundantCheck", errmsgcond, CWE825, Certainty::normal); return; } 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"); 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 { std::string errmsg; 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, "derefInvalidIterator", 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", "$symbol:" + iterName + "\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); if (!value) continue; - if (value->isInconclusive() && !mSettings->inconclusive) + if (value->isInconclusive() && !mSettings->certainty.isEnabled(Certainty::inconclusive)) continue; - if (!value->errorSeverity() && !mSettings->isEnabled(Settings::WARNING)) + if (!value->errorSeverity() && !mSettings->severity.isEnabled(Severity::warning)) continue; if (Token::Match(tok, "%name% . %name% (")) { 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"); - 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) { 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) @@ -2481,7 +2481,7 @@ static std::string minmaxCompare(const Token *condTok, nonneg int loopVar, nonne void CheckStl::useStlAlgorithm() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; for (const Scope *function : mTokenizer->getSymbolDatabase()->functionScopes) { 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, "knownEmptyContainer", - msg, CWE398, false); + msg, CWE398, Certainty::normal); } static bool isKnownEmptyContainer(const Token* tok) @@ -2664,7 +2664,7 @@ static bool isKnownEmptyContainer(const Token* tok) void CheckStl::knownEmptyContainer() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; for (const Scope *function : mTokenizer->getSymbolDatabase()->functionScopes) { 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, "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) { reportError(tok, Severity::warning, "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() diff --git a/lib/checkstring.cpp b/lib/checkstring.cpp index 334c4ecd3..1701f2516 100644 --- a/lib/checkstring.cpp +++ b/lib/checkstring.cpp @@ -87,7 +87,7 @@ void CheckString::stringLiteralWriteError(const Token *tok, const Token *strValu } 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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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", "Unnecessary comparison of static strings.\n" "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) @@ -153,7 +153,7 @@ void CheckString::alwaysTrueStringVariableCompareError(const Token *tok, const s reportError(tok, Severity::warning, "stringCompare", "Comparison of identical string variables.\n" "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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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"; 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) { 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(); else if (tok && tok->astOperand2() && tok->astOperand2()->tokType() == Token::eChar && tok->astOperand2()->isLong()) 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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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) { - 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) @@ -311,7 +311,7 @@ void CheckString::incorrectStringBooleanError(const Token *tok, const std::strin reportError(tok, Severity::warning, 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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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) " "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 " - "to sprintf() or snprintf(), the results are undefined.\"", CWE628, false); + "to sprintf() or snprintf(), the results are undefined.\"", CWE628, Certainty::normal); } diff --git a/lib/checktype.cpp b/lib/checktype.cpp index 6bd7c344f..e037b79f0 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -107,7 +107,7 @@ void CheckType::tooBigBitwiseShiftError(const Token *tok, int lhsbits, const Val const char id[] = "shiftTooManyBits"; 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; } @@ -118,7 +118,7 @@ void CheckType::tooBigBitwiseShiftError(const Token *tok, int lhsbits, const Val if (rhsbits.condition) 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) @@ -131,7 +131,7 @@ void CheckType::tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, con if (cpp14) behaviour = "implementation-defined"; 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; } @@ -146,9 +146,9 @@ void CheckType::tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, con if (cpp14) severity = Severity::portability; - if ((severity == Severity::portability) && !mSettings->isEnabled(Settings::PORTABILITY)) + if ((severity == Severity::portability) && !mSettings->severity.isEnabled(Severity::portability)) 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(), msg, 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() { - if (!mSettings->isEnabled(Settings::WARNING)) + if (!mSettings->severity.isEnabled(Severity::warning)) return; 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."; if (!negativeValue) - reportError(tok, Severity::warning, "signConversion", msg.str(), CWE195, false); + reportError(tok, Severity::warning, "signConversion", msg.str(), CWE195, Certainty::normal); else { const ErrorPath &errorPath = getErrorPath(tok,negativeValue,"Negative value is converted to an unsigned value"); reportError(errorPath, @@ -275,7 +275,7 @@ void CheckType::signConversionError(const Token *tok, const ValueFlow::Value *ne Check::getMessageId(*negativeValue, "signConversion").c_str(), msg.str(), 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() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; // Assignments.. @@ -362,7 +362,7 @@ void CheckType::longCastAssignError(const Token *tok) Severity::style, "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 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) @@ -371,7 +371,7 @@ void CheckType::longCastReturnError(const Token *tok) Severity::style, "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 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"), value.errorSeverity() ? Severity::error : Severity::warning, "floatConversionOverflow", - errmsg.str(), CWE190, value.isInconclusive()); + errmsg.str(), CWE190, value.isInconclusive() ? Certainty::inconclusive : Certainty::normal); } diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index ecde5a96c..b2d2a8665 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1287,7 +1287,7 @@ bool CheckUninitVar::isMemberVariableUsage(const Token *tok, bool isPointer, All tok->astParent()->astParent()->astParent()->astOperand2() == tok->astParent()->astParent()) return true; - else if (mSettings->experimental && + else if (mSettings->certainty.isEnabled(Certainty::experimental) && !isPointer && Token::Match(tok->tokAt(-2), "[(,] & %name% [,)]") && 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_) { - 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) { - 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) { 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) @@ -1317,7 +1317,7 @@ void CheckUninitVar::uninitStructMemberError(const Token *tok, const std::string reportError(tok, Severity::error, "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) @@ -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, "ctuuninitvar", CWE_USE_OF_UNINITIALIZED_VARIABLE, - false); + Certainty::normal); errorLogger.reportErr(errmsg); foundErrors = true; diff --git a/lib/checkunusedfunctions.cpp b/lib/checkunusedfunctions.cpp index 5dba2eda0..eded8507d 100644 --- a/lib/checkunusedfunctions.cpp +++ b/lib/checkunusedfunctions.cpp @@ -331,7 +331,7 @@ void CheckUnusedFunctions::unusedFunctionError(ErrorLogger * const errorLogger, 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) errorLogger->reportErr(errmsg); else @@ -340,7 +340,7 @@ void CheckUnusedFunctions::unusedFunctionError(ErrorLogger * const errorLogger, 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; if (settings->jobs == 1 && settings->buildDir.empty()) instance.parseTokens(*tokenizer, tokenizer->list.getFiles().front().c_str(), settings); diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 26e05dd50..3f5a2c0b1 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -1142,7 +1142,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const void CheckUnusedVar::checkFunctionVariableUsage() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; if (mSettings->clang) @@ -1270,7 +1270,7 @@ void CheckUnusedVar::checkFunctionVariableUsage() FwdAnalysis fwdAnalysis(mTokenizer->isCPP(), mSettings->library); if (fwdAnalysis.unusedValue(expr, start, scope->bodyEnd)) { if (!bailoutTypeName.empty() && bailoutTypeName != "auto") { - if (mSettings->checkLibrary && mSettings->isEnabled(Settings::INFORMATION)) { + if (mSettings->checkLibrary && mSettings->severity.isEnabled(Severity::information)) { reportError(tok, Severity::information, "checkLibraryCheckType", @@ -1334,25 +1334,25 @@ void CheckUnusedVar::checkFunctionVariableUsage() 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) { - 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) { 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 - 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) { - 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() { - if (!mSettings->isEnabled(Settings::STYLE)) + if (!mSettings->severity.isEnabled(Severity::style)) return; 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) { 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) diff --git a/lib/checkvaarg.cpp b/lib/checkvaarg.cpp index 74151be8e..bb4a151b2 100644 --- a/lib/checkvaarg.cpp +++ b/lib/checkvaarg.cpp @@ -48,7 +48,7 @@ void CheckVaarg::va_start_argument() { const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase(); 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) { 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) { 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) { 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) { 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) { 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) { 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); } diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 10e2ff233..a80c3a1f9 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -356,7 +356,7 @@ static bool reportClangErrors(std::istream &is, std::function mSettings.maxConfigs) { - if (mSettings.isEnabled(Settings::INFORMATION)) { + if (mSettings.severity.isEnabled(Severity::information)) { tooManyConfigsError(Path::toNativeSeparators(filename),configurations.size()); } else { mTooManyConfigs = true; @@ -842,14 +842,14 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string Severity::error, e.errorMessage, 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); } } - if (!hasValidConfig && configurations.size() > 1 && mSettings.isEnabled(Settings::INFORMATION)) { + if (!hasValidConfig && configurations.size() > 1 && mSettings.severity.isEnabled(Severity::information)) { std::string msg; 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:"; @@ -865,7 +865,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string Severity::information, msg, "noValidConfiguration", - false); + Certainty::normal); reportErr(errmsg); } @@ -891,7 +891,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string // In jointSuppressionReport mode, unmatched suppressions are // 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())); } @@ -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 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); std::list callstack(1, loc1); @@ -914,7 +914,7 @@ void CppCheck::internalError(const std::string &filename, const std::string &msg Severity::information, fullmsg, "internalError", - false); + Certainty::normal); mErrorLogger.reportErr(errmsg); } else { @@ -1163,7 +1163,7 @@ void CppCheck::executeRules(const std::string &tokenlist, const Tokenizer &token Severity::error, msg, "pcre_compile", - false); + Certainty::normal); reportErr(errmsg); } @@ -1184,7 +1184,7 @@ void CppCheck::executeRules(const std::string &tokenlist, const Tokenizer &token Severity::error, msg, "pcre_study", - false); + Certainty::normal); reportErr(errmsg); // 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, std::string("pcre_exec failed: ") + errorMessage, "pcre_exec", - false); + Certainty::normal); reportErr(errmsg); } @@ -1242,7 +1242,7 @@ void CppCheck::executeRules(const std::string &tokenlist, const Tokenizer &token summary = "found '" + str.substr(pos1, pos2 - pos1) + "'"; else 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 reportErr(errmsg); @@ -1320,12 +1320,12 @@ Settings &CppCheck::settings() void CppCheck::tooManyConfigsError(const std::string &file, const int numberOfConfigurations) { - if (!mSettings.isEnabled(Settings::INFORMATION) && !mTooManyConfigs) + if (!mSettings.severity.isEnabled(Severity::information) && !mTooManyConfigs) return; mTooManyConfigs = false; - if (mSettings.isEnabled(Settings::INFORMATION) && file.empty()) + if (mSettings.severity.isEnabled(Severity::information) && file.empty()) return; std::list loclist; @@ -1354,7 +1354,7 @@ void CppCheck::tooManyConfigsError(const std::string &file, const int numberOfCo Severity::information, msg.str(), "toomanyconfigs", CWE398, - false); + Certainty::normal); reportErr(errmsg); } @@ -1363,7 +1363,7 @@ void CppCheck::purgedConfigurationMessage(const std::string &file, const std::st { mTooManyConfigs = false; - if (mSettings.isEnabled(Settings::INFORMATION) && file.empty()) + if (mSettings.severity.isEnabled(Severity::information) && file.empty()) return; std::list loclist; @@ -1378,7 +1378,7 @@ void CppCheck::purgedConfigurationMessage(const std::string &file, const std::st Severity::information, "The configuration '" + configuration + "' was not checked because its code equals another one.", "purgedConfiguration", - false); + Certainty::normal); reportErr(errmsg); } @@ -1457,11 +1457,11 @@ void CppCheck::bughuntingReport(const std::string &str) void CppCheck::getErrorMessages() { Settings s(mSettings); - s.addEnabled("warning"); - s.addEnabled("style"); - s.addEnabled("portability"); - s.addEnabled("performance"); - s.addEnabled("information"); + s.severity.enable(Severity::warning); + s.severity.enable(Severity::style); + s.severity.enable(Severity::portability); + s.severity.enable(Severity::performance); + s.severity.enable(Severity::information); purgedConfigurationMessage("",""); @@ -1577,7 +1577,7 @@ void CppCheck::analyseWholeProgram(const std::string &buildDir, const std::map fileInfoList; CTU::FileInfo ctuFileInfo; @@ -1635,5 +1635,5 @@ void CppCheck::analyseWholeProgram(const std::string &buildDir, const std::map &callStack, const std::string& file1, Severity::SeverityType severity, const std::string &msg, const std::string &id, bool inconclusive) : +ErrorMessage::ErrorMessage(const std::list &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 id(id), // set the message id file0(file1), incomplete(false), severity(severity), // severity for this error message cwe(0U), - inconclusive(inconclusive), + certainty(certainty), hash(0) { // set the summary and verbose messages @@ -87,22 +87,22 @@ ErrorMessage::ErrorMessage(const std::list &callStack, const std:: -ErrorMessage::ErrorMessage(const std::list &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 &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 id(id), // set the message id file0(file1), incomplete(false), severity(severity), // severity for this error message cwe(cwe.id), - inconclusive(inconclusive), + certainty(certainty), hash(0) { // set the summary and verbose messages setmsg(msg); } -ErrorMessage::ErrorMessage(const std::list& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, bool inconclusive) - : id(id), incomplete(false), severity(severity), cwe(0U), inconclusive(inconclusive), hash(0) +ErrorMessage::ErrorMessage(const std::list& 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), certainty(certainty), hash(0) { // Format callstack for (std::list::const_iterator it = callstack.begin(); it != callstack.end(); ++it) { @@ -120,8 +120,8 @@ ErrorMessage::ErrorMessage(const std::list& callstack, const Token } -ErrorMessage::ErrorMessage(const std::list& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, const CWE &cwe, bool inconclusive, bool bugHunting) - : id(id), incomplete(false), severity(severity), cwe(cwe.id), inconclusive(inconclusive) +ErrorMessage::ErrorMessage(const std::list& 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), certainty(certainty) { // Format callstack for (const Token *tok: callstack) { @@ -145,8 +145,8 @@ ErrorMessage::ErrorMessage(const std::list& callstack, const Token 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) - : id(id), incomplete(false), severity(severity), cwe(cwe.id), inconclusive(inconclusive) +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), certainty(certainty) { // Format callstack for (const ErrorPathItem& e: errorPath) { @@ -181,7 +181,7 @@ ErrorMessage::ErrorMessage(const tinyxml2::XMLElement * const errmsg) : incomplete(false), severity(Severity::none), cwe(0U), - inconclusive(false) + certainty(Certainty::normal) { const char * const unknown = ""; @@ -195,7 +195,7 @@ ErrorMessage::ErrorMessage(const tinyxml2::XMLElement * const errmsg) std::istringstream(attr ? attr : "0") >> cwe.id; 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"); mShortMessage = attr ? attr : ""; @@ -257,7 +257,7 @@ Suppressions::ErrorMessage ErrorMessage::toSuppressionsErrorMessage() const ret.setFileName(callStack.back().getfile(false)); ret.lineNumber = callStack.back().line; } - ret.inconclusive = inconclusive; + ret.certainty = certainty; ret.symbolNames = mSymbolNames; return ret; } @@ -271,7 +271,7 @@ std::string ErrorMessage::serialize() const oss << Severity::toString(severity).length() << " " << Severity::toString(severity); oss << MathLib::toString(cwe.id).length() << " " << MathLib::toString(cwe.id); oss << MathLib::toString(hash).length() << " " << MathLib::toString(hash); - if (inconclusive) { + if (certainty == Certainty::inconclusive) { const std::string text("inconclusive"); oss << text.length() << " " << text; } @@ -294,7 +294,7 @@ std::string ErrorMessage::serialize() const bool ErrorMessage::deserialize(const std::string &data) { - inconclusive = false; + certainty = Certainty::normal; callStack.clear(); std::istringstream iss(data); std::array results; @@ -312,7 +312,7 @@ bool ErrorMessage::deserialize(const std::string &data) } if (temp == "inconclusive") { - inconclusive = true; + certainty = Certainty::inconclusive; continue; } @@ -436,7 +436,7 @@ std::string ErrorMessage::toXML() const printer.PushAttribute("cwe", cwe.id); if (hash) printer.PushAttribute("hash", MathLib::toString(hash).c_str()); - if (inconclusive) + if (certainty == Certainty::inconclusive) printer.PushAttribute("inconclusive", "true"); for (std::list::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) << ": "; if (severity != Severity::none) { text << '(' << Severity::toString(severity); - if (inconclusive) + if (certainty == Certainty::inconclusive) text << ", inconclusive"; 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 pos2 = result.find('}', 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, "{severity}", Severity::toString(severity)); @@ -614,7 +614,7 @@ bool ErrorLogger::reportUnmatchedSuppressions(const std::list callStack; if (!s.fileName.empty()) 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; } return err; diff --git a/lib/errorlogger.h b/lib/errorlogger.h index bc6bf6c33..a001347e1 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -70,11 +70,11 @@ public: : 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) { } - 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) { } @@ -127,27 +127,27 @@ public: const std::string& file1, Severity::SeverityType severity, const std::string &msg, - const std::string &id, bool inconclusive); + const std::string &id, Certainty::CertaintyLevel certainty); ErrorMessage(const std::list &callStack, const std::string& file1, Severity::SeverityType severity, const std::string &msg, const std::string &id, const CWE &cwe, - bool inconclusive); + Certainty::CertaintyLevel certainty); ErrorMessage(const std::list& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, - bool inconclusive); + Certainty::CertaintyLevel certainty); ErrorMessage(const std::list& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, const CWE &cwe, - bool inconclusive, + Certainty::CertaintyLevel certainty, bool bugHunting); ErrorMessage(const ErrorPath &errorPath, const TokenList *tokenList, @@ -155,7 +155,7 @@ public: const char id[], const std::string &msg, const CWE &cwe, - bool inconclusive, + Certainty::CertaintyLevel certainty, bool bugHunting); ErrorMessage(); explicit ErrorMessage(const tinyxml2::XMLElement * const errmsg); @@ -196,7 +196,7 @@ public: Severity::SeverityType severity; CWE cwe; - bool inconclusive; + Certainty::CertaintyLevel certainty; /** Warning hash */ std::size_t hash; diff --git a/lib/errortypes.h b/lib/errortypes.h index 80fcf1f50..7887c34c1 100644 --- a/lib/errortypes.h +++ b/lib/errortypes.h @@ -40,6 +40,20 @@ struct InternalError { 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. */ class CPPCHECKLIB Severity { public: diff --git a/lib/exprengine.cpp b/lib/exprengine.cpp index 8ddea84d0..78b1b436b 100644 --- a/lib/exprengine.cpp +++ b/lib/exprengine.cpp @@ -642,7 +642,7 @@ namespace { ErrorPath e = errorPath; 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.function = functionName.empty() ? currentFunction : functionName; errorLogger->reportErr(errmsg); diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 8e378f473..b3e5f3865 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -822,7 +822,7 @@ void Preprocessor::error(const std::string &filename, unsigned int linenr, const Severity::error, msg, "preprocessorErrorDirective", - false)); + Certainty::normal)); } // 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.", (headerType==SystemHeader) ? "missingIncludeSystem" : "missingInclude", - false); + Certainty::normal); mErrorLogger->reportInfo(errmsg); } } @@ -882,7 +882,7 @@ bool Preprocessor::validateCfg(const std::string &cfg, const std::list locationList; const ErrorMessage::FileLocation loc(file, line, 0); 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); } diff --git a/lib/settings.cpp b/lib/settings.cpp index c3a8b64ed..84c070313 100644 --- a/lib/settings.cpp +++ b/lib/settings.cpp @@ -29,8 +29,7 @@ const char Settings::SafeChecks::XmlInternalFunctions[] = "internal-functions"; const char Settings::SafeChecks::XmlExternalVariables[] = "external-variables"; Settings::Settings() - : mEnabled(0), - bugHunting(false), + : bugHunting(false), bugHuntingCheckFunctionMaxTime(60), checkAllConfigurations(true), checkConfiguration(false), @@ -50,9 +49,7 @@ Settings::Settings() enforcedLang(None), exceptionHandling(false), exitCode(0), - experimental(false), force(false), - inconclusive(false), inlineSuppressions(false), jobs(1), jointSuppressionReport(false), @@ -69,6 +66,8 @@ Settings::Settings() xml(false), xml_version(2) { + severity.setEnabled(Severity::error, true); + certainty.setEnabled(Certainty::normal, true); } std::string Settings::addEnabled(const std::string &str) @@ -92,25 +91,28 @@ std::string Settings::addEnabled(const std::string &str) } 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") { - mEnabled |= WARNING; + severity.enable(Severity::warning); } else if (str == "style") { - mEnabled |= STYLE; + severity.enable(Severity::style); } else if (str == "performance") { - mEnabled |= PERFORMANCE; + severity.enable(Severity::performance); } else if (str == "portability") { - mEnabled |= PORTABILITY; + severity.enable(Severity::portability); } else if (str == "information") { - mEnabled |= INFORMATION | MISSING_INCLUDE; + severity.enable(Severity::information); + checks.enable(Checks::missingInclude); } else if (str == "unusedFunction") { - mEnabled |= UNUSED_FUNCTION; + checks.enable(Checks::unusedFunction); } else if (str == "missingInclude") { - mEnabled |= MISSING_INCLUDE; + checks.enable(Checks::missingInclude); } #ifdef CHECK_INTERNAL else if (str == "internal") { - mEnabled |= INTERNAL; + checks.enable(Checks::internalCheck); } #endif else { @@ -123,35 +125,11 @@ std::string Settings::addEnabled(const std::string &str) 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 { - if (!isEnabled(Settings::WARNING) && (value->condition || value->defaultArg)) + if (!severity.isEnabled(Severity::warning) && (value->condition || value->defaultArg)) return false; - if (!inconclusive && (inconclusiveCheck || value->isInconclusive())) + if (!certainty.isEnabled(Certainty::inconclusive) && (inconclusiveCheck || value->isInconclusive())) return false; return true; } diff --git a/lib/settings.h b/lib/settings.h index 0300e589d..ba2173736 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -35,6 +35,7 @@ #include #include #include +#include namespace ValueFlow { class Value; @@ -43,27 +44,50 @@ namespace ValueFlow { /// @addtogroup Core /// @{ +template +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 * to pass individual values to functions or constructors now or in the * future when we might have even more detailed settings. */ 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: - /** @brief enable extra checks by id */ - int mEnabled; /** @brief terminate checking */ static std::atomic mTerminated; @@ -167,14 +191,6 @@ public: Default value is 0. */ 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 */ std::string fileFilter; @@ -193,9 +209,6 @@ public: for finding include files inside source files. (-I) */ std::list includePaths; - /** @brief Inconclusive checks */ - bool inconclusive; - /** @brief Is --inline-suppr given? */ bool inlineSuppressions; @@ -319,6 +332,10 @@ public: SafeChecks safeChecks; + SimpleEnableGroup severity; + SimpleEnableGroup certainty; + SimpleEnableGroup checks; + /** @brief show timing information (--showtime=file|summary|top5) */ SHOWTIME_MODES showtime; @@ -372,29 +389,6 @@ public: */ 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 * @return true if the value can be shown diff --git a/lib/suppressions.h b/lib/suppressions.h index 2f3b5681d..23236f996 100644 --- a/lib/suppressions.h +++ b/lib/suppressions.h @@ -21,6 +21,7 @@ //--------------------------------------------------------------------------- #include "config.h" +#include "errortypes.h" #include #include @@ -42,7 +43,7 @@ public: return mFileName; } int lineNumber; - bool inconclusive; + Certainty::CertaintyLevel certainty; std::string symbolNames; private: std::string mFileName; diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 2ca536c1a..96e63efc8 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1775,7 +1775,7 @@ void SymbolDatabase::validateExecutableScopes() const const ErrorMessage errmsg(callstack, &mTokenizer->list, Severity::debug, "symbolDatabaseWarning", msg, - false); + Certainty::normal); mErrorLogger->reportErr(errmsg); } } @@ -3091,7 +3091,7 @@ void SymbolDatabase::debugMessage(const Token *tok, const std::string &type, con Severity::debug, type, msg, - false); + Certainty::normal); if (mErrorLogger) mErrorLogger->reportErr(errmsg); } diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 070c45589..4d5f57b3f 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -1107,7 +1107,7 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration) Severity::debug, "noparamend", "TemplateSimplifier couldn't find end of template parameter.", - false); + Certainty::normal); } break; } @@ -2973,8 +2973,8 @@ bool TemplateSimplifier::simplifyTemplateInstantiations( "TemplateSimplifier: max template recursion (" + MathLib::toString(mSettings->maxTemplateRecursion) + ") reached for template '"+typeForNewName+"'. You might want to limit Cppcheck recursion.", - false); - if (mErrorLogger && mSettings->isEnabled(Settings::INFORMATION)) + Certainty::normal); + if (mErrorLogger && mSettings->severity.isEnabled(Severity::information)) mErrorLogger->reportErr(errmsg); // bail out.. @@ -3078,7 +3078,7 @@ bool TemplateSimplifier::simplifyTemplateInstantiations( if (printDebug && mErrorLogger) { std::list callstack(1, tok2); 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()) continue; @@ -3146,7 +3146,7 @@ bool TemplateSimplifier::simplifyTemplateInstantiations( if (printDebug && mErrorLogger) { std::list callstack(1, tok2); 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; } @@ -3778,7 +3778,7 @@ void TemplateSimplifier::simplifyTemplates( Severity::debug, "debug", "TemplateSimplifier: pass count limit hit before simplifications were finished.", - false); + Certainty::normal); if (mErrorLogger) mErrorLogger->reportErr(errmsg); } diff --git a/lib/token.cpp b/lib/token.cpp index b4f5fcf01..e769a4fb6 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -1810,9 +1810,9 @@ const ValueFlow::Value * Token::getValueLE(const MathLib::bigint val, const Sett } } if (settings && ret) { - if (ret->isInconclusive() && !settings->inconclusive) + if (ret->isInconclusive() && !settings->certainty.isEnabled(Certainty::inconclusive)) return nullptr; - if (ret->condition && !settings->isEnabled(Settings::WARNING)) + if (ret->condition && !settings->severity.isEnabled(Severity::warning)) return nullptr; } return ret; @@ -1835,9 +1835,9 @@ const ValueFlow::Value * Token::getValueGE(const MathLib::bigint val, const Sett } } if (settings && ret) { - if (ret->isInconclusive() && !settings->inconclusive) + if (ret->isInconclusive() && !settings->certainty.isEnabled(Certainty::inconclusive)) return nullptr; - if (ret->condition && !settings->isEnabled(Settings::WARNING)) + if (ret->condition && !settings->severity.isEnabled(Severity::warning)) return nullptr; } return ret; @@ -1861,9 +1861,9 @@ const ValueFlow::Value * Token::getInvalidValue(const Token *ftok, nonneg int ar } } if (ret) { - if (ret->isInconclusive() && !settings->inconclusive) + if (ret->isInconclusive() && !settings->certainty.isEnabled(Certainty::inconclusive)) return nullptr; - if (ret->condition && !settings->isEnabled(Settings::WARNING)) + if (ret->condition && !settings->severity.isEnabled(Severity::warning)) return nullptr; } return ret; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index aca0a925e..a09a19e8c 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2598,7 +2598,7 @@ bool Tokenizer::simplifyUsing() str += " ;"; std::list callstack(1, usingStart); 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; @@ -4975,7 +4975,7 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) } // 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()) { if (Token::Match(tok, "class %type% %type% [:{]")) { unhandled_macro_class_x_y(tok); @@ -9103,7 +9103,7 @@ bool Tokenizer::isScopeNoReturn(const Token *endScopeToken, bool *unknown) const } if (unknown) *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? bool globalFunction = true; 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& 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) mErrorLogger->reportErr(errmsg); else diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index ecd1d6d6b..7c4d60ca6 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -118,7 +118,7 @@ static void bailoutInternal(const std::string& type, TokenList *tokenlist, Error function = "(valueFlow)"; std::list callstack(1, ErrorMessage::FileLocation(tok, tokenlist)); 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); } @@ -3108,7 +3108,7 @@ struct LifetimeStore { return false; bool update = false; for (const LifetimeToken& lt : getLifetimeTokens(argtok)) { - if (!settings->inconclusive && lt.inconclusive) + if (!settings->certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive) continue; ErrorPath er = errorPath; er.insert(er.end(), lt.errorPath.begin(), lt.errorPath.end()); @@ -3171,7 +3171,7 @@ struct LifetimeStore { continue; const Token *tok3 = v.tokvalue; for (const LifetimeToken& lt : getLifetimeTokens(tok3)) { - if (!settings->inconclusive && lt.inconclusive) + if (!settings->certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive) continue; ErrorPath er = v.errorPath; er.insert(er.end(), lt.errorPath.begin(), lt.errorPath.end()); @@ -3210,7 +3210,7 @@ struct LifetimeStore { template 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; if (!argtok) return; @@ -3573,7 +3573,7 @@ static void valueFlowLifetime(TokenList *tokenlist, SymbolDatabase*, ErrorLogger // address of else if (tok->isUnaryOp("&")) { for (const LifetimeToken& lt : getLifetimeTokens(tok->astOperand1())) { - if (!settings->inconclusive && lt.inconclusive) + if (!settings->certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive) continue; ErrorPath errorPath = lt.errorPath; errorPath.emplace_back(tok, "Address of variable taken here."); diff --git a/test/test64bit.cpp b/test/test64bit.cpp index 8b66d36d7..23fbc4866 100644 --- a/test/test64bit.cpp +++ b/test/test64bit.cpp @@ -32,7 +32,7 @@ private: Settings settings; void run() OVERRIDE { - settings.addEnabled("portability"); + settings.severity.enable(Severity::portability); TEST_CASE(novardecl); TEST_CASE(functionpar); diff --git a/test/testassert.cpp b/test/testassert.cpp index 9cef5f3d6..93517303b 100644 --- a/test/testassert.cpp +++ b/test/testassert.cpp @@ -45,7 +45,7 @@ private: } void run() OVERRIDE { - settings.addEnabled("warning"); + settings.severity.enable(Severity::warning); TEST_CASE(assignmentInAssert); TEST_CASE(functionCallInAssert); diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index a67dbb8c0..2b9a0dd48 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -35,7 +35,7 @@ private: // Clear the error buffer.. errout.str(""); - settings.inconclusive = inconclusive; + settings.certainty.setEnabled(Certainty::inconclusive, inconclusive); // Tokenize.. Tokenizer tokenizer(&settings, this); @@ -47,8 +47,8 @@ private: } void run() OVERRIDE { - settings.addEnabled("warning"); - settings.addEnabled("style"); + settings.severity.enable(Severity::warning); + settings.severity.enable(Severity::style); LOAD_LIB_2(settings.library, "std.cfg"); LOAD_LIB_2(settings.library, "qt.cfg"); diff --git a/test/testbool.cpp b/test/testbool.cpp index f9dde9cfc..8a8445b30 100644 --- a/test/testbool.cpp +++ b/test/testbool.cpp @@ -32,9 +32,9 @@ private: Settings settings; void run() OVERRIDE { - settings.addEnabled("style"); - settings.addEnabled("warning"); - settings.inconclusive = true; + settings.severity.enable(Severity::style); + settings.severity.enable(Severity::warning); + settings.certainty.enable(Certainty::inconclusive); TEST_CASE(bitwiseOnBoolean); // if (bool & bool) TEST_CASE(incrementBoolean); @@ -80,7 +80,7 @@ private: // Clear the error buffer.. errout.str(""); - settings.experimental = experimental; + settings.certainty.setEnabled(Certainty::experimental, experimental); // Tokenize.. Tokenizer tokenizer(&settings, this); diff --git a/test/testboost.cpp b/test/testboost.cpp index fae9dd5d5..c96477c0f 100644 --- a/test/testboost.cpp +++ b/test/testboost.cpp @@ -32,8 +32,8 @@ private: Settings settings; void run() OVERRIDE { - settings.addEnabled("style"); - settings.addEnabled("performance"); + settings.severity.enable(Severity::style); + settings.severity.enable(Severity::performance); TEST_CASE(BoostForeachContainerModification); } diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 985252f27..4f7cb2119 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -45,8 +45,8 @@ private: // Clear the error buffer.. errout.str(""); - settings0.inconclusive = true; - settings0.experimental = experimental; + settings0.certainty.enable(Certainty::inconclusive); + settings0.certainty.setEnabled(Certainty::experimental, experimental); // Tokenize.. Tokenizer tokenizer(&settings0, this); @@ -74,9 +74,9 @@ private: void run() OVERRIDE { LOAD_LIB_2(settings0.library, "std.cfg"); - settings0.addEnabled("warning"); - settings0.addEnabled("style"); - settings0.addEnabled("portability"); + settings0.severity.enable(Severity::warning); + settings0.severity.enable(Severity::style); + settings0.severity.enable(Severity::portability); TEST_CASE(noerr1); TEST_CASE(noerr2); @@ -3324,7 +3324,7 @@ private: tinyxml2::XMLDocument doc; doc.Parse(xmldata, sizeof(xmldata)); settings.library.load(doc); - settings.addEnabled("warning"); + settings.severity.enable(Severity::warning); settings.sizeof_wchar_t = 4; check("void f() {\n" diff --git a/test/testcharvar.cpp b/test/testcharvar.cpp index a414a1c15..8fe030766 100644 --- a/test/testcharvar.cpp +++ b/test/testcharvar.cpp @@ -34,8 +34,8 @@ private: void run() OVERRIDE { settings.platform(Settings::Unspecified); - settings.addEnabled("warning"); - settings.addEnabled("portability"); + settings.severity.enable(Severity::warning); + settings.severity.enable(Severity::portability); TEST_CASE(array_index_1); TEST_CASE(array_index_2); diff --git a/test/testclass.cpp b/test/testclass.cpp index e6a36b35d..f46fb1762 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -36,8 +36,8 @@ private: Settings settings1; void run() OVERRIDE { - settings0.addEnabled("style"); - settings1.addEnabled("warning"); + settings0.severity.enable(Severity::style); + settings1.severity.enable(Severity::warning); // Load std.cfg configuration { @@ -231,7 +231,7 @@ private: // Clear the error log errout.str(""); Settings settings; - settings.addEnabled("warning"); + settings.severity.enable(Severity::warning); // Tokenize.. Tokenizer tokenizer(&settings, this); @@ -2427,8 +2427,8 @@ private: // Clear the error log errout.str(""); - settings0.inconclusive = inconclusive; - settings0.addEnabled("warning"); + settings0.certainty.setEnabled(Certainty::inconclusive, inconclusive); + settings0.severity.enable(Severity::warning); // Tokenize.. Tokenizer tokenizer(&settings0, this); @@ -2719,8 +2719,8 @@ private: void checkNoMemset(const char code[]) { Settings settings; - settings.addEnabled("warning"); - settings.addEnabled("portability"); + settings.severity.enable(Severity::warning); + settings.severity.enable(Severity::portability); checkNoMemset(code,settings); } @@ -3353,7 +3353,7 @@ private: // Check.. if (!s) s = &settings0; - s->inconclusive = inconclusive; + s->certainty.setEnabled(Certainty::inconclusive, inconclusive); // Tokenize.. Tokenizer tokenizer(s, this); @@ -6539,7 +6539,7 @@ private: errout.str(""); // Check.. - settings0.inconclusive = true; + settings0.certainty.setEnabled(Certainty::inconclusive, true); // Tokenize.. Tokenizer tokenizer(&settings0, this); @@ -6574,7 +6574,7 @@ private: // Check.. Settings settings; - settings.addEnabled("performance"); + settings.severity.enable(Severity::performance); // Tokenize.. Tokenizer tokenizer(&settings, this); @@ -6884,9 +6884,9 @@ private: if (!s) { static Settings settings_; s = &settings_; - s->addEnabled("warning"); + s->severity.enable(Severity::warning); } - s->inconclusive = inconclusive; + s->certainty.setEnabled(Certainty::inconclusive, inconclusive); // Tokenize.. Tokenizer tokenizer(s, this); @@ -7137,7 +7137,7 @@ private: // Clear the error log errout.str(""); Settings settings; - settings.addEnabled("style"); + settings.severity.enable(Severity::style); // Tokenize.. Tokenizer tokenizer(&settings, this); @@ -7220,7 +7220,7 @@ private: errout.str(""); Settings settings; settings.safeChecks.classes = true; - settings.addEnabled("warning"); + settings.severity.enable(Severity::warning); // Tokenize.. Tokenizer tokenizer(&settings, this); diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index c2c39f347..381c088c0 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -470,11 +470,11 @@ private: const char * const argv[] = {"cppcheck", "--enable=all", "file.cpp"}; settings = Settings(); ASSERT(defParser.parseFromArgs(3, argv)); - ASSERT(settings.isEnabled(Settings::STYLE)); - ASSERT(settings.isEnabled(Settings::WARNING)); - ASSERT(settings.isEnabled(Settings::UNUSED_FUNCTION)); - ASSERT(settings.isEnabled(Settings::MISSING_INCLUDE)); - ASSERT(!settings.isEnabled(Settings::INTERNAL)); + ASSERT(settings.severity.isEnabled(Severity::style)); + ASSERT(settings.severity.isEnabled(Severity::warning)); + ASSERT(settings.checks.isEnabled(Checks::unusedFunction)); + ASSERT(settings.checks.isEnabled(Checks::missingInclude)); + ASSERT(!settings.checks.isEnabled(Checks::internalCheck)); } void enabledStyle() { @@ -482,12 +482,12 @@ private: const char * const argv[] = {"cppcheck", "--enable=style", "file.cpp"}; settings = Settings(); ASSERT(defParser.parseFromArgs(3, argv)); - ASSERT(settings.isEnabled(Settings::STYLE)); - ASSERT(settings.isEnabled(Settings::WARNING)); - ASSERT(settings.isEnabled(Settings::PERFORMANCE)); - ASSERT(settings.isEnabled(Settings::PORTABILITY)); - ASSERT(!settings.isEnabled(Settings::UNUSED_FUNCTION)); - ASSERT(!settings.isEnabled(Settings::MISSING_INCLUDE)); + ASSERT(settings.severity.isEnabled(Severity::style)); + ASSERT(settings.severity.isEnabled(Severity::warning)); + ASSERT(settings.severity.isEnabled(Severity::performance)); + ASSERT(settings.severity.isEnabled(Severity::portability)); + ASSERT(!settings.checks.isEnabled(Checks::unusedFunction)); + ASSERT(!settings.checks.isEnabled(Checks::internalCheck)); } void enabledPerformance() { @@ -495,12 +495,12 @@ private: const char * const argv[] = {"cppcheck", "--enable=performance", "file.cpp"}; settings = Settings(); ASSERT(defParser.parseFromArgs(3, argv)); - ASSERT(!settings.isEnabled(Settings::STYLE)); - ASSERT(!settings.isEnabled(Settings::WARNING)); - ASSERT(settings.isEnabled(Settings::PERFORMANCE)); - ASSERT(!settings.isEnabled(Settings::PORTABILITY)); - ASSERT(!settings.isEnabled(Settings::UNUSED_FUNCTION)); - ASSERT(!settings.isEnabled(Settings::MISSING_INCLUDE)); + ASSERT(!settings.severity.isEnabled(Severity::style)); + ASSERT(!settings.severity.isEnabled(Severity::warning)); + ASSERT(settings.severity.isEnabled(Severity::performance)); + ASSERT(!settings.severity.isEnabled(Severity::portability)); + ASSERT(!settings.checks.isEnabled(Checks::unusedFunction)); + ASSERT(!settings.checks.isEnabled(Checks::missingInclude)); } void enabledPortability() { @@ -508,12 +508,12 @@ private: const char * const argv[] = {"cppcheck", "--enable=portability", "file.cpp"}; settings = Settings(); ASSERT(defParser.parseFromArgs(3, argv)); - ASSERT(!settings.isEnabled(Settings::STYLE)); - ASSERT(!settings.isEnabled(Settings::WARNING)); - ASSERT(!settings.isEnabled(Settings::PERFORMANCE)); - ASSERT(settings.isEnabled(Settings::PORTABILITY)); - ASSERT(!settings.isEnabled(Settings::UNUSED_FUNCTION)); - ASSERT(!settings.isEnabled(Settings::MISSING_INCLUDE)); + ASSERT(!settings.severity.isEnabled(Severity::style)); + ASSERT(!settings.severity.isEnabled(Severity::warning)); + ASSERT(!settings.severity.isEnabled(Severity::performance)); + ASSERT(settings.severity.isEnabled(Severity::portability)); + ASSERT(!settings.checks.isEnabled(Checks::unusedFunction)); + ASSERT(!settings.checks.isEnabled(Checks::missingInclude)); } void enabledUnusedFunction() { @@ -521,7 +521,7 @@ private: const char * const argv[] = {"cppcheck", "--enable=unusedFunction", "file.cpp"}; settings = Settings(); ASSERT(defParser.parseFromArgs(3, argv)); - ASSERT(settings.isEnabled(Settings::UNUSED_FUNCTION)); + ASSERT(settings.checks.isEnabled(Checks::unusedFunction)); } void enabledMissingInclude() { @@ -529,7 +529,7 @@ private: const char * const argv[] = {"cppcheck", "--enable=missingInclude", "file.cpp"}; settings = Settings(); ASSERT(defParser.parseFromArgs(3, argv)); - ASSERT(settings.isEnabled(Settings::MISSING_INCLUDE)); + ASSERT(settings.checks.isEnabled(Checks::missingInclude)); } #ifdef CHECK_INTERNAL @@ -547,20 +547,20 @@ private: const char * const argv[] = {"cppcheck", "--enable=missingInclude,portability,warning", "file.cpp"}; settings = Settings(); ASSERT(defParser.parseFromArgs(3, argv)); - ASSERT(!settings.isEnabled(Settings::STYLE)); - ASSERT(settings.isEnabled(Settings::WARNING)); - ASSERT(!settings.isEnabled(Settings::PERFORMANCE)); - ASSERT(settings.isEnabled(Settings::PORTABILITY)); - ASSERT(!settings.isEnabled(Settings::UNUSED_FUNCTION)); - ASSERT(settings.isEnabled(Settings::MISSING_INCLUDE)); + ASSERT(!settings.severity.isEnabled(Severity::style)); + ASSERT(settings.severity.isEnabled(Severity::warning)); + ASSERT(!settings.severity.isEnabled(Severity::performance)); + ASSERT(settings.severity.isEnabled(Severity::portability)); + ASSERT(!settings.checks.isEnabled(Checks::unusedFunction)); + ASSERT(settings.checks.isEnabled(Checks::missingInclude)); } void inconclusive() { REDIRECT; const char * const argv[] = {"cppcheck", "--inconclusive"}; - settings.inconclusive = false; + settings.certainty.clear(); ASSERT(defParser.parseFromArgs(2, argv)); - ASSERT_EQUALS(true, settings.inconclusive); + ASSERT_EQUALS(true, settings.certainty.isEnabled(Certainty::inconclusive)); } void errorExitcode() { diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 497cd1a57..e770c9699 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -41,8 +41,8 @@ private: LOAD_LIB_2(settings0.library, "qt.cfg"); LOAD_LIB_2(settings0.library, "std.cfg"); - settings0.addEnabled("style"); - settings0.addEnabled("warning"); + settings0.severity.enable(Severity::style); + settings0.severity.enable(Severity::warning); const char cfg[] = "\n" "\n" @@ -50,8 +50,8 @@ private: ""; tinyxml2::XMLDocument xmldoc; xmldoc.Parse(cfg, sizeof(cfg)); - settings1.addEnabled("style"); - settings1.addEnabled("warning"); + settings1.severity.enable(Severity::style); + settings1.severity.enable(Severity::warning); settings1.library.load(xmldoc); TEST_CASE(assignAndCompare); // assignment and comparison don't match @@ -126,7 +126,7 @@ private: // Clear the error buffer.. errout.str(""); - settings0.inconclusive = inconclusive; + settings0.certainty.setEnabled(Certainty::inconclusive, inconclusive); // Raw tokens.. std::vector files(1, filename); diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index df1e23ed3..8d97db740 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -35,7 +35,7 @@ private: // Clear the error buffer.. errout.str(""); - settings.inconclusive = inconclusive; + settings.certainty.setEnabled(Certainty::inconclusive, inconclusive); // Tokenize.. Tokenizer tokenizer(&settings, this); @@ -48,8 +48,8 @@ private: } void run() OVERRIDE { - settings.addEnabled("style"); - settings.addEnabled("warning"); + settings.severity.enable(Severity::style); + settings.severity.enable(Severity::warning); TEST_CASE(simple1); TEST_CASE(simple2); diff --git a/test/testerrorlogger.cpp b/test/testerrorlogger.cpp index f827f8723..d9153867a 100644 --- a/test/testerrorlogger.cpp +++ b/test/testerrorlogger.cpp @@ -112,7 +112,7 @@ private: void ErrorMessageConstruct() const { std::list 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("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Programming error.", msg.verboseMessage()); @@ -122,7 +122,7 @@ private: void ErrorMessageConstructLocations() const { std::list 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("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Programming error.", msg.verboseMessage()); @@ -132,7 +132,7 @@ private: void ErrorMessageVerbose() const { std::list 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("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Verbose error", msg.verboseMessage()); @@ -142,7 +142,7 @@ private: void ErrorMessageVerboseLocations() const { std::list 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("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Verbose error", msg.verboseMessage()); @@ -152,7 +152,7 @@ private: void CustomFormat() const { std::list 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("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Verbose error", msg.verboseMessage()); @@ -162,7 +162,7 @@ private: void CustomFormat2() const { std::list 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("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Verbose error", msg.verboseMessage()); @@ -173,7 +173,7 @@ private: void CustomFormatLocations() const { // Check that first location from location stack is used in template std::list 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("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Verbose error", msg.verboseMessage()); @@ -183,7 +183,7 @@ private: void ToXmlV2() const { std::list 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("\n\n"); header += " locs = { fooCpp5, barCpp8 }; 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("\n\n"); header += " 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(" "); ASSERT_EQUALS(expected, msg.toXML()); } @@ -224,9 +224,9 @@ private: const char code1[]="äöü"; const char code2[]="\x12\x00\x00\x01"; std::list 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(" ", 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(" ", msg2.toXML()); } } @@ -236,7 +236,7 @@ private: std::list locs(1, fooCpp5); // 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 ASSERT_EQUALS(" \n" @@ -248,7 +248,7 @@ private: void SerializeInconclusiveMessage() const { // Inconclusive error message std::list 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" "5 error" "1 0" @@ -262,7 +262,7 @@ private: msg2.deserialize(msg.serialize()); ASSERT_EQUALS("errorId", msg2.id); 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.verboseMessage()); } @@ -274,7 +274,7 @@ private: void SerializeSanitize() const { std::list 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" "5 error" @@ -299,7 +299,7 @@ private: std::list 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; msg2.deserialize(msg.serialize()); diff --git a/test/testexceptionsafety.cpp b/test/testexceptionsafety.cpp index 60c30eaa4..7b43eed9b 100644 --- a/test/testexceptionsafety.cpp +++ b/test/testexceptionsafety.cpp @@ -32,7 +32,7 @@ private: Settings settings; void run() OVERRIDE { - settings.addEnabled("all"); + settings.severity.fill(); TEST_CASE(destructors); TEST_CASE(deallocThrow1); @@ -57,7 +57,7 @@ private: // Clear the error buffer.. errout.str(""); - settings.inconclusive = inconclusive; + settings.certainty.setEnabled(Certainty::inconclusive, inconclusive); // Tokenize.. Tokenizer tokenizer(&settings, this); diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp index a4d9a39b4..e98ff4208 100644 --- a/test/testfunctions.cpp +++ b/test/testfunctions.cpp @@ -35,9 +35,9 @@ private: Settings settings; void run() OVERRIDE { - settings.addEnabled("style"); - settings.addEnabled("warning"); - settings.addEnabled("portability"); + settings.severity.enable(Severity::style); + settings.severity.enable(Severity::warning); + settings.severity.enable(Severity::portability); settings.libraries.emplace_back("posix"); settings.standards.c = Standards::C11; settings.standards.cpp = Standards::CPP11; @@ -1092,7 +1092,7 @@ private: void checkIgnoredReturnValue() { Settings settings2; - settings2.addEnabled("warning"); + settings2.severity.enable(Severity::warning); const char xmldata[] = "\n" "\n" " \n" diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 96b6abb0a..4b3474fdc 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -35,13 +35,8 @@ private: void run() OVERRIDE { settings.debugwarnings = true; - settings.addEnabled("style"); - settings.addEnabled("warning"); - settings.addEnabled("portability"); - settings.addEnabled("performance"); - settings.addEnabled("information"); - settings.inconclusive = true; - settings.experimental = true; + settings.severity.fill(); + settings.certainty.fill(); // don't freak out when the syntax is wrong diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index d29da328c..dca355607 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -37,7 +37,7 @@ private: // Clear the error buffer.. errout.str(""); - settings.inconclusive = inconclusive; + settings.certainty.setEnabled(Certainty::inconclusive, inconclusive); // Raw tokens.. std::vector files(1, "test.cpp"); @@ -60,7 +60,7 @@ private: } void run() OVERRIDE { - settings.addEnabled("warning"); + settings.severity.enable(Severity::warning); TEST_CASE(test1); TEST_CASE(test2); diff --git a/test/testio.cpp b/test/testio.cpp index fffe4140b..6fb33a77f 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -80,12 +80,12 @@ private: // Clear the error buffer.. errout.str(""); - settings.clearEnabled(); - settings.addEnabled("warning"); - settings.addEnabled("style"); + settings.severity.clear(); + settings.severity.enable(Severity::warning); + settings.severity.enable(Severity::style); if (portability) - settings.addEnabled("portability"); - settings.inconclusive = inconclusive; + settings.severity.enable(Severity::portability); + settings.certainty.setEnabled(Certainty::inconclusive, inconclusive); settings.platform(platform); // Tokenize.. diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 5d5a51cb9..231019268 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -208,7 +208,7 @@ private: // Check for leaks.. CheckLeakAutoVar c; settings.checkLibrary = true; - settings.addEnabled("information"); + settings.severity.enable(Severity::information); c.runChecks(&tokenizer, &settings, this); } @@ -224,7 +224,7 @@ private: // Check for leaks.. CheckLeakAutoVar c; settings.checkLibrary = true; - settings.addEnabled("information"); + settings.severity.enable(Severity::information); c.runChecks(&tokenizer, &settings, this); } @@ -2245,7 +2245,7 @@ private: // Check for leaks.. CheckLeakAutoVar checkLeak; settings.checkLibrary = true; - settings.addEnabled("information"); + settings.severity.enable(Severity::information); checkLeak.runChecks(&tokenizer, &settings, this); } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 8eaf1681a..465250226 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -486,8 +486,8 @@ private: } void run() OVERRIDE { - settings.addEnabled("warning"); - settings.addEnabled("style"); + settings.severity.enable(Severity::warning); + settings.severity.enable(Severity::style); LOAD_LIB_2(settings.library, "std.cfg"); @@ -2141,9 +2141,9 @@ private: } void run() OVERRIDE { - settings.inconclusive = true; + settings.certainty.setEnabled(Certainty::inconclusive, true); 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, "posix.cfg"); diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 51a1f0a54..68af03ba3 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -42,7 +42,7 @@ private: void run() OVERRIDE { LOAD_LIB_2(settings.library, "std.cfg"); - settings.addEnabled("warning"); + settings.severity.enable(Severity::warning); TEST_CASE(nullpointerAfterLoop); TEST_CASE(nullpointer1); @@ -149,7 +149,7 @@ private: // Clear the error buffer.. errout.str(""); - settings.inconclusive = inconclusive; + settings.certainty.setEnabled(Certainty::inconclusive, inconclusive); // Tokenize.. Tokenizer tokenizer(&settings, this); @@ -166,7 +166,7 @@ private: // Clear the error buffer.. errout.str(""); - settings.inconclusive = false; + settings.certainty.setEnabled(Certainty::inconclusive, false); // Raw tokens.. std::vector files(1, "test.cpp"); diff --git a/test/testother.cpp b/test/testother.cpp index fcbebbb95..b7722a05a 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -260,14 +260,14 @@ private: if (!settings) { settings = &_settings; } - settings->addEnabled("style"); - settings->addEnabled("warning"); - settings->addEnabled("portability"); - settings->addEnabled("performance"); + settings->severity.enable(Severity::style); + settings->severity.enable(Severity::warning); + settings->severity.enable(Severity::portability); + settings->severity.enable(Severity::performance); settings->standards.c = Standards::CLatest; settings->standards.cpp = Standards::CPPLatest; - settings->inconclusive = inconclusive; - settings->experimental = experimental; + settings->certainty.setEnabled(Certainty::inconclusive, inconclusive); + settings->certainty.setEnabled(Certainty::experimental, experimental); settings->verbose = verbose; // Tokenize.. @@ -291,14 +291,14 @@ private: errout.str(""); Settings* settings = &_settings; - settings->addEnabled("style"); - settings->addEnabled("warning"); - settings->addEnabled("portability"); - settings->addEnabled("performance"); + settings->severity.enable(Severity::style); + settings->severity.enable(Severity::warning); + settings->severity.enable(Severity::portability); + settings->severity.enable(Severity::performance); settings->standards.c = Standards::CLatest; settings->standards.cpp = Standards::CPPLatest; - settings->inconclusive = true; - settings->experimental = false; + settings->certainty.enable(Certainty::inconclusive); + settings->certainty.disable(Certainty::experimental); // Raw tokens.. std::vector files(1, filename); @@ -326,7 +326,7 @@ private: void checkposix(const char code[]) { static Settings settings; - settings.addEnabled("warning"); + settings.severity.enable(Severity::warning); settings.libraries.emplace_back("posix"); check(code, @@ -1298,7 +1298,7 @@ private: errout.str(""); static Settings settings; - settings.addEnabled("style"); + settings.severity.enable(Severity::style); settings.standards.cpp = Standards::CPP03; // #5560 // Tokenize.. @@ -1439,10 +1439,10 @@ private: errout.str(""); Settings settings; - settings.addEnabled("warning"); + settings.severity.enable(Severity::warning); if (portability) - settings.addEnabled("portability"); - settings.inconclusive = inconclusive; + settings.severity.enable(Severity::portability); + settings.certainty.setEnabled(Certainty::inconclusive, inconclusive); settings.defaultSign = 's'; // Tokenize.. diff --git a/test/testpostfixoperator.cpp b/test/testpostfixoperator.cpp index 6e24d21ba..368454ee2 100644 --- a/test/testpostfixoperator.cpp +++ b/test/testpostfixoperator.cpp @@ -47,7 +47,7 @@ private: } void run() OVERRIDE { - settings.addEnabled("performance"); + settings.severity.enable(Severity::performance); TEST_CASE(testsimple); TEST_CASE(testfor); diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 0726ba609..a90f85a3b 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -40,7 +40,7 @@ public: TestPreprocessor() : TestFixture("TestPreprocessor") , preprocessor0(settings0, this) { - settings0.addEnabled("information"); + settings0.severity.enable(Severity::information); } class OurPreprocessor : public Preprocessor { @@ -1929,7 +1929,7 @@ private: Preprocessor::missingIncludeFlag = false; Settings settings; settings.inlineSuppressions = true; - settings.addEnabled("all"); + settings.severity.fill(); Preprocessor preprocessor(settings, this); std::istringstream src("// cppcheck-suppress missingInclude\n" diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index df5b55ab4..5fd7deaba 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -39,7 +39,7 @@ private: Settings settings; void run() OVERRIDE { - settings.addEnabled("portability"); + settings.severity.enable(Severity::portability); // If there are unused templates, keep those settings.checkUnusedTemplates = true; diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index df65c9f1b..edf98b698 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -42,9 +42,9 @@ private: void run() OVERRIDE { LOAD_LIB_2(settings_std.library, "std.cfg"); LOAD_LIB_2(settings_windows.library, "windows.cfg"); - settings0.addEnabled("portability"); - settings1.addEnabled("style"); - settings_windows.addEnabled("portability"); + settings0.severity.enable(Severity::portability); + settings1.severity.enable(Severity::style); + settings_windows.severity.enable(Severity::portability); // If there are unused templates, keep those settings0.checkUnusedTemplates = true; diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 8dff6116d..ddc10ceb9 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -39,8 +39,8 @@ private: Settings settings2; void run() OVERRIDE { - settings0.addEnabled("style"); - settings2.addEnabled("style"); + settings0.severity.enable(Severity::style); + settings2.severity.enable(Severity::style); // If there are unused templates, keep those 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) { errout.str(""); - settings0.inconclusive = true; + settings0.certainty.enable(Certainty::inconclusive); settings0.debugwarnings = debugwarnings; // show warnings about unhandled typedef settings0.platform(type); Tokenizer tokenizer(&settings0, this); @@ -223,7 +223,7 @@ private: void checkSimplifyTypedef(const char code[]) { errout.str(""); // Tokenize.. - settings2.inconclusive = true; + settings2.certainty.enable(Certainty::inconclusive); settings2.debugwarnings = true; // show warnings about unhandled typedef Tokenizer tokenizer(&settings2, this); std::istringstream istr(code); diff --git a/test/testsimplifyusing.cpp b/test/testsimplifyusing.cpp index f68fe902b..55d938f18 100644 --- a/test/testsimplifyusing.cpp +++ b/test/testsimplifyusing.cpp @@ -39,8 +39,8 @@ private: Settings settings2; void run() OVERRIDE { - settings0.addEnabled("style"); - settings2.addEnabled("style"); + settings0.severity.enable(Severity::style); + settings2.severity.enable(Severity::style); // If there are unused templates, keep those 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) { errout.str(""); - settings0.inconclusive = true; + settings0.certainty.enable(Certainty::inconclusive); settings0.debugwarnings = debugwarnings; settings0.platform(type); Tokenizer tokenizer(&settings0, this); diff --git a/test/testsizeof.cpp b/test/testsizeof.cpp index 17a31786f..95c39b562 100644 --- a/test/testsizeof.cpp +++ b/test/testsizeof.cpp @@ -34,9 +34,9 @@ private: Settings settings; void run() OVERRIDE { - settings.addEnabled("warning"); - settings.addEnabled("portability"); - settings.inconclusive = true; + settings.severity.enable(Severity::warning); + settings.severity.enable(Severity::portability); + settings.certainty.enable(Certainty::inconclusive); TEST_CASE(sizeofsizeof); TEST_CASE(sizeofCalculation); diff --git a/test/teststl.cpp b/test/teststl.cpp index 87ea9d7b9..07b8ec612 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -35,9 +35,9 @@ private: Settings settings; void run() OVERRIDE { - settings.addEnabled("warning"); - settings.addEnabled("style"); - settings.addEnabled("performance"); + settings.severity.enable(Severity::warning); + settings.severity.enable(Severity::style); + settings.severity.enable(Severity::performance); LOAD_LIB_2(settings.library, "std.cfg"); TEST_CASE(outOfBounds); @@ -175,7 +175,7 @@ private: // Clear the error buffer.. errout.str(""); - settings.inconclusive = inconclusive; + settings.certainty.setEnabled(Certainty::inconclusive, inconclusive); settings.standards.cpp = cppstandard; diff --git a/test/teststring.cpp b/test/teststring.cpp index f4bef1bcf..8cdc12a71 100644 --- a/test/teststring.cpp +++ b/test/teststring.cpp @@ -32,8 +32,8 @@ private: Settings settings; void run() OVERRIDE { - settings.addEnabled("warning"); - settings.addEnabled("style"); + settings.severity.enable(Severity::warning); + settings.severity.enable(Severity::style); TEST_CASE(stringLiteralWrite); diff --git a/test/testsuppressions.cpp b/test/testsuppressions.cpp index 73eb80d39..dabd8bc1f 100644 --- a/test/testsuppressions.cpp +++ b/test/testsuppressions.cpp @@ -184,8 +184,8 @@ private: settings.exitCode = 1; settings.inlineSuppressions = true; if (suppression == "unusedFunction") - settings.addEnabled("unusedFunction"); - settings.addEnabled("information"); + settings.checks.setEnabled(Checks::unusedFunction, true); + settings.severity.enable(Severity::information); settings.jointSuppressionReport = true; if (!suppression.empty()) { std::string r = settings.nomsg.addSuppressionLine(suppression); @@ -214,7 +214,7 @@ private: Settings settings; settings.jobs = 1; settings.inlineSuppressions = true; - settings.addEnabled("information"); + settings.severity.enable(Severity::information); if (!suppression.empty()) { EXPECT_EQ("", settings.nomsg.addSuppressionLine(suppression)); } @@ -680,7 +680,7 @@ private: CppCheck cppCheck(*this, true, nullptr); Settings& settings = cppCheck.settings(); - settings.addEnabled("style"); + settings.severity.enable(Severity::style); settings.inlineSuppressions = true; settings.relativePaths = true; settings.basePaths.emplace_back("/somewhere"); diff --git a/test/testtype.cpp b/test/testtype.cpp index c31bb2451..06c25a008 100644 --- a/test/testtype.cpp +++ b/test/testtype.cpp @@ -49,8 +49,8 @@ private: static Settings _settings; settings = &_settings; } - settings->addEnabled("warning"); - settings->addEnabled("portability"); + settings->severity.enable(Severity::warning); + settings->severity.enable(Severity::portability); settings->standards.setCPP(standard); // Tokenize.. @@ -209,7 +209,7 @@ private: void checkIntegerOverflow() { Settings settings; settings.platform(Settings::Unix32); - settings.addEnabled("warning"); + settings.severity.enable(Severity::warning); 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()); @@ -298,7 +298,7 @@ private: void longCastAssign() { Settings settings; - settings.addEnabled("style"); + settings.severity.enable(Severity::style); settings.platform(Settings::Unix64); check("long f(int x, int y) {\n" @@ -330,7 +330,7 @@ private: void longCastReturn() { Settings settings; - settings.addEnabled("style"); + settings.severity.enable(Severity::style); check("long f(int x, int y) {\n" " return x * y;\n" diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 889a118a4..b462fc5a5 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -108,7 +108,7 @@ private: checkuninitvar.check(); settings.debugwarnings = false; - settings.experimental = true; + settings.certainty.enable(Certainty::experimental); } void uninitvar1() { @@ -4069,7 +4069,7 @@ private: // Tokenize.. settings.debugwarnings = false; - settings.experimental = false; + settings.certainty.disable(Certainty::experimental); Tokenizer tokenizer(&settings, this); std::istringstream istr(code); diff --git a/test/testunusedfunctions.cpp b/test/testunusedfunctions.cpp index 416c98449..27e3bf32f 100644 --- a/test/testunusedfunctions.cpp +++ b/test/testunusedfunctions.cpp @@ -34,7 +34,7 @@ private: Settings settings; void run() OVERRIDE { - settings.addEnabled("style"); + settings.severity.enable(Severity::style); TEST_CASE(incondition); TEST_CASE(return1); diff --git a/test/testunusedprivfunc.cpp b/test/testunusedprivfunc.cpp index d4add33a3..c605a5059 100644 --- a/test/testunusedprivfunc.cpp +++ b/test/testunusedprivfunc.cpp @@ -35,7 +35,7 @@ private: Settings settings; void run() OVERRIDE { - settings.addEnabled("style"); + settings.severity.enable(Severity::style); TEST_CASE(test1); TEST_CASE(test2); diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 81630bffe..5aa01af6b 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -33,8 +33,8 @@ private: Settings settings; void run() OVERRIDE { - settings.addEnabled("style"); - settings.addEnabled("information"); + settings.severity.enable(Severity::style); + settings.severity.enable(Severity::information); settings.checkLibrary = true; LOAD_LIB_2(settings.library, "std.cfg"); diff --git a/test/testvaarg.cpp b/test/testvaarg.cpp index 3ccabbc42..83a61e6fb 100644 --- a/test/testvaarg.cpp +++ b/test/testvaarg.cpp @@ -45,7 +45,7 @@ private: } void run() OVERRIDE { - settings.addEnabled("warning"); + settings.severity.enable(Severity::warning); TEST_CASE(wrongParameterTo_va_start); TEST_CASE(referenceAs_va_start);