diff --git a/cfg/qt.cfg b/cfg/qt.cfg
index 69bc205a316..8c2d34073b0 100644
--- a/cfg/qt.cfg
+++ b/cfg/qt.cfg
@@ -5236,12 +5236,12 @@
QApplication
QMutexLocker
- QRectF
- QSizeF
- QPointF
QRect
+ QRectF
QSize
+ QSizeF
QPoint
+ QPointF
QRegion
diff --git a/cfg/windows.cfg b/cfg/windows.cfg
index f690a83a1aa..05c31803fbc 100644
--- a/cfg/windows.cfg
+++ b/cfg/windows.cfg
@@ -4907,6 +4907,8 @@ HFONT CreateFont(
+
+
false
diff --git a/cfg/wxwidgets.cfg b/cfg/wxwidgets.cfg
index dd42c600bd1..a5a3b3242b8 100644
--- a/cfg/wxwidgets.cfg
+++ b/cfg/wxwidgets.cfg
@@ -5,6 +5,8 @@
wxRect
wxSize
wxPoint
+ wxPoint2DInt
+ wxPoint2DDouble
wxRealPoint
wxVersionInfo
wxRegion
diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp
index 7f275ab00df..59cf67847fa 100644
--- a/cli/cmdlineparser.cpp
+++ b/cli/cmdlineparser.cpp
@@ -1071,44 +1071,57 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
// Rule file
else if (std::strncmp(argv[i], "--rule-file=", 12) == 0) {
#ifdef HAVE_RULES
- // TODO: improved error handling - unknown elements, wrong root node, etc.
+ // TODO: improved error handling - wrong root node, etc.
+ // TODO: consume unused "version" attribute
const std::string ruleFile = argv[i] + 12;
tinyxml2::XMLDocument doc;
const tinyxml2::XMLError err = doc.LoadFile(ruleFile.c_str());
if (err == tinyxml2::XML_SUCCESS) {
const tinyxml2::XMLElement *node = doc.FirstChildElement();
- // TODO: this looks like legacy handling - deprecate it
+ // check if it is a single or multi rule configuration
if (node && strcmp(node->Value(), "rules") == 0)
node = node->FirstChildElement("rule");
for (; node && strcmp(node->Value(), "rule") == 0; node = node->NextSiblingElement()) {
Settings::Rule rule;
- const tinyxml2::XMLElement *tokenlist = node->FirstChildElement("tokenlist");
- if (tokenlist)
- rule.tokenlist = tokenlist->GetText();
-
- const tinyxml2::XMLElement *pattern = node->FirstChildElement("pattern");
- if (pattern) {
- rule.pattern = pattern->GetText();
+ for (const tinyxml2::XMLElement *subnode = node->FirstChildElement(); subnode; subnode = subnode->NextSiblingElement()) {
+ const char * const subtext = subnode->GetText();
+ if (std::strcmp(subnode->Name(), "tokenlist") == 0) {
+ rule.tokenlist = empty_if_null(subtext);
+ }
+ else if (std::strcmp(subnode->Name(), "pattern") == 0) {
+ rule.pattern = empty_if_null(subtext);
+ }
+ else if (std::strcmp(subnode->Name(), "message") == 0) {
+ for (const tinyxml2::XMLElement *msgnode = subnode->FirstChildElement(); msgnode; msgnode = msgnode->NextSiblingElement()) {
+ const char * const msgtext = msgnode->GetText();
+ if (std::strcmp(msgnode->Name(), "severity") == 0) {
+ rule.severity = severityFromString(empty_if_null(msgtext));
+ }
+ else if (std::strcmp(msgnode->Name(), "id") == 0) {
+ rule.id = empty_if_null(msgtext);
+ }
+ else if (std::strcmp(msgnode->Name(), "summary") == 0) {
+ rule.summary = empty_if_null(msgtext);
+ }
+ else {
+ mLogger.printError("unable to load rule-file '" + ruleFile + "' - unknown element '" + msgnode->Name() + "' encountered in 'message'.");
+ return Result::Fail;
+ }
+ }
+ }
+ else {
+ mLogger.printError("unable to load rule-file '" + ruleFile + "' - unknown element '" + subnode->Name() + "' encountered in 'rule'.");
+ return Result::Fail;
+ }
}
- const tinyxml2::XMLElement *message = node->FirstChildElement("message");
- if (message) {
- const tinyxml2::XMLElement *severity = message->FirstChildElement("severity");
- if (severity)
- rule.severity = severityFromString(severity->GetText());
-
- const tinyxml2::XMLElement *id = message->FirstChildElement("id");
- if (id)
- rule.id = id->GetText();
-
- const tinyxml2::XMLElement *summary = message->FirstChildElement("summary");
- if (summary)
- rule.summary = summary->GetText() ? summary->GetText() : "";
+ if (rule.pattern.empty()) {
+ mLogger.printError("unable to load rule-file '" + ruleFile + "' - a rule is lacking a pattern.");
+ return Result::Fail;
}
- if (!rule.pattern.empty())
- mSettings.rules.emplace_back(std::move(rule));
+ mSettings.rules.emplace_back(std::move(rule));
}
} else {
mLogger.printError("unable to load rule-file '" + ruleFile + "' (" + tinyxml2::XMLDocument::ErrorIDToName(err) + ").");
diff --git a/lib/checkother.cpp b/lib/checkother.cpp
index 331cb03be27..beff6996668 100644
--- a/lib/checkother.cpp
+++ b/lib/checkother.cpp
@@ -944,6 +944,9 @@ void CheckOther::checkVariableScope()
if (!var || !var->isLocal() || var->isConst())
continue;
+ if (var->nameToken()->isExpandedMacro())
+ continue;
+
const bool isPtrOrRef = var->isPointer() || var->isReference();
const bool isSimpleType = var->typeStartToken()->isStandardType() || var->typeStartToken()->isEnumType() || (var->typeStartToken()->isC() && var->type() && var->type()->isStructType());
if (!isPtrOrRef && !isSimpleType && !astIsContainer(var->nameToken()))
@@ -1824,7 +1827,7 @@ static bool isConstant(const Token* tok) {
return tok && (tok->isEnumerator() || Token::Match(tok, "%bool%|%num%|%str%|%char%|nullptr|NULL"));
}
-static bool isConstStatement(const Token *tok)
+static bool isConstStatement(const Token *tok, bool isNestedBracket = false)
{
if (!tok)
return false;
@@ -1875,9 +1878,13 @@ static bool isConstStatement(const Token *tok)
if (Token::simpleMatch(tok, "?") && Token::simpleMatch(tok->astOperand2(), ":")) // ternary operator
return isConstStatement(tok->astOperand1()) && isConstStatement(tok->astOperand2()->astOperand1()) && isConstStatement(tok->astOperand2()->astOperand2());
if (isBracketAccess(tok) && isWithoutSideEffects(tok->astOperand1(), /*checkArrayAccess*/ true, /*checkReference*/ false)) {
- if (Token::simpleMatch(tok->astParent(), "["))
- return isConstStatement(tok->astOperand2()) && isConstStatement(tok->astParent());
- return isConstStatement(tok->astOperand2());
+ const bool isChained = succeeds(tok->astParent(), tok);
+ if (Token::simpleMatch(tok->astParent(), "[")) {
+ if (isChained)
+ return isConstStatement(tok->astOperand2()) && isConstStatement(tok->astParent());
+ return isNestedBracket && isConstStatement(tok->astOperand2());
+ }
+ return isConstStatement(tok->astOperand2(), /*isNestedBracket*/ !isChained);
}
return false;
}
diff --git a/lib/checktype.cpp b/lib/checktype.cpp
index 0cc91ac8976..df30f929601 100644
--- a/lib/checktype.cpp
+++ b/lib/checktype.cpp
@@ -299,7 +299,7 @@ void CheckType::signConversionError(const Token *tok, const ValueFlow::Value *ne
//---------------------------------------------------------------------------
// Checking for long cast of int result const long x = var1 * var2;
//---------------------------------------------------------------------------
-static bool checkTypeCombination(const ValueType& src, const ValueType& tgt, const Settings& settings)
+static bool checkTypeCombination(ValueType src, ValueType tgt, const Settings& settings)
{
static const std::pair typeCombinations[] = {
{ ValueType::Type::INT, ValueType::Type::LONG },
@@ -310,6 +310,9 @@ static bool checkTypeCombination(const ValueType& src, const ValueType& tgt, con
{ ValueType::Type::DOUBLE, ValueType::Type::LONGDOUBLE },
};
+ src.reference = Reference::None;
+ tgt.reference = Reference::None;
+
const std::size_t sizeSrc = ValueFlow::getSizeOf(src, settings);
const std::size_t sizeTgt = ValueFlow::getSizeOf(tgt, settings);
if (!(sizeSrc > 0 && sizeTgt > 0 && sizeSrc < sizeTgt))
diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp
index 7d7ccd7b023..15f989d8a99 100644
--- a/lib/checkunusedvar.cpp
+++ b/lib/checkunusedvar.cpp
@@ -713,10 +713,12 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
type = Variables::pointer;
else if (mTokenizer->isC() ||
i->typeEndToken()->isStandardType() ||
+ i->isStlType() ||
isRecordTypeWithoutSideEffects(i->type()) ||
mSettings->library.detectContainer(i->typeStartToken()) ||
- i->isStlType())
+ mSettings->library.getTypeCheck("unusedvar", i->typeStartToken()->str()) == Library::TypeCheck::check)
type = Variables::standard;
+
if (type == Variables::none || isPartOfClassStructUnion(i->typeStartToken()))
continue;
const Token* defValTok = i->nameToken()->next();
@@ -1007,7 +1009,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
// assignment
else if ((Token::Match(tok, "%name% [") && Token::simpleMatch(skipBracketsAndMembers(tok->next()), "=")) ||
- (tok->isUnaryOp("*") && Token::simpleMatch(tok->astParent(), "=") && Token::simpleMatch(tok->astOperand1(), "+"))) {
+ (tok->isUnaryOp("*") && astIsLHS(tok) && Token::simpleMatch(tok->astParent(), "=") && Token::simpleMatch(tok->astOperand1(), "+"))) {
const Token *eq = tok;
while (eq && !eq->isAssignmentOp())
eq = eq->astParent();
@@ -1199,8 +1201,9 @@ void CheckUnusedVar::checkFunctionVariableUsage()
if (!isAssignment && !isInitialization && !isIncrementOrDecrement)
continue;
+ bool isTrivialInit = false;
if (isInitialization && Token::Match(tok, "%var% { }")) // don't warn for trivial initialization
- continue;
+ isTrivialInit = true;
if (isIncrementOrDecrement && tok->astParent() && precedes(tok, tok->astOperand1()))
continue;
@@ -1306,6 +1309,8 @@ void CheckUnusedVar::checkFunctionVariableUsage()
reportLibraryCfgError(tok, bailoutTypeName);
continue;
}
+ if (isTrivialInit && findExpressionChanged(expr, start, scopeEnd, mSettings))
+ continue;
// warn
if (!expr->variable() || !expr->variable()->isMaybeUnused())
diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp
index 9d719cfaafa..2d85f117a17 100644
--- a/lib/tokenize.cpp
+++ b/lib/tokenize.cpp
@@ -4251,7 +4251,7 @@ static bool setVarIdParseDeclaration(Token** tok, const VariableMap& variableMap
bracket = true;
} else if (tok2->str() == "::") {
singleNameCount = 0;
- } else if (tok2->str() != "*" && tok2->str() != "::" && tok2->str() != "...") {
+ } else if (tok2->str() != "*" && tok2->str() != "...") {
break;
}
tok2 = tok2->next();
@@ -4826,7 +4826,8 @@ void Tokenizer::setVarIdPass1()
// function declaration inside executable scope? Function declaration is of form: type name "(" args ")"
if (scopeStack.top().isExecutable && Token::Match(tok, "%name% [,)[]")) {
bool par = false;
- const Token *start, *end;
+ const Token* start;
+ Token* end;
// search begin of function declaration
for (start = tok; Token::Match(start, "%name%|*|&|,|("); start = start->previous()) {
@@ -4850,9 +4851,11 @@ void Tokenizer::setVarIdPass1()
const bool isNotstartKeyword = start->next() && notstart.find(start->next()->str()) != notstart.end();
// now check if it is a function declaration
- if (Token::Match(start, "[;{}] %type% %name%|*") && par && Token::simpleMatch(end, ") ;") && !isNotstartKeyword)
+ if (Token::Match(start, "[;{}] %type% %name%|*") && par && Token::simpleMatch(end, ") ;") && !isNotstartKeyword) {
// function declaration => don't set varid
+ tok = end;
continue;
+ }
}
if ((!scopeStack.top().isEnum || !(Token::Match(tok->previous(), "{|,") && Token::Match(tok->next(), ",|=|}"))) &&
@@ -8583,9 +8586,12 @@ void Tokenizer::findGarbageCode() const
bool match1 = Token::Match(tok, "%or%|%oror%|==|!=|+|-|/|!|>=|<=|~|^|++|--|::|sizeof");
bool match2 = Token::Match(tok->next(), "{|if|else|while|do|for|return|switch|break");
if (isCPP()) {
- match1 = match1 || Token::Match(tok, "::|throw|decltype|typeof");
+ match1 = match1 || Token::Match(tok, "throw|decltype|typeof");
match2 = match2 || Token::Match(tok->next(), "try|catch|namespace");
}
+ if (match1 && !tok->isIncDecOp()) {
+ match2 = match2 || Token::Match(tok->next(), "%assign%");
+ }
if (match1 && match2)
syntaxError(tok);
}
@@ -8635,6 +8641,8 @@ void Tokenizer::findGarbageCode() const
syntaxError(tok);
if (Token::Match(tok, "==|!=|<=|>= %comp%") && tok->strAt(-1) != "operator")
syntaxError(tok, tok->str() + " " + tok->strAt(1));
+ if (Token::simpleMatch(tok, ":: ::"))
+ syntaxError(tok);
}
// ternary operator without :
diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp
index 5e9017eb487..af8d20e17d8 100644
--- a/lib/tokenlist.cpp
+++ b/lib/tokenlist.cpp
@@ -1758,7 +1758,10 @@ static Token * createAstAtToken(Token *tok)
void TokenList::createAst() const
{
for (Token *tok = mTokensFrontBack.front; tok; tok = tok ? tok->next() : nullptr) {
- tok = createAstAtToken(tok);
+ Token* const nextTok = createAstAtToken(tok);
+ if (precedes(nextTok, tok))
+ throw InternalError(tok, "Syntax Error: Infinite loop when creating AST.", InternalError::AST);
+ tok = nextTok;
}
}
diff --git a/lib/utils.h b/lib/utils.h
index 481d9e890b3..22b511c90c8 100644
--- a/lib/utils.h
+++ b/lib/utils.h
@@ -361,4 +361,10 @@ namespace cppcheck
}
}
+template
+static inline T* empty_if_null(T* p)
+{
+ return p ? p : "";
+}
+
#endif
diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp
index 5a3833419b0..aa194ea1727 100644
--- a/lib/valueflow.cpp
+++ b/lib/valueflow.cpp
@@ -4972,6 +4972,8 @@ static void valueFlowLifetime(TokenList &tokenlist, ErrorLogger *errorLogger, co
}
// address of
else if (tok->isUnaryOp("&")) {
+ if (Token::simpleMatch(tok->astParent(), "*"))
+ continue;
for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(tok->astOperand1())) {
if (!settings.certainty.isEnabled(Certainty::inconclusive) && lt.inconclusive)
continue;
@@ -5334,16 +5336,19 @@ static const Scope* getLoopScope(const Token* tok)
//
static void valueFlowConditionExpressions(const TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger *errorLogger, const Settings &settings)
{
- if (settings.checkLevel == Settings::CheckLevel::normal)
+ if (!settings.daca && (settings.checkLevel == Settings::CheckLevel::normal))
return;
for (const Scope * scope : symboldatabase.functionScopes) {
if (const Token* incompleteTok = findIncompleteVar(scope->bodyStart, scope->bodyEnd)) {
if (settings.debugwarnings)
bailoutIncompleteVar(tokenlist, errorLogger, incompleteTok, "Skipping function due to incomplete variable " + incompleteTok->str());
- break;
+ continue;
}
+ if (settings.daca && (settings.checkLevel == Settings::CheckLevel::normal))
+ continue;
+
for (Token* tok = const_cast(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
if (!Token::simpleMatch(tok, "if ("))
continue;
diff --git a/releasenotes.txt b/releasenotes.txt
index 65c9e9ef90a..f68333b7075 100644
--- a/releasenotes.txt
+++ b/releasenotes.txt
@@ -24,4 +24,6 @@ Other:
- Removed deprecated platform type 'Unspecified'. Please use 'unspecified' instead.
- Removed deprecated 'Makefile' option 'SRCDIR'.
- Added CMake option 'DISALLOW_THREAD_EXECUTOR' to control the inclusion of the executor which performs the analysis within a thread of the main process.
-- Removed CMake option 'USE_THREADS' in favor of 'DISALLOW_THREAD_EXECUTOR'.
\ No newline at end of file
+- Removed CMake option 'USE_THREADS' in favor of 'DISALLOW_THREAD_EXECUTOR'.
+- Fixed crash with '--rule-file=' if some data was missing.
+- '--rule-file' will now bail out if a rule could not be added or a file contains unexpected data.
\ No newline at end of file
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 4ec673ba152..a92ef8ed166 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -115,7 +115,6 @@ if (BUILD_TESTS)
else()
# TODO: remove missingInclude disabling when it no longer is implied by --enable=information
# TODO: add syntax check
- # need to suppress unmatchedSuppression in case valueFlowBailout is not reported
add_test(NAME cfg-${TEST_NAME}
COMMAND $
--library=${LIBRARY}
@@ -129,9 +128,7 @@ if (BUILD_TESTS)
--disable=missingInclude
--inline-suppr
--debug-warnings
- --suppress=valueFlowBailout
- --suppress=purgedConfiguration
- --suppress=unmatchedSuppression
+ --suppress=checkersReport
${CMAKE_CURRENT_SOURCE_DIR}/cfg/${CFG_TEST}
)
endif()
diff --git a/test/cfg/boost.cpp b/test/cfg/boost.cpp
index d2e19fbd2b1..d68d5a7f262 100644
--- a/test/cfg/boost.cpp
+++ b/test/cfg/boost.cpp
@@ -7,6 +7,8 @@
// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0
//
+// cppcheck-suppress-file valueFlowBailout
+
#include
#include
#include
diff --git a/test/cfg/bsd.c b/test/cfg/bsd.c
index 734a97fe4aa..6652129c553 100644
--- a/test/cfg/bsd.c
+++ b/test/cfg/bsd.c
@@ -6,6 +6,8 @@
// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0
//
+// cppcheck-suppress-file valueFlowBailout
+
#include
#include
#include
diff --git a/test/cfg/cppunit.cpp b/test/cfg/cppunit.cpp
index 28b7fa7a858..1eaf0b66628 100644
--- a/test/cfg/cppunit.cpp
+++ b/test/cfg/cppunit.cpp
@@ -6,6 +6,8 @@
// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0
//
+// cppcheck-suppress-file valueFlowBailout
+
#include
void cppunit_assert_equal(int x, double y)
diff --git a/test/cfg/gnu.c b/test/cfg/gnu.c
index a259215153b..296a3cc0442 100644
--- a/test/cfg/gnu.c
+++ b/test/cfg/gnu.c
@@ -7,6 +7,8 @@
// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0
//
+// cppcheck-suppress-file valueFlowBailout
+
#include
#include
#include
@@ -387,6 +389,7 @@ void memleak_xmalloc()
void memleak_mmap()
{
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
const void * p_mmap = mmap(NULL, 1, PROT_NONE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
printf("%p", p_mmap);
// cppcheck-suppress memleak
@@ -466,6 +469,7 @@ int nullPointer_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
// Remove (deregister) the target file descriptor fd from the
// epoll instance referred to by epfd. The event is ignored and
// can be NULL.
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
return epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);
}
#endif
diff --git a/test/cfg/googletest.cpp b/test/cfg/googletest.cpp
index cc4c1415ae6..c13db34967a 100644
--- a/test/cfg/googletest.cpp
+++ b/test/cfg/googletest.cpp
@@ -7,6 +7,8 @@
// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0
//
+// cppcheck-suppress-file valueFlowBailout
+
#include
#include
@@ -50,6 +52,7 @@ TEST(test_cppcheck, cppcheck)
// #9964 - avoid compareBoolExpressionWithInt false positive
TEST(Test, assert_false_fp)
{
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
ASSERT_FALSE(errno < 0);
}
@@ -73,6 +76,7 @@ TEST(Test, warning_in_assert_macros)
// cppcheck-suppress duplicateExpression
ASSERT_GE(i, i);
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
unsigned int u = errno;
// cppcheck-suppress [unsignedPositive]
ASSERT_GE(u, 0);
diff --git a/test/cfg/gtk.c b/test/cfg/gtk.c
index 66aa875b229..6d8b2258a91 100644
--- a/test/cfg/gtk.c
+++ b/test/cfg/gtk.c
@@ -302,6 +302,7 @@ void g_new0_test()
int b;
};
// valid
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
struct a * pNew1 = g_new0(struct a, 5);
printf("%p", pNew1);
g_free(pNew1);
@@ -320,6 +321,7 @@ void g_try_new_test()
int b;
};
// valid
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
struct a * pNew1 = g_try_new(struct a, 5);
printf("%p", pNew1);
g_free(pNew1);
@@ -337,6 +339,7 @@ void g_try_new0_test()
int b;
};
// valid
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
struct a * pNew1 = g_try_new0(struct a, 5);
printf("%p", pNew1);
g_free(pNew1);
@@ -354,7 +357,7 @@ void g_renew_test()
struct a {
int b;
};
- // cppcheck-suppress leakReturnValNotUsed
+ // cppcheck-suppress [leakReturnValNotUsed,valueFlowBailoutIncompleteVar]
g_renew(struct a, NULL, 1);
struct a * pNew = g_new(struct a, 1);
@@ -369,7 +372,7 @@ void g_try_renew_test()
struct a {
int b;
};
- // cppcheck-suppress leakReturnValNotUsed
+ // cppcheck-suppress [leakReturnValNotUsed,valueFlowBailoutIncompleteVar]
g_try_renew(struct a, NULL, 1);
struct a * pNew = g_try_new(struct a, 1);
diff --git a/test/cfg/libcurl.c b/test/cfg/libcurl.c
index 8c494494a03..9e91eefcc5c 100644
--- a/test/cfg/libcurl.c
+++ b/test/cfg/libcurl.c
@@ -7,6 +7,8 @@
// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0
//
+// cppcheck-suppress-file valueFlowBailout
+
#include
#include
diff --git a/test/cfg/opencv2.cpp b/test/cfg/opencv2.cpp
index 6667785ef4e..de0f3731b81 100644
--- a/test/cfg/opencv2.cpp
+++ b/test/cfg/opencv2.cpp
@@ -7,6 +7,8 @@
// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0
//
+// cppcheck-suppress-file valueFlowBailout
+
#include
#include
@@ -43,7 +45,7 @@ void memleak()
{
// cppcheck-suppress cstyleCast
const char * pBuf = (char *)cv::fastMalloc(1000);
- // cppcheck-suppress uninitdata
+ // cppcheck-suppress [uninitdata, valueFlowBailoutIncompleteVar]
std::cout << pBuf;
// cppcheck-suppress memleak
}
diff --git a/test/cfg/posix.c b/test/cfg/posix.c
index c2a78fbdc1b..b4b8c9e4985 100644
--- a/test/cfg/posix.c
+++ b/test/cfg/posix.c
@@ -7,6 +7,8 @@
// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0
//
+// cppcheck-suppress-file [valueFlowBailout,purgedConfiguration]
+
#define _BSD_SOURCE
#include
@@ -1062,6 +1064,7 @@ void * memleak_mmap2() // #8327
void memleak_getline() { // #11043
char *line = NULL;
size_t size = 0;
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
getline(&line, &size, stdin);
// cppcheck-suppress memleak
line = NULL;
@@ -1082,6 +1085,7 @@ void memleak_getline_array(FILE* stream) { // #12498
void memleak_getdelim(int delim) {
char *line = NULL;
size_t size = 0;
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
getdelim(&line, &size, delim, stdin);
// cppcheck-suppress memleak
line = NULL;
@@ -1101,6 +1105,7 @@ void memleak_getdelim_array(FILE* stream, int delim) {
void * identicalCondition_mmap(int fd, size_t size) // #9940
{
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
void* buffer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (buffer == MAP_FAILED) {
return NULL;
@@ -1113,6 +1118,7 @@ int munmap_no_double_free(int tofd, // #11396
size_t len)
{
int rc;
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
const void* fptr = mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,fromfd,(off_t)0);
if (fptr == MAP_FAILED) {
return -1;
@@ -1147,6 +1153,7 @@ void resourceLeak_fdopen(int fd)
void resourceLeak_fdopen2(const char* fn) // #2767
{
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
int fi = open(fn, O_RDONLY);
FILE* fd = fdopen(fi, "r");
fclose(fd);
@@ -1193,14 +1200,14 @@ void resourceLeak_socket(void)
void resourceLeak_open1(void)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress [unreadVariable,valueFlowBailoutIncompleteVar]
int fd = open("file", O_RDWR | O_CREAT);
// cppcheck-suppress resourceLeak
}
void resourceLeak_open2(void)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress [unreadVariable,valueFlowBailoutIncompleteVar]
int fd = open("file", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
// cppcheck-suppress resourceLeak
}
@@ -1213,6 +1220,7 @@ void noleak(int x, int y, int z)
closedir(p2);
int s = socket(AF_INET,SOCK_STREAM,0);
close(s);
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
int fd1 = open("a", O_RDWR | O_CREAT);
close(fd1);
int fd2 = open("a", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
@@ -1357,7 +1365,7 @@ void timet_h(const struct timespec* ptp1)
clockid_t clk_id1, clk_id2, clk_id3;
// cppcheck-suppress constVariablePointer
struct timespec* ptp;
- // cppcheck-suppress uninitvar
+ // cppcheck-suppress [uninitvar,valueFlowBailoutIncompleteVar]
clock_settime(CLOCK_REALTIME, ptp);
// cppcheck-suppress uninitvar
clock_settime(clk_id1, ptp);
diff --git a/test/cfg/qt.cpp b/test/cfg/qt.cpp
index 5fcb803e372..d4350cea827 100644
--- a/test/cfg/qt.cpp
+++ b/test/cfg/qt.cpp
@@ -7,6 +7,8 @@
// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0
//
+// cppcheck-suppress-file valueFlowBailout
+
#include
#include
#include
@@ -23,19 +25,19 @@
#include
#include
#include
-#include
-#include
-#include
-#include
#include
+#include
#include
+#include
#include
+#include
+#include
#include
void unreadVariable_QRegion(const int x, const QRegion::RegionType type, const QPolygon &polygon, const QBitmap &bm, const QRegion ®ion, const Qt::FillRule fillRule)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
QRegion a;
// cppcheck-suppress unreadVariable
QRegion b{};
@@ -53,7 +55,7 @@ void unreadVariable_QRegion(const int x, const QRegion::RegionType type, const Q
void unreadVariable_QPoint(const QPoint &s)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
QPoint a;
// cppcheck-suppress unreadVariable
QPoint b{};
@@ -67,7 +69,7 @@ void unreadVariable_QPoint(const QPoint &s)
void unreadVariable_QPointF(const QPointF &s)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
QPointF a;
// cppcheck-suppress unreadVariable
QPointF b{};
@@ -81,7 +83,7 @@ void unreadVariable_QPointF(const QPointF &s)
void unreadVariable_QSizeF(const QSize &s)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
QSizeF a;
// cppcheck-suppress unreadVariable
QSizeF b{};
@@ -95,7 +97,7 @@ void unreadVariable_QSizeF(const QSize &s)
void unreadVariable_QSize(const QSize &s)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
QSize a;
// cppcheck-suppress unreadVariable
QSize b{};
@@ -108,7 +110,7 @@ void unreadVariable_QSize(const QSize &s)
}
void unreadVariable_QRect(const QPoint &topLeft, const QSize &size, const QPoint &bottomRight, const int x) {
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
QRect a;
// cppcheck-suppress unreadVariable
QRect b{};
@@ -123,7 +125,7 @@ void unreadVariable_QRect(const QPoint &topLeft, const QSize &size, const QPoint
}
void unreadVariable_QRectF(const QPointF &topLeft, const QSizeF &size, const QPointF &bottomRight, const QRectF &rect, const qreal x) {
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
QRectF a;
// cppcheck-suppress unreadVariable
QRectF b{};
@@ -576,7 +578,7 @@ void validCode(int * pIntPtr, QString & qstrArg, double d)
printf(QT_TR_NOOP("Hi"));
- // cppcheck-suppress checkLibraryFunction
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
Q_DECLARE_LOGGING_CATEGORY(logging_category_test);
QT_FORWARD_DECLARE_CLASS(forwardDeclaredClass);
QT_FORWARD_DECLARE_STRUCT(forwardDeclaredStruct);
diff --git a/test/cfg/runtests.sh b/test/cfg/runtests.sh
index 744d9aa7284..5b4fa1dd6fd 100755
--- a/test/cfg/runtests.sh
+++ b/test/cfg/runtests.sh
@@ -27,7 +27,7 @@ CFG="$DIR"../../cfg/
# TODO: remove missingInclude disabling when it no longer is implied by --enable=information
# Cppcheck options
# need to suppress unmatchedSuppression in case valueFlowBailout is not reported
-CPPCHECK_OPT='--check-library --platform=unix64 --enable=style,information --inconclusive --force --check-level=exhaustive --error-exitcode=-1 --disable=missingInclude --inline-suppr --template="{file}:{line}:{severity}:{id}:{message}" --debug-warnings --suppress=valueFlowBailout --suppress=purgedConfiguration --suppress=unmatchedSuppression'
+CPPCHECK_OPT='--check-library --platform=unix64 --enable=style,information --inconclusive --force --check-level=exhaustive --error-exitcode=-1 --disable=missingInclude --inline-suppr --template="{file}:{line}:{severity}:{id}:{message}" --debug-warnings --suppress=checkersReport'
# Compiler settings
CXX=g++
diff --git a/test/cfg/std.c b/test/cfg/std.c
index 9f2a0d213cf..f795cdc5bda 100644
--- a/test/cfg/std.c
+++ b/test/cfg/std.c
@@ -7,6 +7,8 @@
// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0
//
+// cppcheck-suppress-file valueFlowBailout
+
#include
#include
#include
@@ -401,6 +403,7 @@ void nullpointer(int value)
fp = 0;
// No FP
fflush(0); // If stream is a null pointer, all streams are flushed.
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
fp = freopen(0,"abc",stdin);
fclose(fp);
fp = NULL;
@@ -732,6 +735,7 @@ void uninitvar_fgets(void)
char *str;
int n;
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
fgets(buf,10,stdin);
// cppcheck-suppress uninitvar
@@ -749,6 +753,7 @@ void uninitvar_fputc(void)
int i;
FILE *fp;
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
fputc('a', stdout);
// cppcheck-suppress uninitvar
@@ -763,6 +768,7 @@ void uninitvar_fputs(void)
const char *s;
FILE *fp;
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
fputs("a", stdout);
// cppcheck-suppress uninitvar
@@ -3456,6 +3462,7 @@ void invalidFunctionArg_log10(float f, double d, const long double ld)
(void)log10f(0.0f);
(void)log10f(1.4013e-45f); // note: calculated by nextafterf(0.0f, 1.0f);
(void)log10f(f);
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
(void)log10f(FLT_MAX);
// cppcheck-suppress invalidFunctionArg
@@ -3480,6 +3487,7 @@ void invalidFunctionArg_log(float f, double d, const long double ld)
(void)logf(0.0f);
(void)logf(1.4013e-45f); // note: calculated by nextafterf(0.0f, 1.0f);
(void)logf(f);
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
(void)logf(FLT_MAX);
// cppcheck-suppress invalidFunctionArg
@@ -3504,6 +3512,7 @@ void invalidFunctionArg_log2(float f, double d, const long double ld)
(void)log2f(0.0f);
(void)log2f(1.4013e-45f); // note: calculated by nextafterf(0.0f, 1.0f);
(void)log2f(f);
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
(void)log2f(FLT_MAX);
// cppcheck-suppress invalidFunctionArg
@@ -4973,6 +4982,7 @@ void invalidPrintfArgType_printf(void)
// #7016
uint8_t n = 7;
// TODO cppcheck-suppress invalidPrintfArgType_uint
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
printf("%" PRIi16 "\n", n);
}
diff --git a/test/cfg/std.cpp b/test/cfg/std.cpp
index 0438ea39487..a8a0f018c4e 100644
--- a/test/cfg/std.cpp
+++ b/test/cfg/std.cpp
@@ -7,6 +7,8 @@
// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0
//
+// cppcheck-suppress-file valueFlowBailout
+
#include
#include
#include
@@ -662,8 +664,10 @@ void memleak_localtime_s(const std::time_t *restrict time, struct tm *restrict r
{
const time_t t = time(0);
const struct tm* const now = new tm();
- if (localtime_s(now, &t) == 0)
+ if (localtime_s(now, &t) == 0) {
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
std::cout << now->tm_mday << std::endl;
+ }
// cppcheck-suppress memleak
}
#endif // __STDC_LIB_EXT1__
@@ -706,6 +710,7 @@ void invalidFunctionArg_std_wstring_substr(const std::wstring &str, std::size_t
(void)str.substr(pos,-1);
// no warning is expected for
(void)str.substr(pos,len);
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
(void)str.substr(pos, std::wstring::npos);
}
@@ -2469,21 +2474,21 @@ void uninitvar_ldexp(void)
void invalidFunctionArg_lgamma(float f, double d, long double ld)
{
(void)lgamma(d);
- // cppcheck-suppress invalidFunctionArg
+ // TODO cppcheck-suppress invalidFunctionArg
(void)lgamma(-0.1);
// cppcheck-suppress invalidFunctionArg
(void)lgamma(0.0);
(void)lgamma(0.1);
(void)lgammaf(f);
- // cppcheck-suppress invalidFunctionArg
+ // TODO cppcheck-suppress invalidFunctionArg
(void)lgammaf(-0.1f);
// cppcheck-suppress invalidFunctionArg
(void)lgammaf(0.0f);
(void)lgammaf(0.1f);
(void)lgammal(ld);
- // cppcheck-suppress invalidFunctionArg
+ // TODO cppcheck-suppress invalidFunctionArg
(void)lgammal(-0.1L);
// cppcheck-suppress invalidFunctionArg
(void)lgammal(0.0L);
@@ -2493,21 +2498,21 @@ void invalidFunctionArg_lgamma(float f, double d, long double ld)
void invalidFunctionArg_tgamma(float f, double d, long double ld)
{
(void)tgamma(d);
- // cppcheck-suppress invalidFunctionArg
+ // TODO cppcheck-suppress invalidFunctionArg
(void)tgamma(-0.1);
// cppcheck-suppress invalidFunctionArg
(void)tgamma(0.0);
(void)tgamma(0.1);
(void)tgammaf(f);
- // cppcheck-suppress invalidFunctionArg
+ // TODO cppcheck-suppress invalidFunctionArg
(void)tgammaf(-0.1f);
// cppcheck-suppress invalidFunctionArg
(void)tgammaf(0.0f);
(void)tgammaf(0.1f);
(void)tgammal(ld);
- // cppcheck-suppress invalidFunctionArg
+ // TODO cppcheck-suppress invalidFunctionArg
(void)tgammal(-0.1L);
// cppcheck-suppress invalidFunctionArg
(void)tgammal(0.0L);
@@ -4256,7 +4261,7 @@ void nullPointer_system(const char *c)
void uninitvar_setw(void)
{
int i;
- // cppcheck-suppress uninitvar
+ // cppcheck-suppress [uninitvar,valueFlowBailoutIncompleteVar]
std::cout << std::setw(i);
}
@@ -4264,6 +4269,7 @@ void uninitvar_setiosflags(void)
{
std::ios_base::fmtflags mask;
// TODO cppcheck-suppress uninitvar
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
std::cout << std::setiosflags(mask); // #6987 - false negative
}
@@ -4271,13 +4277,14 @@ void uninitvar_resetiosflags(void)
{
std::ios_base::fmtflags mask;
// TODO cppcheck-suppress uninitvar
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
std::cout << std::resetiosflags(mask); // #6987 - false negative
}
void uninitvar_setfill(void)
{
char c;
- // cppcheck-suppress uninitvar
+ // cppcheck-suppress [uninitvar,valueFlowBailoutIncompleteVar]
std::cout << std::setfill(c);
wchar_t wc;
@@ -4288,14 +4295,14 @@ void uninitvar_setfill(void)
void uninitvar_setprecision(void)
{
int p;
- // cppcheck-suppress uninitvar
+ // cppcheck-suppress [uninitvar,valueFlowBailoutIncompleteVar]
std::cout << std::setprecision(p);
}
void uninitvar_setbase(void)
{
int p;
- // cppcheck-suppress uninitvar
+ // cppcheck-suppress [uninitvar,valueFlowBailoutIncompleteVar]
std::cout << std::setbase(p);
}
@@ -4732,6 +4739,7 @@ void stdbind_helper(int a)
void stdbind()
{
+ // cppcheck-suppress valueFlowBailoutIncompleteVar
using namespace std::placeholders;
// TODO cppcheck-suppress ignoredReturnValue #9369
@@ -4963,7 +4971,7 @@ void memleak_std_realloc(void* block, size_t newsize)
void unusedAllocatedMemory_std_free()
{
- //cppcheck-suppress unusedAllocatedMemory
+ // TODO cppcheck-suppress unusedAllocatedMemory
void* p = std::malloc(1);
std::free(p);
}
diff --git a/test/cfg/windows.cpp b/test/cfg/windows.cpp
index 179f44d4b3f..5f2e6555ead 100644
--- a/test/cfg/windows.cpp
+++ b/test/cfg/windows.cpp
@@ -7,6 +7,8 @@
// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0
//
+// cppcheck-suppress-file [valueFlowBailout,purgedConfiguration]
+
#include
#include
#include
@@ -355,7 +357,7 @@ void validCode()
WSACleanup();
wordInit = MAKEWORD(1, 2);
- // cppcheck-suppress redundantAssignment
+ // TODO cppcheck-suppress redundantAssignment
dwordInit = MAKELONG(1, 2);
// cppcheck-suppress redundantAssignment
wordInit = LOWORD(dwordInit);
@@ -485,7 +487,7 @@ void mismatchAllocDealloc()
void nullPointer()
{
HANDLE hSemaphore;
- // cppcheck-suppress nullPointer
+ // cppcheck-suppress [nullPointer,valueFlowBailoutIncompleteVar]
hSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, NULL);
CloseHandle(hSemaphore);
@@ -588,7 +590,7 @@ void memleak_HeapAlloc()
void memleak_LocalAlloc()
{
LPTSTR pszBuf;
- // cppcheck-suppress [LocalAllocCalled, cstyleCast]
+ // cppcheck-suppress [LocalAllocCalled, cstyleCast, valueFlowBailoutIncompleteVar]
pszBuf = (LPTSTR)LocalAlloc(LPTR, MAX_PATH*sizeof(TCHAR));
(void)LocalSize(pszBuf);
(void)LocalFlags(pszBuf);
@@ -622,7 +624,7 @@ void resourceLeak_CreateSemaphoreA()
void resourceLeak_CreateSemaphoreEx()
{
HANDLE hSemaphore;
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress [unreadVariable,valueFlowBailoutIncompleteVar]
hSemaphore = CreateSemaphoreEx(NULL, 0, 1, NULL, 0, SEMAPHORE_ALL_ACCESS);
// cppcheck-suppress resourceLeak
}
@@ -630,7 +632,7 @@ void resourceLeak_CreateSemaphoreEx()
void resourceLeak_OpenSemaphore()
{
HANDLE hSemaphore;
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress [unreadVariable,valueFlowBailoutIncompleteVar]
hSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS, TRUE, _T("sem"));
// cppcheck-suppress resourceLeak
}
@@ -646,7 +648,7 @@ void resourceLeak_CreateMutexA()
void resourceLeak_CreateMutexEx()
{
HANDLE hMutex;
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress [unreadVariable,valueFlowBailoutIncompleteVar]
hMutex = CreateMutexEx(NULL, _T("sem"), 0, MUTEX_ALL_ACCESS);
// cppcheck-suppress resourceLeak
}
@@ -688,7 +690,7 @@ void resourceLeak_CreateEventExA()
void resourceLeak_OpenEventW()
{
HANDLE hEvent;
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress [unreadVariable,valueFlowBailoutIncompleteVar]
hEvent = OpenEventW(EVENT_ALL_ACCESS, TRUE, L"testevent");
// cppcheck-suppress resourceLeak
}
@@ -705,7 +707,7 @@ void ignoredReturnValue(FILE* fp)
{
// cppcheck-suppress leakReturnValNotUsed
CreateSemaphoreW(NULL, 0, 1, NULL);
- // cppcheck-suppress leakReturnValNotUsed
+ // cppcheck-suppress [leakReturnValNotUsed,valueFlowBailoutIncompleteVar]
CreateSemaphoreExA(NULL, 0, 1, NULL, 0, SEMAPHORE_ALL_ACCESS);
// cppcheck-suppress leakReturnValNotUsed
OpenSemaphoreA(SEMAPHORE_ALL_ACCESS, TRUE, "sem");
@@ -770,7 +772,7 @@ void invalidFunctionArg()
// cppcheck-suppress invalidFunctionArgBool
hSemaphore = CreateSemaphore(NULL, 0, 1, false);
CloseHandle(hSemaphore);
- // cppcheck-suppress invalidFunctionArg
+ // cppcheck-suppress [invalidFunctionArg,valueFlowBailoutIncompleteVar]
hSemaphore = CreateSemaphoreEx(NULL, 0, 0, NULL, 0, SEMAPHORE_ALL_ACCESS);
CloseHandle(hSemaphore);
// cppcheck-suppress invalidFunctionArg
@@ -789,7 +791,7 @@ void invalidFunctionArg()
CloseHandle(hMutex);
//Incorrect: 2. parameter to LoadLibraryEx() must be NULL
- // cppcheck-suppress invalidFunctionArg
+ // TODO cppcheck-suppress invalidFunctionArg
HINSTANCE hInstLib = LoadLibraryEx(L"My.dll", HANDLE(1), 0);
FreeLibrary(hInstLib);
@@ -814,7 +816,7 @@ void uninitvar()
// cppcheck-suppress uninitvar
lstrcat(buf, _T("test"));
buf[0] = _T('\0');
- // cppcheck-suppress constVariable
+ // TODO cppcheck-suppress constVariable
TCHAR buf2[2];
// cppcheck-suppress lstrcatCalled
// cppcheck-suppress uninitvar
diff --git a/test/cfg/wxwidgets.cpp b/test/cfg/wxwidgets.cpp
index 85e233cdf9a..9292a7f71b3 100644
--- a/test/cfg/wxwidgets.cpp
+++ b/test/cfg/wxwidgets.cpp
@@ -7,12 +7,15 @@
// No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0
//
+// cppcheck-suppress-file valueFlowBailout
+
#include
#include
#include
#include
#include
#include
+#include
#include
#include
#include
@@ -36,15 +39,41 @@
#include
#include
-void unreadVariable_wxAcceleratorEntry()
+void unreadVariable_wxPoint2DInt(const wxInt32 x, const wxPoint2DInt& pti, const wxPoint &pt)
+{
+ // cppcheck-suppress unusedVariable
+ wxPoint2DInt a;
+ // cppcheck-suppress unreadVariable
+ wxPoint2DInt b(x, x);
+ // cppcheck-suppress unreadVariable
+ wxPoint2DInt c(pti);
+ // cppcheck-suppress unreadVariable
+ wxPoint2DInt d(pt);
+}
+
+void unreadVariable_wxPoint2DDouble(const wxDouble x, const wxPoint2DDouble& ptd, const wxPoint2DInt& pti, const wxPoint &pt)
{
+ // cppcheck-suppress unusedVariable
+ wxPoint2DDouble a;
+ // cppcheck-suppress unreadVariable
+ wxPoint2DDouble b(x, x);
+ // cppcheck-suppress unreadVariable
+ wxPoint2DDouble c(ptd);
// cppcheck-suppress unreadVariable
+ wxPoint2DDouble d(pti);
+ // cppcheck-suppress unreadVariable
+ wxPoint2DDouble e(pt);
+}
+
+void unusedVariable_wxAcceleratorEntry()
+{
+ // cppcheck-suppress unusedVariable
wxAcceleratorEntry a;
}
void unreadVariable_wxDateSpan(const int x)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
wxDateSpan a;
// cppcheck-suppress unreadVariable
wxDateSpan b{x};
@@ -58,7 +87,7 @@ void unreadVariable_wxDateSpan(const int x)
void unreadVariable_wxTimeSpan(const long x, const wxLongLong y)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
wxTimeSpan a;
// cppcheck-suppress unreadVariable
wxTimeSpan b{};
@@ -80,7 +109,7 @@ void unreadVariable_wxFileType(const wxFileTypeInfo &info)
void unreadVariable_wxPosition(const int x)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
wxPosition a;
// cppcheck-suppress unreadVariable
wxPosition b{};
@@ -90,7 +119,7 @@ void unreadVariable_wxPosition(const int x)
void unreadVariable_wxRegEx(const wxString &expr, const int flags)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
wxRegEx a;
// cppcheck-suppress unreadVariable
wxRegEx b{expr};
@@ -100,7 +129,7 @@ void unreadVariable_wxRegEx(const wxString &expr, const int flags)
void unreadVariable_wxRegion(const wxCoord x, const wxPoint &pt, const wxRect &rect, const wxRegion ®ion, const wxBitmap &bmp)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
wxRegion a;
// cppcheck-suppress unreadVariable
wxRegion b{};
@@ -118,7 +147,7 @@ void unreadVariable_wxRegion(const wxCoord x, const wxPoint &pt, const wxRect &r
void unreadVariable_wxVersionInfo(const wxString &name, const int major, const int minor, const int micro, const wxString &description, const wxString ©right)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
wxVersionInfo a;
// cppcheck-suppress unreadVariable
wxVersionInfo b(name);
@@ -136,7 +165,7 @@ void unreadVariable_wxVersionInfo(const wxString &name, const int major, const i
void unreadVariable_wxSize(const wxSize &s)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
wxSize a;
// cppcheck-suppress unreadVariable
wxSize b{};
@@ -150,7 +179,7 @@ void unreadVariable_wxSize(const wxSize &s)
void unreadVariable_wxPoint(const wxRealPoint &rp, const int x, const int y)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
wxPoint a;
// cppcheck-suppress unreadVariable
wxPoint b{};
@@ -168,7 +197,7 @@ void unreadVariable_wxPoint(const wxRealPoint &rp, const int x, const int y)
void unreadVariable_wxRealPoint(const wxPoint &pt, const double x, const double y)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
wxRealPoint a;
// cppcheck-suppress unreadVariable
wxRealPoint b{};
@@ -186,7 +215,7 @@ void unreadVariable_wxRealPoint(const wxPoint &pt, const double x, const double
void unreadVariable_wxRect(const int x, const wxPoint &pt, const wxSize &sz)
{
- // cppcheck-suppress unreadVariable
+ // cppcheck-suppress unusedVariable
wxRect a;
// cppcheck-suppress unreadVariable
wxRect b{};
diff --git a/test/cli/fuzz-crash/crash-0f0efd6e66bd115fc0aabbfe6503230b31de5f24 b/test/cli/fuzz-crash/crash-0f0efd6e66bd115fc0aabbfe6503230b31de5f24
new file mode 100644
index 00000000000..a011f109bd7
--- /dev/null
+++ b/test/cli/fuzz-crash/crash-0f0efd6e66bd115fc0aabbfe6503230b31de5f24
@@ -0,0 +1 @@
+d f(t*a){a[a[3]]}
\ No newline at end of file
diff --git a/test/cli/fuzz-crash/crash-43fe82a87d6a7f34f000cbbc90b63ad1a58e3dcd b/test/cli/fuzz-crash/crash-43fe82a87d6a7f34f000cbbc90b63ad1a58e3dcd
new file mode 100644
index 00000000000..ac43489b2c0
--- /dev/null
+++ b/test/cli/fuzz-crash/crash-43fe82a87d6a7f34f000cbbc90b63ad1a58e3dcd
@@ -0,0 +1 @@
+d o(){t&a=*&a}
\ No newline at end of file
diff --git a/test/cli/fuzz-timeout/timeout-0ee5eed9abd34e9d23640a5b82dd724affd05b79 b/test/cli/fuzz-timeout/timeout-0ee5eed9abd34e9d23640a5b82dd724affd05b79
new file mode 100644
index 00000000000..5f9465da55e
--- /dev/null
+++ b/test/cli/fuzz-timeout/timeout-0ee5eed9abd34e9d23640a5b82dd724affd05b79
@@ -0,0 +1 @@
+;new t()
\ No newline at end of file
diff --git a/test/cli/fuzz-timeout/timeout-a0b9848dd6e98677a0a96c5fc50ad571ed5a7092 b/test/cli/fuzz-timeout/timeout-a0b9848dd6e98677a0a96c5fc50ad571ed5a7092
new file mode 100644
index 00000000000..2f29da2e360
--- /dev/null
+++ b/test/cli/fuzz-timeout/timeout-a0b9848dd6e98677a0a96c5fc50ad571ed5a7092
@@ -0,0 +1,2 @@
+t i(){int
+t,?:0::::}
\ No newline at end of file
diff --git a/test/fixture.h b/test/fixture.h
index 7527f3261bd..af227609363 100644
--- a/test/fixture.h
+++ b/test/fixture.h
@@ -280,7 +280,7 @@ class TestFixture : public ErrorLogger {
};
// TODO: most asserts do not actually assert i.e. do not return
-#define TEST_CASE( NAME ) do { if (prepareTest(#NAME)) { setVerbose(false); NAME(); teardownTest(); } } while (false)
+#define TEST_CASE( NAME ) do { if (prepareTest(#NAME)) { setVerbose(false); try { NAME(); teardownTest(); } catch (...) { assertNoThrowFail(__FILE__, __LINE__); } } } while (false)
#define ASSERT( CONDITION ) if (!assert_(__FILE__, __LINE__, (CONDITION))) return
#define ASSERT_LOC( CONDITION, FILE_, LINE_ ) assert_(FILE_, LINE_, (CONDITION))
#define CHECK_EQUALS( EXPECTED, ACTUAL ) assertEquals(__FILE__, __LINE__, (EXPECTED), (ACTUAL))
diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp
index 5437ca9f013..60a56efbccc 100644
--- a/test/testcmdlineparser.cpp
+++ b/test/testcmdlineparser.cpp
@@ -334,11 +334,16 @@ class TestCmdlineParser : public TestFixture {
TEST_CASE(ruleNotSupported);
#endif
#ifdef HAVE_RULES
- TEST_CASE(ruleFile);
+ TEST_CASE(ruleFileMulti);
+ TEST_CASE(ruleFileSingle);
TEST_CASE(ruleFileEmpty);
TEST_CASE(ruleFileMissing);
TEST_CASE(ruleFileInvalid);
TEST_CASE(ruleFileNoRoot);
+ TEST_CASE(ruleFileEmptyElements1);
+ TEST_CASE(ruleFileEmptyElements2);
+ TEST_CASE(ruleFileUnknownElement1);
+ TEST_CASE(ruleFileUnknownElement2);
#else
TEST_CASE(ruleFileNotSupported);
#endif
@@ -2147,19 +2152,67 @@ class TestCmdlineParser : public TestFixture {
#endif
#ifdef HAVE_RULES
- void ruleFile() {
+ void ruleFileMulti() {
REDIRECT;
ScopedFile file("rule.xml",
"\n"
"\n"
+ "toklist1\n"
".+\n"
+ "\n"
+ "error\n"
+ "ruleId1\n"
+ "ruleSummary1\n"
+ "\n"
+ "\n"
+ "\n"
+ "toklist2\n"
+ ".*\n"
+ "\n"
+ "warning\n"
+ "ruleId2\n"
+ "ruleSummary2\n"
+ "\n"
"\n"
"");
const char * const argv[] = {"cppcheck", "--rule-file=rule.xml", "file.cpp"};
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv));
+ ASSERT_EQUALS(2, settings->rules.size());
+ auto it = settings->rules.cbegin();
+ ASSERT_EQUALS("toklist1", it->tokenlist);
+ ASSERT_EQUALS(".+", it->pattern);
+ ASSERT_EQUALS_ENUM(Severity::error, it->severity);
+ ASSERT_EQUALS("ruleId1", it->id);
+ ASSERT_EQUALS("ruleSummary1", it->summary);
+ ++it;
+ ASSERT_EQUALS("toklist2", it->tokenlist);
+ ASSERT_EQUALS(".*", it->pattern);
+ ASSERT_EQUALS_ENUM(Severity::warning, it->severity);
+ ASSERT_EQUALS("ruleId2", it->id);
+ ASSERT_EQUALS("ruleSummary2", it->summary);
+ }
+
+ void ruleFileSingle() {
+ REDIRECT;
+ ScopedFile file("rule.xml",
+ "\n"
+ "toklist\n"
+ ".+\n"
+ "\n"
+ "error\n"
+ "ruleId\n"
+ "ruleSummary\n"
+ "\n"
+ "\n");
+ const char * const argv[] = {"cppcheck", "--rule-file=rule.xml", "file.cpp"};
+ ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv));
ASSERT_EQUALS(1, settings->rules.size());
auto it = settings->rules.cbegin();
+ ASSERT_EQUALS("toklist", it->tokenlist);
ASSERT_EQUALS(".+", it->pattern);
+ ASSERT_EQUALS_ENUM(Severity::error, it->severity);
+ ASSERT_EQUALS("ruleId", it->id);
+ ASSERT_EQUALS("ruleSummary", it->summary);
}
void ruleFileEmpty() {
@@ -2189,6 +2242,63 @@ class TestCmdlineParser : public TestFixture {
ScopedFile file("rule.xml", "");
const char * const argv[] = {"cppcheck", "--rule-file=rule.xml", "file.cpp"};
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv));
+ ASSERT_EQUALS(0, settings->rules.size());
+ }
+
+ void ruleFileEmptyElements1() {
+ REDIRECT;
+ ScopedFile file("rule.xml",
+ ""
+ ""
+ ""
+ ""
+ ""
+ );
+ const char * const argv[] = {"cppcheck", "--rule-file=rule.xml", "file.cpp"};
+ ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parser->parseFromArgs(3, argv)); // do not crash
+ ASSERT_EQUALS("cppcheck: error: unable to load rule-file 'rule.xml' - a rule is lacking a pattern.\n", logger->str());
+ }
+
+ void ruleFileEmptyElements2() {
+ REDIRECT;
+ ScopedFile file("rule.xml",
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ );
+ const char * const argv[] = {"cppcheck", "--rule-file=rule.xml", "file.cpp"};
+ ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parser->parseFromArgs(3, argv)); // do not crash
+ ASSERT_EQUALS("cppcheck: error: unable to load rule-file 'rule.xml' - a rule is lacking a pattern.\n", logger->str());
+ }
+
+ void ruleFileUnknownElement1() {
+ REDIRECT;
+ ScopedFile file("rule.xml",
+ ""
+ ""
+ ""
+ );
+ const char * const argv[] = {"cppcheck", "--rule-file=rule.xml", "file.cpp"};
+ ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parser->parseFromArgs(3, argv));
+ ASSERT_EQUALS("cppcheck: error: unable to load rule-file 'rule.xml' - unknown element 'messages' encountered in 'rule'.\n", logger->str());
+ }
+
+ void ruleFileUnknownElement2() {
+ REDIRECT;
+ ScopedFile file("rule.xml",
+ ""
+ ""
+ ""
+ ""
+ ""
+ );
+ const char * const argv[] = {"cppcheck", "--rule-file=rule.xml", "file.cpp"};
+ ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parser->parseFromArgs(3, argv));
+ ASSERT_EQUALS("cppcheck: error: unable to load rule-file 'rule.xml' - unknown element 'pattern' encountered in 'message'.\n", logger->str());
}
#else
void ruleFileNotSupported() {
diff --git a/test/testcondition.cpp b/test/testcondition.cpp
index 868f8a98caa..5c794bbd39c 100644
--- a/test/testcondition.cpp
+++ b/test/testcondition.cpp
@@ -123,6 +123,7 @@ class TestCondition : public TestFixture {
TEST_CASE(compareOutOfTypeRange);
TEST_CASE(knownConditionCast); // #9976
TEST_CASE(knownConditionIncrementLoop); // #9808
+ TEST_CASE(knownConditionAfterBailout); // #12526
}
#define check(...) check_(__FILE__, __LINE__, __VA_ARGS__)
@@ -5957,6 +5958,37 @@ class TestCondition : public TestFixture {
"}\n");
ASSERT_EQUALS("", errout_str());
}
+
+ void knownConditionAfterBailout() { // #12526
+ check(
+ "#include \n"
+ "int func()\n"
+ "{\n"
+ " return VALUE_1;"
+ "}\n"
+ "\n"
+ "struct S1 {\n"
+ " bool b{};\n"
+ "};\n"
+ "\n"
+ "struct S {\n"
+ " void f(const std::list& l) const\n"
+ " {\n"
+ " if (mS.b)\n"
+ " return;\n"
+ " for (int i : l)\n"
+ " {\n"
+ " (void)i;\n"
+ " if (mS.b)\n"
+ " continue;\n"
+ " }\n"
+ " }\n"
+ "\n"
+ " S1 mS;\n"
+ "};"
+ );
+ ASSERT_EQUALS("[test.cpp:13] -> [test.cpp:18]: (style) Condition 'mS.b' is always false\n", errout_str());
+ }
};
REGISTER_TEST(TestCondition)
diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp
index f52ba217473..acb46bfe609 100644
--- a/test/testgarbage.cpp
+++ b/test/testgarbage.cpp
@@ -253,6 +253,7 @@ class TestGarbage : public TestFixture {
TEST_CASE(garbageCode222); // #10763
TEST_CASE(garbageCode223); // #11639
TEST_CASE(garbageCode224);
+ TEST_CASE(garbageCode225);
TEST_CASE(garbageCodeFuzzerClientMode1); // test cases created with the fuzzer client, mode 1
@@ -1746,6 +1747,10 @@ class TestGarbage : public TestFixture {
checkCode("void f(){ auto* b = dynamic_cast 0 && *q < 100) {}\n"
"}\n";
valueOfTok(code, "&&");
+
+ code = "void f() { int& a = *&a; }\n"; // #12511
+ valueOfTok(code, "=");
}
void valueFlowHang() {
@@ -8468,6 +8473,22 @@ class TestValueFlow : public TestFixture {
ASSERT_EQUALS(false, testValueOfX(code, 5U, 0));
}
+ void valueFlowBailoutIncompleteVar() { // #12526
+ bailout(
+ "int f1() {\n"
+ " return VALUE_1;\n"
+ "}\n"
+ "\n"
+ "int f2() {\n"
+ " return VALUE_2;\n"
+ "}\n"
+ );
+ ASSERT_EQUALS_WITHOUT_LINENUMBERS(
+ "[test.cpp:2]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable VALUE_1\n"
+ "[test.cpp:6]: (debug) valueFlowConditionExpressions bailout: Skipping function due to incomplete variable VALUE_2\n",
+ errout_str());
+ }
+
void performanceIfCount() {
/*const*/ Settings s(settings);
s.performanceValueFlowMaxIfCount = 1;
diff --git a/test/testvarid.cpp b/test/testvarid.cpp
index f763a0f1207..a6e5e132042 100644
--- a/test/testvarid.cpp
+++ b/test/testvarid.cpp
@@ -1507,6 +1507,20 @@ class TestVarID : public TestFixture {
"6: }\n";
ASSERT_EQUALS(expected, actual);
}
+
+ {
+ const std::string actual = tokenize("void f(int n) {\n" // #12537
+ " int n1;\n"
+ " void g(int is, int n1);\n"
+ " n1 = n - 1;\n"
+ "}\n", "test.cpp");
+ const char expected[] = "1: void f ( int n@1 ) {\n"
+ "2: int n1@2 ;\n"
+ "3: void g ( int is , int n1 ) ;\n"
+ "4: n1@2 = n@1 - 1 ;\n"
+ "5: }\n";
+ ASSERT_EQUALS(expected, actual);
+ }
}
void varid_sizeof() {