Move more setting checks out of loops and use const bools instead. Reorder a few related checks.

Follow up to eedcb6abcb .
This commit is contained in:
Matthias Krüger 2015-04-10 14:18:52 +02:00
parent 282f701989
commit 42f0955e3f
18 changed files with 133 additions and 106 deletions

View File

@ -118,9 +118,9 @@ static bool variableIsUsedInScope(const Token* start, unsigned int varId, const
void CheckAutoVariables::assignFunctionArg() void CheckAutoVariables::assignFunctionArg()
{ {
const bool style = _settings->isEnabled("style"); const bool printStyle = _settings->isEnabled("style");
const bool warning = _settings->isEnabled("warning"); const bool printWarning = _settings->isEnabled("warning");
if (!style && !warning) if (!printStyle && !printWarning)
return; return;
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
@ -132,9 +132,9 @@ void CheckAutoVariables::assignFunctionArg()
isNonReferenceArg(tok->next()) && isNonReferenceArg(tok->next()) &&
!variableIsUsedInScope(Token::findsimplematch(tok->tokAt(2), ";"), tok->next()->varId(), scope) && !variableIsUsedInScope(Token::findsimplematch(tok->tokAt(2), ";"), tok->next()->varId(), scope) &&
!Token::findsimplematch(tok, "goto", scope->classEnd)) { !Token::findsimplematch(tok, "goto", scope->classEnd)) {
if (tok->next()->variable()->isPointer() && warning) if (tok->next()->variable()->isPointer() && printWarning)
errorUselessAssignmentPtrArg(tok->next()); errorUselessAssignmentPtrArg(tok->next());
else if (style) else if (printStyle)
errorUselessAssignmentArg(tok->next()); errorUselessAssignmentArg(tok->next());
} }
} }
@ -143,6 +143,7 @@ void CheckAutoVariables::assignFunctionArg()
void CheckAutoVariables::autoVariables() void CheckAutoVariables::autoVariables()
{ {
const bool printInconclusive = _settings->inconclusive;
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
const std::size_t functions = symbolDatabase->functionScopes.size(); const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) { for (std::size_t i = 0; i < functions; ++i) {
@ -157,7 +158,7 @@ void CheckAutoVariables::autoVariables()
errorAutoVariableAssignment(tok->next(), false); errorAutoVariableAssignment(tok->next(), false);
} else if (Token::Match(tok, "[;{}] %var% . %var% = & %var%")) { } else if (Token::Match(tok, "[;{}] %var% . %var% = & %var%")) {
// TODO: check if the parameter is only changed temporarily (#2969) // TODO: check if the parameter is only changed temporarily (#2969)
if (_settings->inconclusive) { if (printInconclusive) {
const Variable * var1 = tok->next()->variable(); const Variable * var1 = tok->next()->variable();
if (var1 && var1->isArgument() && var1->isPointer()) { if (var1 && var1->isArgument() && var1->isPointer()) {
const Token * const var2tok = tok->tokAt(6); const Token * const var2tok = tok->tokAt(6);
@ -168,7 +169,7 @@ void CheckAutoVariables::autoVariables()
tok = tok->tokAt(6); tok = tok->tokAt(6);
} else if (Token::Match(tok, "[;{}] %var% . %var% = %var% ;")) { } else if (Token::Match(tok, "[;{}] %var% . %var% = %var% ;")) {
// TODO: check if the parameter is only changed temporarily (#2969) // TODO: check if the parameter is only changed temporarily (#2969)
if (_settings->inconclusive) { if (printInconclusive) {
const Variable * var1 = tok->next()->variable(); const Variable * var1 = tok->next()->variable();
if (var1 && var1->isArgument() && var1->isPointer()) { if (var1 && var1->isArgument() && var1->isPointer()) {
if (isAutoVarArray(tok->tokAt(5))) if (isAutoVarArray(tok->tokAt(5)))

View File

@ -517,6 +517,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
return; return;
} }
const bool printInconclusive = _settings->inconclusive;
const MathLib::bigint total_size = arrayInfo.element_size() * size; const MathLib::bigint total_size = arrayInfo.element_size() * size;
const unsigned int declarationId = arrayInfo.declarationId(); const unsigned int declarationId = arrayInfo.declarationId();
@ -540,7 +541,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
// out of bounds then this flag will be set. // out of bounds then this flag will be set.
bool pointerIsOutOfBounds = false; bool pointerIsOutOfBounds = false;
const bool isPortabilityEnabled = _settings->isEnabled("portability"); const bool printPortability = _settings->isEnabled("portability");
for (const Token* const end = tok->scope()->classEnd; tok && tok != end; tok = tok->next()) { for (const Token* const end = tok->scope()->classEnd; tok && tok != end; tok = tok->next()) {
if (declarationId != 0 && Token::Match(tok, "%varid% = new|malloc|realloc", declarationId)) { if (declarationId != 0 && Token::Match(tok, "%varid% = new|malloc|realloc", declarationId)) {
@ -632,7 +633,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
// The access is still within the memory range for the array // The access is still within the memory range for the array
// so it may be intentional. // so it may be intentional.
else if (_settings->inconclusive) { else if (printInconclusive) {
arrayIndexOutOfBoundsError(tok->tokAt(1 + varcount), arrayInfo, indexes); arrayIndexOutOfBoundsError(tok->tokAt(1 + varcount), arrayInfo, indexes);
break; // only warn about the first one break; // only warn about the first one
} }
@ -669,7 +670,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
if (var && var->isArray() && var->dimensions().size() == 1) { if (var && var->isArray() && var->dimensions().size() == 1) {
const MathLib::bigint len = var->dimension(0); const MathLib::bigint len = var->dimension(0);
if (len > total_size) { if (len > total_size) {
if (_settings->inconclusive) if (printInconclusive)
possibleBufferOverrunError(tok, tok->strAt(4), tok->strAt(2), tok->str() == "strcat"); possibleBufferOverrunError(tok, tok->strAt(4), tok->strAt(2), tok->str() == "strcat");
continue; continue;
} }
@ -707,7 +708,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
// undefined behaviour: result of pointer arithmetic is out of bounds // undefined behaviour: result of pointer arithmetic is out of bounds
if (declarationId && Token::Match(tok, "= %varid% + %num% ;", declarationId)) { if (declarationId && Token::Match(tok, "= %varid% + %num% ;", declarationId)) {
const MathLib::bigint index = MathLib::toLongNumber(tok->strAt(3)); const MathLib::bigint index = MathLib::toLongNumber(tok->strAt(3));
if (isPortabilityEnabled && index > size) if (printPortability && index > size)
pointerOutOfBoundsError(tok->tokAt(2)); pointerOutOfBoundsError(tok->tokAt(2));
if (index >= size && Token::Match(tok->tokAt(-2), "[;{}] %varid% =", declarationId)) if (index >= size && Token::Match(tok->tokAt(-2), "[;{}] %varid% =", declarationId))
pointerIsOutOfBounds = true; pointerIsOutOfBounds = true;
@ -733,6 +734,7 @@ void CheckBufferOverrun::valueFlowCheckArrayIndex(const Token * const tok, const
return; return;
} }
*/ */
const bool printInconclusive = _settings->inconclusive;
// Taking address? // Taking address?
bool addressOf = false; bool addressOf = false;
{ {
@ -819,7 +821,7 @@ void CheckBufferOverrun::valueFlowCheckArrayIndex(const Token * const tok, const
if (indexes[i].intvalue >= arrayInfo.num(i)) { if (indexes[i].intvalue >= arrayInfo.num(i)) {
// The access is still within the memory range for the array // The access is still within the memory range for the array
// so it may be intentional. // so it may be intentional.
if (_settings->inconclusive) { if (printInconclusive) {
arrayIndexOutOfBoundsError(tok, arrayInfo, indexes); arrayIndexOutOfBoundsError(tok, arrayInfo, indexes);
break; // only warn about the first one break; // only warn about the first one
} }
@ -839,8 +841,9 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
const unsigned int declarationId = arrayInfo.declarationId(); const unsigned int declarationId = arrayInfo.declarationId();
const bool isPortabilityEnabled = _settings->isEnabled("portability"); const bool printPortability = _settings->isEnabled("portability");
const bool isWarningEnabled = _settings->isEnabled("warning"); const bool printWarning = _settings->isEnabled("warning");
const bool printInconclusive = _settings->inconclusive;
bool reassigned = false; bool reassigned = false;
@ -857,7 +860,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
valueFlowCheckArrayIndex(tok->next(), arrayInfo); valueFlowCheckArrayIndex(tok->next(), arrayInfo);
} }
else if (isPortabilityEnabled && !tok->isCast() && tok->astParent() && tok->astParent()->str() == "+") { else if (printPortability && !tok->isCast() && tok->astParent() && tok->astParent()->str() == "+") {
// undefined behaviour: result of pointer arithmetic is out of bounds // undefined behaviour: result of pointer arithmetic is out of bounds
const Token *index; const Token *index;
if (tok == tok->astParent()->astOperand1()) if (tok == tok->astParent()->astOperand1())
@ -873,7 +876,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
} }
} }
else if (isPortabilityEnabled && tok->astParent() && tok->astParent()->str() == "-") { else if (printPortability && tok->astParent() && tok->astParent()->str() == "-") {
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(declarationId); const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(declarationId);
if (var && var->isArray()) { if (var && var->isArray()) {
const Token *index = tok->astParent()->astOperand2(); const Token *index = tok->astParent()->astOperand2();
@ -893,7 +896,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
// Check function call.. // Check function call..
checkFunctionCall(tok, arrayInfo, std::list<const Token*>()); checkFunctionCall(tok, arrayInfo, std::list<const Token*>());
if (isWarningEnabled && _settings->inconclusive && Token::Match(tok, "strncpy|memcpy|memmove ( %varid% , %str% , %num% )", declarationId)) { if (printWarning && printInconclusive && Token::Match(tok, "strncpy|memcpy|memmove ( %varid% , %str% , %num% )", declarationId)) {
if (Token::getStrLength(tok->tokAt(4)) >= (unsigned int)total_size) { if (Token::getStrLength(tok->tokAt(4)) >= (unsigned int)total_size) {
const MathLib::bigint num = MathLib::toLongNumber(tok->strAt(6)); const MathLib::bigint num = MathLib::toLongNumber(tok->strAt(6));
if (total_size == num) if (total_size == num)
@ -901,7 +904,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
} }
} }
if (isWarningEnabled && Token::Match(tok, "strncpy|strncat ( %varid% ,", declarationId) && Token::Match(tok->linkAt(1)->tokAt(-2), ", %num% )")) { if (printWarning && Token::Match(tok, "strncpy|strncat ( %varid% ,", declarationId) && Token::Match(tok->linkAt(1)->tokAt(-2), ", %num% )")) {
const Token* param3 = tok->linkAt(1)->previous(); const Token* param3 = tok->linkAt(1)->previous();
// check for strncpy which is not terminated // check for strncpy which is not terminated
@ -910,7 +913,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
const MathLib::bigint num = MathLib::toLongNumber(param3->str()); const MathLib::bigint num = MathLib::toLongNumber(param3->str());
// this is currently 'inconclusive'. See TestBufferOverrun::terminateStrncpy3 // this is currently 'inconclusive'. See TestBufferOverrun::terminateStrncpy3
if (num >= total_size && _settings->inconclusive) { if (printInconclusive && num >= total_size) {
const Token *tok2 = tok->next()->link()->next(); const Token *tok2 = tok->next()->link()->next();
for (; tok2; tok2 = tok2->next()) { for (; tok2; tok2 = tok2->next()) {
const Token* tok3 = tok->tokAt(2); const Token* tok3 = tok->tokAt(2);

View File

@ -75,17 +75,18 @@ CheckClass::CheckClass(const Tokenizer *tokenizer, const Settings *settings, Err
void CheckClass::constructors() void CheckClass::constructors()
{ {
const bool style = _settings->isEnabled("style"); const bool printStyle = _settings->isEnabled("style");
const bool warnings = _settings->isEnabled("warning"); const bool printWarnings = _settings->isEnabled("warning");
if (!style && !warnings) if (!printStyle && !printWarnings)
return; return;
const bool printInconclusive = _settings->inconclusive;
const std::size_t classes = symbolDatabase->classAndStructScopes.size(); const std::size_t classes = symbolDatabase->classAndStructScopes.size();
for (std::size_t i = 0; i < classes; ++i) { for (std::size_t i = 0; i < classes; ++i) {
const Scope * scope = symbolDatabase->classAndStructScopes[i]; const Scope * scope = symbolDatabase->classAndStructScopes[i];
// There are no constructors. // There are no constructors.
if (scope->numConstructors == 0 && style) { if (scope->numConstructors == 0 && printStyle) {
// If there is a private variable, there should be a constructor.. // If there is a private variable, there should be a constructor..
std::list<Variable>::const_iterator var; std::list<Variable>::const_iterator var;
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) { for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) {
@ -97,7 +98,7 @@ void CheckClass::constructors()
} }
} }
if (!warnings) if (!printWarnings)
continue; continue;
// #3196 => bailout if there are nested unions // #3196 => bailout if there are nested unions
@ -176,7 +177,7 @@ void CheckClass::constructors()
!(var->type() && var->type()->needInitialization != Type::True) && !(var->type() && var->type()->needInitialization != Type::True) &&
(func->type == Function::eCopyConstructor || func->type == Function::eOperatorEqual)) { (func->type == Function::eCopyConstructor || func->type == Function::eOperatorEqual)) {
if (!var->typeStartToken()->isStandardType()) { if (!var->typeStartToken()->isStandardType()) {
if (_settings->inconclusive) if (printInconclusive)
inconclusive = true; inconclusive = true;
else else
continue; continue;
@ -206,7 +207,7 @@ void CheckClass::constructors()
func->arg && func->arg->link()->next() == func->functionScope->classStart && func->arg && func->arg->link()->next() == func->functionScope->classStart &&
func->functionScope->classStart->link() == func->functionScope->classStart->next()) { func->functionScope->classStart->link() == func->functionScope->classStart->next()) {
// don't warn about user defined default constructor when there are other constructors // don't warn about user defined default constructor when there are other constructors
if (_settings->inconclusive) if (printInconclusive)
uninitVarError(func->token, scope->className, var->name(), true); uninitVarError(func->token, scope->className, var->name(), true);
} else } else
uninitVarError(func->token, scope->className, var->name(), inconclusive); uninitVarError(func->token, scope->className, var->name(), inconclusive);
@ -1466,6 +1467,7 @@ void CheckClass::virtualDestructor()
// * base class is deleted // * base class is deleted
// unless inconclusive in which case: // unless inconclusive in which case:
// * base class has virtual members but doesn't have virtual destructor // * base class has virtual members but doesn't have virtual destructor
const bool printInconclusive = _settings->inconclusive;
std::list<const Function *> inconclusive_errors; std::list<const Function *> inconclusive_errors;
@ -1475,7 +1477,7 @@ void CheckClass::virtualDestructor()
// Skip base classes (unless inconclusive) // Skip base classes (unless inconclusive)
if (scope->definedType->derivedFrom.empty()) { if (scope->definedType->derivedFrom.empty()) {
if (_settings->inconclusive) { if (printInconclusive) {
const Function *destructor = scope->getDestructor(); const Function *destructor = scope->getDestructor();
if (destructor && !destructor->isVirtual()) { if (destructor && !destructor->isVirtual()) {
std::list<Function>::const_iterator func; std::list<Function>::const_iterator func;

View File

@ -584,9 +584,9 @@ template<class T> static T getvalue(const int test, const T value1, const T valu
void CheckCondition::checkIncorrectLogicOperator() void CheckCondition::checkIncorrectLogicOperator()
{ {
const bool style = _settings->isEnabled("style"); const bool printStyle = _settings->isEnabled("style");
const bool warning = _settings->isEnabled("warning"); const bool printWarning = _settings->isEnabled("warning");
if (!style && !warning) if (!printWarning && !printStyle)
return; return;
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
@ -703,14 +703,14 @@ void CheckCondition::checkIncorrectLogicOperator()
const std::string cond1str = (expr1->isName() ? expr1->str() : "EXPR") + " " + op1 + " " + value1; const std::string cond1str = (expr1->isName() ? expr1->str() : "EXPR") + " " + op1 + " " + value1;
const std::string cond2str = (expr2->isName() ? expr2->str() : "EXPR") + " " + op2 + " " + value2; const std::string cond2str = (expr2->isName() ? expr2->str() : "EXPR") + " " + op2 + " " + value2;
if (warning && (alwaysTrue || alwaysFalse)) { if (printWarning && (alwaysTrue || alwaysFalse)) {
const std::string text = cond1str + " " + tok->str() + " " + cond2str; const std::string text = cond1str + " " + tok->str() + " " + cond2str;
incorrectLogicOperatorError(tok, text, alwaysTrue); incorrectLogicOperatorError(tok, text, alwaysTrue);
} else if (style && secondTrue) { } else if (printStyle && secondTrue) {
const std::string text = "If " + cond1str + ", the comparison " + cond2str + const std::string text = "If " + cond1str + ", the comparison " + cond2str +
" is always " + (secondTrue ? "true" : "false") + "."; " is always " + (secondTrue ? "true" : "false") + ".";
redundantConditionError(tok, text); redundantConditionError(tok, text);
} else if (style && firstTrue) { } else if (printStyle && firstTrue) {
//const std::string text = "The comparison " + cond1str + " is always " + //const std::string text = "The comparison " + cond1str + " is always " +
// (firstTrue ? "true" : "false") + " when " + // (firstTrue ? "true" : "false") + " when " +
// cond2str + "."; // cond2str + ".";

View File

@ -77,6 +77,7 @@ void CheckExceptionSafety::deallocThrow()
if (!_settings->isEnabled("warning")) if (!_settings->isEnabled("warning"))
return; return;
const bool printInconclusive = _settings->inconclusive;
const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase();
// Deallocate a global/member pointer and then throw exception // Deallocate a global/member pointer and then throw exception
@ -113,7 +114,7 @@ void CheckExceptionSafety::deallocThrow()
for (const Token *tok2 = tok; tok2 != end2; tok2 = tok2->next()) { for (const Token *tok2 = tok; tok2 != end2; tok2 = tok2->next()) {
// Throw after delete -> Dead pointer // Throw after delete -> Dead pointer
if (tok2->str() == "throw") { if (tok2->str() == "throw") {
if (_settings->inconclusive) { // For inconclusive checking, throw directly. if (printInconclusive) { // For inconclusive checking, throw directly.
deallocThrowError(tok2, tok->str()); deallocThrowError(tok2, tok->str());
break; break;
} }

View File

@ -366,9 +366,9 @@ void CheckIO::seekOnAppendedFileError(const Token *tok)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckIO::invalidScanf() void CheckIO::invalidScanf()
{ {
const bool warning = _settings->isEnabled("warning"); const bool printWarning = _settings->isEnabled("warning");
const bool portability = _settings->isEnabled("portability"); const bool printPortability = _settings->isEnabled("portability");
if (!warning && !portability) if (!printWarning && !printPortability)
return; return;
const bool windows = _settings->isWindowsPlatform(); const bool windows = _settings->isWindowsPlatform();
@ -405,9 +405,9 @@ void CheckIO::invalidScanf()
} }
else if (std::isalpha((unsigned char)formatstr[i]) || formatstr[i] == '[') { else if (std::isalpha((unsigned char)formatstr[i]) || formatstr[i] == '[') {
if (warning && (formatstr[i] == 's' || formatstr[i] == '[' || formatstr[i] == 'S' || (formatstr[i] == 'l' && formatstr[i+1] == 's'))) // #3490 - field width limits are only necessary for string input if (printWarning && (formatstr[i] == 's' || formatstr[i] == '[' || formatstr[i] == 'S' || (formatstr[i] == 'l' && formatstr[i+1] == 's'))) // #3490 - field width limits are only necessary for string input
invalidScanfError(tok, false); invalidScanfError(tok, false);
else if (portability && formatstr[i] != 'n' && formatstr[i] != 'c' && !windows) else if (printPortability && formatstr[i] != 'n' && formatstr[i] != 'c' && !windows)
invalidScanfError(tok, true); // Warn about libc bug in versions prior to 2.13-25 invalidScanfError(tok, true); // Warn about libc bug in versions prior to 2.13-25
format = false; format = false;
} }
@ -514,8 +514,8 @@ static inline bool typesMatch(const std::string& iToTest, const std::string& iTy
void CheckIO::checkWrongPrintfScanfArguments() void CheckIO::checkWrongPrintfScanfArguments()
{ {
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
const bool warning = _settings->isEnabled("warning"); const bool printWarning = _settings->isEnabled("warning");
const bool windows = _settings->isWindowsPlatform(); const bool isWindows = _settings->isWindowsPlatform();
std::size_t functions = symbolDatabase->functionScopes.size(); std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t j = 0; j < functions; ++j) { for (std::size_t j = 0; j < functions; ++j) {
@ -548,7 +548,7 @@ void CheckIO::checkWrongPrintfScanfArguments()
// formatstring found in library. Find format string and first argument belonging to format string. // formatstring found in library. Find format string and first argument belonging to format string.
if (!findFormat(static_cast<unsigned int>(formatStringArgNo), tok->tokAt(2), &formatStringTok, &argListTok)) if (!findFormat(static_cast<unsigned int>(formatStringArgNo), tok->tokAt(2), &formatStringTok, &argListTok))
continue; continue;
} else if (windows && Token::Match(tok, "Format|AppendFormat (") && } else if (isWindows && Token::Match(tok, "Format|AppendFormat (") &&
Token::Match(tok->tokAt(-2), "%var% .") && tok->tokAt(-2)->variable() && Token::Match(tok->tokAt(-2), "%var% .") && tok->tokAt(-2)->variable() &&
tok->tokAt(-2)->variable()->typeStartToken()->str() == "CString") { tok->tokAt(-2)->variable()->typeStartToken()->str() == "CString") {
// Find second parameter and format string // Find second parameter and format string
@ -562,7 +562,7 @@ void CheckIO::checkWrongPrintfScanfArguments()
// Find forth parameter and format string // Find forth parameter and format string
if (!findFormat(2, tok->tokAt(2), &formatStringTok, &argListTok)) if (!findFormat(2, tok->tokAt(2), &formatStringTok, &argListTok))
continue; continue;
} else if (windows && Token::Match(tok, "sprintf_s|swprintf_s (")) { } else if (isWindows && Token::Match(tok, "sprintf_s|swprintf_s (")) {
// template <size_t size> int sprintf_s(char (&buffer)[size], const char *format, ...); // template <size_t size> int sprintf_s(char (&buffer)[size], const char *format, ...);
if (findFormat(1, tok->tokAt(2), &formatStringTok, &argListTok)) { if (findFormat(1, tok->tokAt(2), &formatStringTok, &argListTok)) {
if (!formatStringTok) if (!formatStringTok)
@ -573,7 +573,7 @@ void CheckIO::checkWrongPrintfScanfArguments()
if (!formatStringTok) if (!formatStringTok)
continue; continue;
} }
} else if (windows && Token::Match(tok, "_snprintf_s|_snwprintf_s (")) { } else if (isWindows && Token::Match(tok, "_snprintf_s|_snwprintf_s (")) {
// template <size_t size> int _snprintf_s(char (&buffer)[size], size_t count, const char *format, ...); // template <size_t size> int _snprintf_s(char (&buffer)[size], size_t count, const char *format, ...);
if (findFormat(2, tok->tokAt(2), &formatStringTok, &argListTok)) { if (findFormat(2, tok->tokAt(2), &formatStringTok, &argListTok)) {
if (!formatStringTok) if (!formatStringTok)
@ -1040,7 +1040,7 @@ void CheckIO::checkWrongPrintfScanfArguments()
break; break;
} }
} }
} else if (!scan && warning) { } else if (!scan && printWarning) {
std::string specifier; std::string specifier;
bool done = false; bool done = false;
while (!done) { while (!done) {
@ -1357,7 +1357,7 @@ void CheckIO::checkWrongPrintfScanfArguments()
argListTok2 = argListTok2->nextArgument(); // Find next argument argListTok2 = argListTok2->nextArgument(); // Find next argument
} }
if (warning) { if (printWarning) {
// Check that all parameter positions reference an actual parameter // Check that all parameter positions reference an actual parameter
for (std::set<unsigned int>::const_iterator it = parameterPositionsUsed.begin() ; it != parameterPositionsUsed.end() ; ++it) { for (std::set<unsigned int>::const_iterator it = parameterPositionsUsed.begin() ; it != parameterPositionsUsed.end() ; ++it) {
if ((*it == 0) || (*it > numFormat)) if ((*it == 0) || (*it > numFormat))

View File

@ -1400,6 +1400,8 @@ void CheckMemoryLeakInFunction::simplifycode(Token *tok) const
} }
} }
const bool printExperimental = _settings->experimental;
// Insert extra ";" // Insert extra ";"
for (Token *tok2 = tok; tok2; tok2 = tok2->next()) { for (Token *tok2 = tok; tok2; tok2 = tok2->next()) {
if (!tok2->previous() || Token::Match(tok2->previous(), "[;{}]")) { if (!tok2->previous() || Token::Match(tok2->previous(), "[;{}]")) {
@ -1712,7 +1714,7 @@ void CheckMemoryLeakInFunction::simplifycode(Token *tok) const
} }
// Remove the "if break|continue ;" that follows "dealloc ; alloc ;" // Remove the "if break|continue ;" that follows "dealloc ; alloc ;"
if (! _settings->experimental && Token::Match(tok2, "dealloc ; alloc ; if break|continue ;")) { if (!printExperimental && Token::Match(tok2, "dealloc ; alloc ; if break|continue ;")) {
tok2->tokAt(3)->deleteNext(2); tok2->tokAt(3)->deleteNext(2);
done = false; done = false;
} }
@ -1964,7 +1966,7 @@ void CheckMemoryLeakInFunction::simplifycode(Token *tok) const
} }
// If "--all" is given, remove all "callfunc".. // If "--all" is given, remove all "callfunc"..
if (done && _settings->experimental) { if (done && printExperimental) {
for (Token *tok2 = tok; tok2; tok2 = tok2->next()) { for (Token *tok2 = tok; tok2; tok2 = tok2->next()) {
if (tok2->str() == "callfunc") { if (tok2->str() == "callfunc") {
tok2->deleteThis(); tok2->deleteThis();

View File

@ -309,6 +309,7 @@ void CheckNullPointer::nullPointerLinkedList()
void CheckNullPointer::nullPointerByDeRefAndChec() void CheckNullPointer::nullPointerByDeRefAndChec()
{ {
const bool printWarnings = _settings->isEnabled("warning"); const bool printWarnings = _settings->isEnabled("warning");
const bool printInconclusive = (_settings->inconclusive);
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
const Variable *var = tok->variable(); const Variable *var = tok->variable();
@ -320,7 +321,7 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
if (!value) if (!value)
continue; continue;
if (!_settings->inconclusive && value->inconclusive) if (!printInconclusive && value->inconclusive)
continue; continue;
// Is pointer used as function parameter? // Is pointer used as function parameter?
@ -347,7 +348,7 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
// Pointer dereference. // Pointer dereference.
bool unknown = false; bool unknown = false;
if (!isPointerDeRef(tok,unknown)) { if (!isPointerDeRef(tok,unknown)) {
if (_settings->inconclusive && unknown) { if (printInconclusive && unknown) {
if (value->condition == nullptr) if (value->condition == nullptr)
nullPointerError(tok, tok->str(), true, value->defaultArg); nullPointerError(tok, tok->str(), true, value->defaultArg);
else else

View File

@ -37,6 +37,7 @@ void CheckObsoleteFunctions::obsoleteFunctions()
return; return;
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
const bool cStandard = _settings->standards.c >= Standards::C99 ;
// Functions defined somewhere? // Functions defined somewhere?
for (unsigned int i = 0; i < symbolDatabase->functionScopes.size(); i++) { for (unsigned int i = 0; i < symbolDatabase->functionScopes.size(); i++) {
@ -64,7 +65,7 @@ void CheckObsoleteFunctions::obsoleteFunctions()
reportError(tok, Severity::style, "obsoleteFunctions"+it->first, it->second); reportError(tok, Severity::style, "obsoleteFunctions"+it->first, it->second);
} }
} }
if (_settings->standards.c >= Standards::C99) { if (cStandard) {
// alloca : this function is obsolete in C but not in C++ (#4382) // alloca : this function is obsolete in C but not in C++ (#4382)
it = _obsoleteC99Functions.find(tok->str()); it = _obsoleteC99Functions.find(tok->str());
if (it != _obsoleteC99Functions.end() && !(tok->str() == "alloca" && _tokenizer->isCPP())) { if (it != _obsoleteC99Functions.end() && !(tok->str() == "alloca" && _tokenizer->isCPP())) {

View File

@ -433,6 +433,7 @@ void CheckOther::invalidPointerCast()
if (!_settings->isEnabled("portability")) if (!_settings->isEnabled("portability"))
return; return;
const bool printInconclusive = _settings->inconclusive;
const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase();
const std::size_t functions = symbolDatabase->functionScopes.size(); const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) { for (std::size_t i = 0; i < functions; ++i) {
@ -491,7 +492,7 @@ void CheckOther::invalidPointerCast()
std::string fromType = analyzeType(fromTok); std::string fromType = analyzeType(fromTok);
std::string toType = analyzeType(toTok); std::string toType = analyzeType(toTok);
if (fromType != toType && !fromType.empty() && !toType.empty() && (toTok->str() != "char" || _settings->inconclusive)) if (fromType != toType && !fromType.empty() && !toType.empty() && (toTok->str() != "char" || printInconclusive))
invalidPointerCastError(tok, fromType, toType, toTok->str() == "char"); invalidPointerCastError(tok, fromType, toType, toTok->str() == "char");
} }
} }
@ -585,11 +586,12 @@ static void eraseMemberAssignments(const unsigned int varId, const std::map<unsi
void CheckOther::checkRedundantAssignment() void CheckOther::checkRedundantAssignment()
{ {
const bool performance = _settings->isEnabled("performance"); const bool printPerformance = _settings->isEnabled("performance");
const bool warning = _settings->isEnabled("warning"); const bool printWarning = _settings->isEnabled("warning");
if (!warning && !performance) if (!printWarning && !printPerformance)
return; return;
const bool printInconclusive = _settings->inconclusive;
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
for (std::list<Scope>::const_iterator scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) { for (std::list<Scope>::const_iterator scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
@ -660,11 +662,11 @@ void CheckOther::checkRedundantAssignment()
} }
} }
if (error) { if (error) {
if (warning && scope->type == Scope::eSwitch && Token::findmatch(it->second, "default|case", tok)) if (printWarning && scope->type == Scope::eSwitch && Token::findmatch(it->second, "default|case", tok))
redundantAssignmentInSwitchError(it->second, tok, tok->str()); redundantAssignmentInSwitchError(it->second, tok, tok->str());
else if (performance) { else if (printPerformance) {
const bool nonlocal = nonLocal(it->second->variable()); const bool nonlocal = nonLocal(it->second->variable());
if (_settings->inconclusive || !nonlocal) // see #5089 - report inconclusive only when requested if (printInconclusive || !nonlocal) // see #5089 - report inconclusive only when requested
redundantAssignmentError(it->second, tok, tok->str(), nonlocal); // Inconclusive for non-local variables redundantAssignmentError(it->second, tok, tok->str(), nonlocal); // Inconclusive for non-local variables
} }
} }
@ -699,9 +701,9 @@ void CheckOther::checkRedundantAssignment()
memAssignments[param1->varId()] = tok; memAssignments[param1->varId()] = tok;
else { else {
const std::map<unsigned int, const Token*>::iterator it = memAssignments.find(param1->varId()); const std::map<unsigned int, const Token*>::iterator it = memAssignments.find(param1->varId());
if (warning && scope->type == Scope::eSwitch && Token::findmatch(it->second, "default|case", tok)) if (printWarning && scope->type == Scope::eSwitch && Token::findmatch(it->second, "default|case", tok))
redundantCopyInSwitchError(it->second, tok, param1->str()); redundantCopyInSwitchError(it->second, tok, param1->str());
else if (performance) else if (printPerformance)
redundantCopyError(it->second, tok, param1->str()); redundantCopyError(it->second, tok, param1->str());
} }
} }
@ -1135,7 +1137,7 @@ void CheckOther::checkUnreachableCode()
{ {
if (!_settings->isEnabled("style")) if (!_settings->isEnabled("style"))
return; return;
const bool printInconclusive = _settings->inconclusive;
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
const std::size_t functions = symbolDatabase->functionScopes.size(); const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) { for (std::size_t i = 0; i < functions; ++i) {
@ -1170,7 +1172,7 @@ void CheckOther::checkUnreachableCode()
// TODO: Try to find a better way to avoid false positives due to preprocessor configurations. // TODO: Try to find a better way to avoid false positives due to preprocessor configurations.
bool inconclusive = secondBreak && (secondBreak->linenr() - 1 > secondBreak->previous()->linenr()); bool inconclusive = secondBreak && (secondBreak->linenr() - 1 > secondBreak->previous()->linenr());
if (secondBreak && (_settings->inconclusive || !inconclusive)) { if (secondBreak && (printInconclusive || !inconclusive)) {
if (Token::Match(secondBreak, "continue|goto|throw") || if (Token::Match(secondBreak, "continue|goto|throw") ||
(secondBreak->str() == "return" && (tok->str() == "return" || secondBreak->strAt(1) == ";"))) { // return with value after statements like throw can be necessary to make a function compile (secondBreak->str() == "return" && (tok->str() == "return" || secondBreak->strAt(1) == ";"))) { // return with value after statements like throw can be necessary to make a function compile
duplicateBreakError(secondBreak, inconclusive); duplicateBreakError(secondBreak, inconclusive);
@ -1275,9 +1277,9 @@ void CheckOther::memsetZeroBytesError(const Token *tok, const std::string &varna
void CheckOther::checkMemsetInvalid2ndParam() void CheckOther::checkMemsetInvalid2ndParam()
{ {
const bool portability = _settings->isEnabled("portability"); const bool printPortability = _settings->isEnabled("portability");
const bool warning = _settings->isEnabled("warning"); const bool printWarning = _settings->isEnabled("warning");
if (!warning && !portability) if (!printWarning && !printPortability)
return; return;
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
@ -1302,9 +1304,9 @@ void CheckOther::checkMemsetInvalid2ndParam()
top = top->astParent(); top = top->astParent();
// Check if second parameter is a float variable or a float literal != 0.0f // Check if second parameter is a float variable or a float literal != 0.0f
if (portability && astIsFloat(top,false)) { if (printPortability && astIsFloat(top,false)) {
memsetFloatError(secondParamTok, top->expressionString()); memsetFloatError(secondParamTok, top->expressionString());
} else if (warning && secondParamTok->isNumber()) { // Check if the second parameter is a literal and is out of range } else if (printWarning && secondParamTok->isNumber()) { // Check if the second parameter is a literal and is out of range
const long long int value = MathLib::toLongNumber(secondParamTok->str()); const long long int value = MathLib::toLongNumber(secondParamTok->str());
if (value < -128 || value > 255) if (value < -128 || value > 255)
memsetValueOutOfRangeError(secondParamTok, secondParamTok->str()); memsetValueOutOfRangeError(secondParamTok, secondParamTok->str());
@ -1786,6 +1788,7 @@ void CheckOther::constStatementError(const Token *tok, const std::string &type)
void CheckOther::checkZeroDivision() void CheckOther::checkZeroDivision()
{ {
const bool printWarnings = _settings->isEnabled("warning"); const bool printWarnings = _settings->isEnabled("warning");
const bool printInconclusive = _settings->inconclusive;
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
if (Token::Match(tok, "div|ldiv|lldiv|imaxdiv ( %num% , %num% )") && if (Token::Match(tok, "div|ldiv|lldiv|imaxdiv ( %num% , %num% )") &&
@ -1802,7 +1805,7 @@ void CheckOther::checkZeroDivision()
// Value flow.. // Value flow..
const ValueFlow::Value *value = tok->astOperand2()->getValue(0LL); const ValueFlow::Value *value = tok->astOperand2()->getValue(0LL);
if (value) { if (value) {
if (!_settings->inconclusive && value->inconclusive) if (!printInconclusive && value->inconclusive)
continue; continue;
if (value->condition == nullptr) if (value->condition == nullptr)
zerodivError(tok, value->inconclusive); zerodivError(tok, value->inconclusive);
@ -2071,6 +2074,7 @@ void CheckOther::checkInvalidFree()
{ {
std::map<unsigned int, bool> allocatedVariables; std::map<unsigned int, bool> allocatedVariables;
const bool printInconclusive = _settings->inconclusive;
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
const std::size_t functions = symbolDatabase->functionScopes.size(); const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) { for (std::size_t i = 0; i < functions; ++i) {
@ -2088,7 +2092,7 @@ void CheckOther::checkInvalidFree()
else if (Token::Match(tok, "%var% = %name% +|-") && else if (Token::Match(tok, "%var% = %name% +|-") &&
tok->varId() == tok->tokAt(2)->varId() && tok->varId() == tok->tokAt(2)->varId() &&
allocatedVariables.find(tok->varId()) != allocatedVariables.end()) { allocatedVariables.find(tok->varId()) != allocatedVariables.end()) {
if (_settings->inconclusive) if (printInconclusive)
allocatedVariables[tok->varId()] = true; allocatedVariables[tok->varId()] = true;
else else
allocatedVariables.erase(tok->varId()); allocatedVariables.erase(tok->varId());
@ -2555,9 +2559,9 @@ void CheckOther::checkIncompleteArrayFill()
{ {
if (!_settings->inconclusive) if (!_settings->inconclusive)
return; return;
const bool warning = _settings->isEnabled("warning"); const bool printWarning = _settings->isEnabled("warning");
const bool portability = _settings->isEnabled("portability"); const bool printPortability = _settings->isEnabled("portability");
if (!portability && !warning) if (!printPortability && !printWarning)
return; return;
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
@ -2574,9 +2578,9 @@ void CheckOther::checkIncompleteArrayFill()
if (MathLib::toLongNumber(tok->linkAt(1)->strAt(-1)) == var->dimension(0)) { if (MathLib::toLongNumber(tok->linkAt(1)->strAt(-1)) == var->dimension(0)) {
unsigned int size = _tokenizer->sizeOfType(var->typeStartToken()); unsigned int size = _tokenizer->sizeOfType(var->typeStartToken());
if ((size != 1 && size != 100 && size != 0) || var->isPointer()) { if ((size != 1 && size != 100 && size != 0) || var->isPointer()) {
if (warning) if (printWarning)
incompleteArrayFillError(tok, var->name(), tok->str(), false); incompleteArrayFillError(tok, var->name(), tok->str(), false);
} else if (var->typeStartToken()->str() == "bool" && portability) // sizeof(bool) is not 1 on all platforms } else if (var->typeStartToken()->str() == "bool" && printPortability) // sizeof(bool) is not 1 on all platforms
incompleteArrayFillError(tok, var->name(), tok->str(), true); incompleteArrayFillError(tok, var->name(), tok->str(), true);
} }
} }

View File

@ -246,10 +246,12 @@ void CheckSizeof::sizeofCalculation()
if (!_settings->isEnabled("warning")) if (!_settings->isEnabled("warning"))
return; return;
const bool printInconclusive = _settings->inconclusive;
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
if (Token::simpleMatch(tok, "sizeof (")) { if (Token::simpleMatch(tok, "sizeof (")) {
const Token *argument = tok->next()->astOperand2(); const Token *argument = tok->next()->astOperand2();
if (argument && argument->isCalculation() && (!argument->isExpandedMacro() || _settings->inconclusive)) if (argument && argument->isCalculation() && (!argument->isExpandedMacro() || printInconclusive))
sizeofCalculationError(argument, argument->isExpandedMacro()); sizeofCalculationError(argument, argument->isExpandedMacro());
} }
} }

View File

@ -758,9 +758,9 @@ static bool if_findCompare(const Token * const tokBack)
void CheckStl::if_find() void CheckStl::if_find()
{ {
const bool warning = _settings->isEnabled("warning"); const bool printWarning = _settings->isEnabled("warning");
const bool performance = _settings->isEnabled("performance"); const bool printPerformance = _settings->isEnabled("performance");
if (!warning && !performance) if (!printWarning && !printPerformance)
return; return;
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
@ -811,11 +811,11 @@ void CheckStl::if_find()
if (if_findCompare(funcTok->next())) if (if_findCompare(funcTok->next()))
continue; continue;
if (warning && !container->stdStringLike) if (printWarning && !container->stdStringLike)
if_findError(tok, false); if_findError(tok, false);
else if (performance && container->stdStringLike) else if (printPerformance && container->stdStringLike)
if_findError(tok, true); if_findError(tok, true);
} else if (warning && Token::Match(tok, "std :: find|find_if (")) { } else if (printWarning && Token::Match(tok, "std :: find|find_if (")) {
// check that result is checked properly // check that result is checked properly
if (!if_findCompare(tok->tokAt(3))) { if (!if_findCompare(tok->tokAt(3))) {
if_findError(tok, false); if_findError(tok, false);
@ -1044,7 +1044,8 @@ static bool isLocal(const Token *tok)
void CheckStl::string_c_str() void CheckStl::string_c_str()
{ {
const bool performance = _settings->isEnabled("performance"); const bool printInconclusive = _settings->inconclusive;
const bool printPerformance = _settings->isEnabled("performance");
// THIS ARRAY MUST BE ORDERED ALPHABETICALLY // THIS ARRAY MUST BE ORDERED ALPHABETICALLY
static const char* const stl_string[] = { static const char* const stl_string[] = {
"string", "u16string", "u32string", "wstring" "string", "u16string", "u32string", "wstring"
@ -1058,7 +1059,7 @@ void CheckStl::string_c_str()
// Find all functions that take std::string as argument // Find all functions that take std::string as argument
std::multimap<std::string, unsigned int> c_strFuncParam; std::multimap<std::string, unsigned int> c_strFuncParam;
if (performance) { if (printPerformance) {
for (std::list<Scope>::const_iterator scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) { for (std::list<Scope>::const_iterator scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
for (std::list<Function>::const_iterator func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { for (std::list<Function>::const_iterator func = scope->functionList.begin(); func != scope->functionList.end(); ++func) {
if (c_strFuncParam.erase(func->tokenDef->str()) != 0) { // Check if function with this name was already found if (c_strFuncParam.erase(func->tokenDef->str()) != 0) { // Check if function with this name was already found
@ -1106,7 +1107,7 @@ void CheckStl::string_c_str()
const Variable* var = tok->next()->variable(); const Variable* var = tok->next()->variable();
if (var && var->isPointer()) if (var && var->isPointer())
string_c_strError(tok); string_c_strError(tok);
} else if (performance && Token::Match(tok, "%name% ( !!)") && c_strFuncParam.find(tok->str()) != c_strFuncParam.end() && } else if (printPerformance && Token::Match(tok, "%name% ( !!)") && c_strFuncParam.find(tok->str()) != c_strFuncParam.end() &&
!Token::Match(tok->previous(), "::|.") && tok->varId() == 0 && tok->str() != scope->className) { // calling function. TODO: Add support for member functions !Token::Match(tok->previous(), "::|.") && tok->varId() == 0 && tok->str() != scope->className) { // calling function. TODO: Add support for member functions
std::pair<std::multimap<std::string, unsigned int>::const_iterator, std::multimap<std::string, unsigned int>::const_iterator> range = c_strFuncParam.equal_range(tok->str()); std::pair<std::multimap<std::string, unsigned int>::const_iterator, std::multimap<std::string, unsigned int>::const_iterator> range = c_strFuncParam.equal_range(tok->str());
for (std::multimap<std::string, unsigned int>::const_iterator i = range.first; i != range.second; ++i) { for (std::multimap<std::string, unsigned int>::const_iterator i = range.first; i != range.second; ++i) {
@ -1157,7 +1158,7 @@ void CheckStl::string_c_str()
} else if (Token::simpleMatch(tok, "return (") && } else if (Token::simpleMatch(tok, "return (") &&
Token::Match(tok->next()->link(), ") . c_str|data ( ) ;")) { Token::Match(tok->next()->link(), ") . c_str|data ( ) ;")) {
// Check for "+ localvar" or "+ std::string(" inside the bracket // Check for "+ localvar" or "+ std::string(" inside the bracket
bool is_implicit_std_string = _settings->inconclusive; bool is_implicit_std_string = printInconclusive;
const Token *search_end = tok->next()->link(); const Token *search_end = tok->next()->link();
for (const Token *search_tok = tok->tokAt(2); search_tok != search_end; search_tok = search_tok->next()) { for (const Token *search_tok = tok->tokAt(2); search_tok != search_end; search_tok = search_tok->next()) {
if (Token::Match(search_tok, "+ %var%") && isLocal(search_tok->next()) && if (Token::Match(search_tok, "+ %var%") && isLocal(search_tok->next()) &&
@ -1175,7 +1176,7 @@ void CheckStl::string_c_str()
} }
} }
// Using c_str() to get the return value is redundant if the function returns std::string or const std::string&. // Using c_str() to get the return value is redundant if the function returns std::string or const std::string&.
else if (performance && (returnType == stdString || returnType == stdStringConstRef)) { else if (printPerformance && (returnType == stdString || returnType == stdStringConstRef)) {
if (tok->str() == "return") { if (tok->str() == "return") {
const Token* tok2 = Token::findsimplematch(tok->next(), ";"); const Token* tok2 = Token::findsimplematch(tok->next(), ";");
if (Token::Match(tok2->tokAt(-4), ". c_str|data ( )")) { if (Token::Match(tok2->tokAt(-4), ". c_str|data ( )")) {
@ -1351,6 +1352,11 @@ void CheckStl::autoPointerMallocError(const Token *tok, const std::string& alloc
void CheckStl::uselessCalls() void CheckStl::uselessCalls()
{ {
const bool printPerformance = _settings->isEnabled("performance");
const bool printWarning = _settings->isEnabled("warning");
if (!printPerformance && !printWarning)
return;
// THIS ARRAY MUST BE ORDERED ALPHABETICALLY // THIS ARRAY MUST BE ORDERED ALPHABETICALLY
static const char* const stl_string[] = { static const char* const stl_string[] = {
"string", "u16string", "u32string", "wstring" "string", "u16string", "u32string", "wstring"
@ -1363,23 +1369,18 @@ void CheckStl::uselessCalls()
"unordered_set", "vector", "wstring" "unordered_set", "vector", "wstring"
}; };
const bool performance = _settings->isEnabled("performance");
const bool warning = _settings->isEnabled("warning");
if (!performance && !warning)
return;
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
const std::size_t functions = symbolDatabase->functionScopes.size(); const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) { for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i]; const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) { for (const Token* tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) {
if (warning && Token::Match(tok, "%var% . compare|find|rfind|find_first_not_of|find_first_of|find_last_not_of|find_last_of ( %name% [,)]") && if (printWarning && Token::Match(tok, "%var% . compare|find|rfind|find_first_not_of|find_first_of|find_last_not_of|find_last_of ( %name% [,)]") &&
tok->varId() == tok->tokAt(4)->varId()) { tok->varId() == tok->tokAt(4)->varId()) {
uselessCallsReturnValueError(tok->tokAt(4), tok->str(), tok->strAt(2)); uselessCallsReturnValueError(tok->tokAt(4), tok->str(), tok->strAt(2));
} else if (performance && Token::Match(tok, "%var% . swap ( %name% )") && } else if (printPerformance && Token::Match(tok, "%var% . swap ( %name% )") &&
tok->varId() == tok->tokAt(4)->varId()) { tok->varId() == tok->tokAt(4)->varId()) {
uselessCallsSwapError(tok, tok->str()); uselessCallsSwapError(tok, tok->str());
} else if (performance && Token::Match(tok, "%var% . substr (") && } else if (printPerformance && Token::Match(tok, "%var% . substr (") &&
tok->variable() && tok->variable()->isStlType(stl_string)) { tok->variable() && tok->variable()->isStlType(stl_string)) {
if (Token::Match(tok->tokAt(4), "0| )")) if (Token::Match(tok->tokAt(4), "0| )"))
uselessCallsSubstrError(tok, false); uselessCallsSubstrError(tok, false);
@ -1388,7 +1389,7 @@ void CheckStl::uselessCalls()
uselessCallsSubstrError(tok, false); uselessCallsSubstrError(tok, false);
} else if (Token::simpleMatch(tok->linkAt(3)->tokAt(-2), ", 0 )")) } else if (Token::simpleMatch(tok->linkAt(3)->tokAt(-2), ", 0 )"))
uselessCallsSubstrError(tok, true); uselessCallsSubstrError(tok, true);
} else if (warning && Token::Match(tok, "[{};] %var% . empty ( ) ;") && } else if (printWarning && Token::Match(tok, "[{};] %var% . empty ( ) ;") &&
tok->next()->variable() && tok->next()->variable()->isStlType(stl_containers_with_empty_and_clear)) tok->next()->variable() && tok->next()->variable()->isStlType(stl_containers_with_empty_and_clear))
uselessCallsEmptyError(tok->next()); uselessCallsEmptyError(tok->next());
else if (Token::Match(tok, "[{};] std :: remove|remove_if|unique (") && tok->tokAt(5)->nextArgument()) else if (Token::Match(tok, "[{};] std :: remove|remove_if|unique (") && tok->tokAt(5)->nextArgument())

View File

@ -100,6 +100,7 @@ static bool astGetSizeSign(const Settings *settings, const Token *tok, unsigned
void CheckType::checkTooBigBitwiseShift() void CheckType::checkTooBigBitwiseShift()
{ {
const bool printWarnings = _settings->isEnabled("warning"); const bool printWarnings = _settings->isEnabled("warning");
const bool printInconclusive = _settings->inconclusive;
// unknown sizeof(int) => can't run this checker // unknown sizeof(int) => can't run this checker
if (_settings->platformType == Settings::Unspecified) if (_settings->platformType == Settings::Unspecified)
@ -138,7 +139,7 @@ void CheckType::checkTooBigBitwiseShift()
continue; continue;
if (value->condition && !printWarnings) if (value->condition && !printWarnings)
continue; continue;
if (value->inconclusive && !_settings->inconclusive) if (value->inconclusive && !printInconclusive)
continue; continue;
tooBigBitwiseShiftError(tok, lhsbits, *value); tooBigBitwiseShiftError(tok, lhsbits, *value);
} }

View File

@ -1203,6 +1203,7 @@ static void conditionAlwaysTrueOrFalse(const Token *tok, const std::map<unsigned
bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn, Alloc* const alloc, const std::string &membervar) bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn, Alloc* const alloc, const std::string &membervar)
{ {
const bool suppressErrors(possibleInit && *possibleInit); const bool suppressErrors(possibleInit && *possibleInit);
const bool printDebug = _settings->debugwarnings;
if (possibleInit) if (possibleInit)
*possibleInit = false; *possibleInit = false;
@ -1282,7 +1283,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
// if (b) return; // cppcheck doesn't know if b can be false when a is false. // if (b) return; // cppcheck doesn't know if b can be false when a is false.
// x++; // it's possible x is always initialized // x++; // it's possible x is always initialized
if (!alwaysTrue && noreturnIf && number_of_if > 0) { if (!alwaysTrue && noreturnIf && number_of_if > 0) {
if (_settings->debugwarnings) { if (printDebug) {
std::string condition; std::string condition;
for (const Token *tok2 = tok->linkAt(-1); tok2 != tok; tok2 = tok2->next()) { for (const Token *tok2 = tok->linkAt(-1); tok2 != tok; tok2 = tok2->next()) {
condition += tok2->str(); condition += tok2->str();
@ -1407,7 +1408,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
if (!forwhile) { if (!forwhile) {
// Assert that the tokens are '} while (' // Assert that the tokens are '} while ('
if (!Token::simpleMatch(tok, "} while (")) { if (!Token::simpleMatch(tok, "} while (")) {
if (_settings->debugwarnings) if (printDebug)
reportError(tok,Severity::debug,"","assertion failed '} while ('"); reportError(tok,Severity::debug,"","assertion failed '} while ('");
break; break;
} }

View File

@ -1217,6 +1217,7 @@ std::list<std::string> Preprocessor::getcfgs(const std::string &filedata, const
unsigned int linenr = 0; unsigned int linenr = 0;
std::istringstream istr(filedata); std::istringstream istr(filedata);
std::string line; std::string line;
const bool printDebug = (_settings && _settings->debugwarnings);
while (std::getline(istr, line)) { while (std::getline(istr, line)) {
++linenr; ++linenr;
@ -1414,7 +1415,7 @@ std::list<std::string> Preprocessor::getcfgs(const std::string &filedata, const
if (!includeStack.top().second) { if (!includeStack.top().second) {
ret.push_back(def); ret.push_back(def);
} else { } else {
if (_errorLogger && _settings && _settings->debugwarnings) { if (_errorLogger && printDebug) {
std::list<ErrorLogger::ErrorMessage::FileLocation> locationList; std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
const ErrorLogger::ErrorMessage errmsg(locationList, Severity::debug, const ErrorLogger::ErrorMessage errmsg(locationList, Severity::debug,
"Configuration not considered: " + def +" for file:"+includeStack.top().first, "debug", false); "Configuration not considered: " + def +" for file:"+includeStack.top().first, "debug", false);
@ -1578,7 +1579,7 @@ std::list<std::string> Preprocessor::getcfgs(const std::string &filedata, const
if (unhandled) { if (unhandled) {
// unhandled ifdef configuration.. // unhandled ifdef configuration..
if (_errorLogger && _settings && _settings->debugwarnings) { if (_errorLogger && printDebug) {
std::list<ErrorLogger::ErrorMessage::FileLocation> locationList; std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
const ErrorLogger::ErrorMessage errmsg(locationList, Severity::debug, "unhandled configuration: " + *it, "debug", false); const ErrorLogger::ErrorMessage errmsg(locationList, Severity::debug, "unhandled configuration: " + *it, "debug", false);
_errorLogger->reportErr(errmsg); _errorLogger->reportErr(errmsg);

View File

@ -44,6 +44,8 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
// Store current access in each scope (depends on evaluation progress) // Store current access in each scope (depends on evaluation progress)
std::map<const Scope*, AccessControl> access; std::map<const Scope*, AccessControl> access;
const bool printDebug =_settings->debugwarnings;
// find all scopes // find all scopes
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok ? tok->next() : nullptr) { for (const Token *tok = _tokenizer->tokens(); tok; tok = tok ? tok->next() : nullptr) {
// #5593 suggested to add here: // #5593 suggested to add here:
@ -996,7 +998,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
} while (unknowns && retry < 100); } while (unknowns && retry < 100);
// this shouldn't happen so output a debug warning // this shouldn't happen so output a debug warning
if (retry == 100 && _settings->debugwarnings) { if (retry == 100 && printDebug) {
for (std::list<Scope>::iterator it = scopeList.begin(); it != scopeList.end(); ++it) { for (std::list<Scope>::iterator it = scopeList.begin(); it != scopeList.end(); ++it) {
scope = &(*it); scope = &(*it);

View File

@ -1189,11 +1189,13 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
if (!tok) if (!tok)
return false; return false;
const bool printDebug = _settings->debugwarnings;
// get the position of the template name // get the position of the template name
int namepos = TemplateSimplifier::getTemplateNamePosition(tok); int namepos = TemplateSimplifier::getTemplateNamePosition(tok);
if (namepos == -1) { if (namepos == -1) {
// debug message that we bail out.. // debug message that we bail out..
if (_settings->debugwarnings && errorlogger) { if (printDebug && errorlogger) {
std::list<const Token *> callstack(1, tok); std::list<const Token *> callstack(1, tok);
errorlogger->reportErr(ErrorLogger::ErrorMessage(callstack, &tokenlist, Severity::debug, "debug", "simplifyTemplates: bailing out", false)); errorlogger->reportErr(ErrorLogger::ErrorMessage(callstack, &tokenlist, Severity::debug, "debug", "simplifyTemplates: bailing out", false));
} }
@ -1270,7 +1272,7 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
templateMatchPattern += ">"; templateMatchPattern += ">";
if (typeForNewName.empty() || typeParametersInDeclaration.size() != typesUsedInTemplateInstantiation.size()) { if (typeForNewName.empty() || typeParametersInDeclaration.size() != typesUsedInTemplateInstantiation.size()) {
if (_settings->debugwarnings && errorlogger) { if (printDebug && errorlogger) {
std::list<const Token *> callstack(1, tok2); std::list<const Token *> callstack(1, tok2);
errorlogger->reportErr(ErrorLogger::ErrorMessage(callstack, &tokenlist, Severity::debug, "debug", errorlogger->reportErr(ErrorLogger::ErrorMessage(callstack, &tokenlist, Severity::debug, "debug",
"Failed to instantiate template \"" + name + "\". The checking continues anyway.", false)); "Failed to instantiate template \"" + name + "\". The checking continues anyway.", false));

View File

@ -6633,6 +6633,7 @@ bool Tokenizer::simplifyKnownVariablesGetData(unsigned int varid, Token **_tok2,
bool Tokenizer::simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, unsigned int varid, const std::string &structname, std::string &value, unsigned int valueVarId, bool valueIsPointer, const Token * const valueToken, int indentlevel) const bool Tokenizer::simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, unsigned int varid, const std::string &structname, std::string &value, unsigned int valueVarId, bool valueIsPointer, const Token * const valueToken, int indentlevel) const
{ {
const bool pointeralias(valueToken->isName() || Token::Match(valueToken, "& %name% [")); const bool pointeralias(valueToken->isName() || Token::Match(valueToken, "& %name% ["));
const bool printDebug = _settings->debugwarnings;
if (_errorLogger && !list.getFiles().empty()) if (_errorLogger && !list.getFiles().empty())
_errorLogger->reportProgress(list.getFiles()[0], "Tokenize (simplifyKnownVariables)", tok3->progressValue()); _errorLogger->reportProgress(list.getFiles()[0], "Tokenize (simplifyKnownVariables)", tok3->progressValue());
@ -6792,7 +6793,7 @@ bool Tokenizer::simplifyKnownVariablesSimplify(Token **tok2, Token *tok3, unsign
if (tok3->varId() == varid) { if (tok3->varId() == varid) {
// This is a really generic bailout so let's try to avoid this. // This is a really generic bailout so let's try to avoid this.
// There might be lots of false negatives. // There might be lots of false negatives.
if (_settings->debugwarnings) { if (printDebug) {
// FIXME: Fix all the debug warnings for values and then // FIXME: Fix all the debug warnings for values and then
// remove this bailout // remove this bailout
if (pointeralias) if (pointeralias)
@ -9636,6 +9637,7 @@ void Tokenizer::simplifyNamespaceStd()
"make_pair", "make_shared", "make_tuple" "make_pair", "make_shared", "make_tuple"
}; };
static const std::set<std::string> stdFunctions(stdFunctions_, stdFunctions_+sizeof(stdFunctions_)/sizeof(*stdFunctions_)); static const std::set<std::string> stdFunctions(stdFunctions_, stdFunctions_+sizeof(stdFunctions_)/sizeof(*stdFunctions_));
const bool isCPP11 = _settings->standards.cpp == Standards::CPP11;
for (const Token* tok = Token::findsimplematch(list.front(), "using namespace std ;"); tok; tok = tok->next()) { for (const Token* tok = Token::findsimplematch(list.front(), "using namespace std ;"); tok; tok = tok->next()) {
bool insert = false; bool insert = false;
@ -9653,12 +9655,12 @@ void Tokenizer::simplifyNamespaceStd()
tok->previous()->insertToken("::"); tok->previous()->insertToken("::");
} }
else if (_settings->standards.cpp == Standards::CPP11 && Token::Match(tok, "!!:: tr1 ::")) else if (isCPP11 && Token::Match(tok, "!!:: tr1 ::"))
tok->next()->str("std"); tok->next()->str("std");
} }
for (Token* tok = list.front(); tok; tok = tok->next()) { for (Token* tok = list.front(); tok; tok = tok->next()) {
if (_settings->standards.cpp == Standards::CPP11 && Token::simpleMatch(tok, "std :: tr1 ::")) if (isCPP11 && Token::simpleMatch(tok, "std :: tr1 ::"))
Token::eraseTokens(tok, tok->tokAt(3)); Token::eraseTokens(tok, tok->tokAt(3));
else if (Token::simpleMatch(tok, "using namespace std ;")) { else if (Token::simpleMatch(tok, "using namespace std ;")) {