diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 1e5b719271c..6eb877a6b70 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1333,20 +1333,6 @@ void CheckOther::passedByValueError(const Variable* var, bool inconclusive, bool reportError(errorPath, Severity::performance, id.c_str(), msg, CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal); } -static bool isUnusedVariable(const Variable *var) -{ - if (!var) - return false; - if (!var->scope()) - return false; - const Token *start = var->declEndToken(); - if (!start) - return false; - if (Token::Match(start, "; %varid% =", var->declarationId())) - start = start->tokAt(2); - return !Token::findmatch(start->next(), "%varid%", var->scope()->bodyEnd, var->declarationId()); -} - static bool isVariableMutableInInitializer(const Token* start, const Token * end, nonneg int varid) { if (!start) @@ -1402,8 +1388,6 @@ void CheckOther::checkConstVariable() if (function && var->isArgument()) { if (function->isImplicitlyVirtual() || function->templateDef) continue; - if (isUnusedVariable(var)) - continue; if (function->isConstructor() && isVariableMutableInInitializer(function->constructorMemberInitialization(), scope->bodyStart, var->declarationId())) continue; } @@ -1417,6 +1401,8 @@ void CheckOther::checkConstVariable() continue; if (var->isVolatile()) continue; + if (var->isMaybeUnused()) + continue; if (var->nameToken()->isExpandedMacro()) continue; if (isStructuredBindingVariable(var)) // TODO: check all bound variables @@ -1505,6 +1491,24 @@ static const Token* getVariableChangedStart(const Variable* p) return start; } +namespace { + struct CompareVariables { + bool operator()(const Variable* a, const Variable* b) const { + const int fileA = a->nameToken()->fileIndex(); + const int fileB = b->nameToken()->fileIndex(); + if (fileA != fileB) + return fileA < fileB; + const int lineA = a->nameToken()->linenr(); + const int lineB = b->nameToken()->linenr(); + if (lineA != lineB) + return lineA < lineB; + const int columnA = a->nameToken()->column(); + const int columnB = b->nameToken()->column(); + return columnA < columnB; + } + }; +} + void CheckOther::checkConstPointer() { if (!mSettings->severity.isEnabled(Severity::style) && @@ -1514,7 +1518,7 @@ void CheckOther::checkConstPointer() logChecker("CheckOther::checkConstPointer"); // style - std::vector pointers, nonConstPointers; + std::set pointers, nonConstPointers; for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { const Variable* const var = tok->variable(); if (!var) @@ -1522,10 +1526,12 @@ void CheckOther::checkConstPointer() if (!var->isLocal() && !var->isArgument()) continue; const Token* const nameTok = var->nameToken(); - // declarations of (static) pointers are (not) split up, array declarations are never split up - if (tok == nameTok && (!var->isStatic() || Token::simpleMatch(nameTok->next(), "[")) && - !astIsRangeBasedForDecl(nameTok)) - continue; + if (tok == nameTok) { + // declarations of (static) pointers are (not) split up, array declarations are never split up + if (var->isLocal() && (!var->isStatic() || Token::simpleMatch(nameTok->next(), "[")) && + !astIsRangeBasedForDecl(nameTok)) + continue; + } const ValueType* const vt = tok->valueType(); if (!vt) continue; @@ -1535,7 +1541,7 @@ void CheckOther::checkConstPointer() continue; if (std::find(nonConstPointers.cbegin(), nonConstPointers.cend(), var) != nonConstPointers.cend()) continue; - pointers.emplace_back(var); + pointers.emplace(var); const Token* parent = tok->astParent(); enum Deref { NONE, DEREF, MEMBER } deref = NONE; bool hasIncDec = false; @@ -1620,12 +1626,15 @@ void CheckOther::checkConstPointer() continue; } } - nonConstPointers.emplace_back(var); + if (tok != nameTok) + nonConstPointers.emplace(var); } for (const Variable *p: pointers) { if (p->isArgument()) { if (!p->scope() || !p->scope()->function || p->scope()->function->isImplicitlyVirtual(true) || p->scope()->function->hasVirtualSpecifier()) continue; + if (p->isMaybeUnused()) + continue; } if (std::find(nonConstPointers.cbegin(), nonConstPointers.cend(), p) == nonConstPointers.cend()) { const Token *start = getVariableChangedStart(p); diff --git a/test/cfg/libcurl.c b/test/cfg/libcurl.c index 354ee549149..8c494494a03 100644 --- a/test/cfg/libcurl.c +++ b/test/cfg/libcurl.c @@ -34,6 +34,7 @@ void validCode() } } +// cppcheck-suppress constParameterPointer void ignoredReturnValue(CURL * handle) { // cppcheck-suppress ignoredReturnValue diff --git a/test/cfg/posix.c b/test/cfg/posix.c index 18400eff3c2..016081aa6c9 100644 --- a/test/cfg/posix.c +++ b/test/cfg/posix.c @@ -1023,6 +1023,7 @@ void nullPointer(char *p, int fd, pthread_mutex_t mutex) pthread_mutex_unlock(NULL); } +// cppcheck-suppress constParameterCallback void* f_returns_NULL(void* arg) { return NULL; diff --git a/test/cfg/wxwidgets.cpp b/test/cfg/wxwidgets.cpp index 7472fc54350..bbe799815b0 100644 --- a/test/cfg/wxwidgets.cpp +++ b/test/cfg/wxwidgets.cpp @@ -352,10 +352,10 @@ void deprecatedFunctions_wxDataViewCustomRenderer(wxDataViewCustomRenderer &data dataViewCustomRenderer.LeftClick(cursor, cell, model, item, col); } -void deprecatedFunctions(wxApp &a, +void deprecatedFunctions([[maybe_unused]] wxApp &a, const wxString &s, - wxArtProvider *artProvider, - wxCalendarCtrl &calenderCtrl, + [[maybe_unused]] wxArtProvider *artProvider, + [[maybe_unused]] wxCalendarCtrl &calenderCtrl, wxComboCtrl &comboCtrl, wxChar * path) { diff --git a/test/testother.cpp b/test/testother.cpp index e85cd590bd5..11ceab209b3 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -2576,11 +2576,10 @@ class TestOther : public TestFixture { "}"); ASSERT_EQUALS("", errout.str()); - // Perhaps unused variable should be checked as well. check("void f(int& x, int& y) {\n" " y++;\n" "}"); - ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'x' can be declared as reference to const\n", errout.str()); check("struct A {\n" " explicit A(int& y) : x(&y) {}\n" @@ -3135,11 +3134,8 @@ class TestOther : public TestFixture { "void an();\n" "void h();"); ASSERT_EQUALS("[test.cpp:131]: (style) Variable 'tm' can be declared as pointer to const\n" - "[test.cpp:131]: (style) Variable 'tm' can be declared as pointer to const\n" // duplicate "[test.cpp:136]: (style) Variable 'af' can be declared as pointer to const\n" - "[test.cpp:137]: (style) Variable 'ag' can be declared as pointer to const\n" - "[test.cpp:136]: (style) Variable 'af' can be declared as pointer to const\n" // duplicate - "[test.cpp:137]: (style) Variable 'ag' can be declared as pointer to const\n", // duplicate + "[test.cpp:137]: (style) Variable 'ag' can be declared as pointer to const\n", errout.str()); check("class C\n" @@ -3355,9 +3351,7 @@ class TestOther : public TestFixture { " d->f();\n" "}\n"); ASSERT_EQUALS( - "[test.cpp:4]: (style) Variable 'd' can be declared as pointer to const\n" - "[test.cpp:4]: (style) Variable 'd' can be declared as pointer to const\n" // duplicate - "[test.cpp:4]: (style) Variable 'd' can be declared as pointer to const\n", // duplicate + "[test.cpp:4]: (style) Variable 'd' can be declared as pointer to const\n", errout.str()); check("void g(const int*);\n" @@ -3366,8 +3360,7 @@ class TestOther : public TestFixture { " g(i);\n" "}\n"); ASSERT_EQUALS( - "[test.cpp:3]: (style) Variable 'i' can be declared as pointer to const\n" - "[test.cpp:3]: (style) Variable 'i' can be declared as pointer to const\n", // duplicate + "[test.cpp:3]: (style) Variable 'i' can be declared as pointer to const\n", errout.str()); check("struct A {\n" // #11225 @@ -3552,6 +3545,18 @@ class TestOther : public TestFixture { " c[0](5) = 12;\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("int f(int& t) {\n" // #11713 + " return 0;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 't' can be declared as reference to const\n", errout.str()); + + check("void f(std::list& v) {\n" // #12202 + " v.remove_if([](std::string& s) {\n" + " return true;\n" + " });\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 's' can be declared as reference to const\n", errout.str()); } void constParameterCallback() { @@ -3744,8 +3749,7 @@ class TestOther : public TestFixture { " if (h) {}\n" "}\n"); ASSERT_EQUALS( - "[test.cpp:5]: (style) Variable 'h' can be declared as pointer to const\n" - "[test.cpp:5]: (style) Variable 'h' can be declared as pointer to const\n", // duplicate + "[test.cpp:5]: (style) Variable 'h' can be declared as pointer to const\n", errout.str()); check("void f(const std::vector& v) {\n" @@ -3755,8 +3759,7 @@ class TestOther : public TestFixture { " if (p == nullptr) {}\n" "}\n"); ASSERT_EQUALS( - "[test.cpp:2]: (style) Variable 'p' can be declared as pointer to const\n" - "[test.cpp:2]: (style) Variable 'p' can be declared as pointer to const\n", // duplicate + "[test.cpp:2]: (style) Variable 'p' can be declared as pointer to const\n", errout.str()); check("void f(std::vector& v) {\n" @@ -3770,8 +3773,7 @@ class TestOther : public TestFixture { " if (p == nullptr) {}\n" "}\n"); ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'v' can be declared as reference to const\n" - "[test.cpp:2]: (style) Variable 'p' can be declared as pointer to const\n" - "[test.cpp:2]: (style) Variable 'p' can be declared as pointer to const\n", // duplicate + "[test.cpp:2]: (style) Variable 'p' can be declared as pointer to const\n", errout.str()); check("void f(std::vector& v) {\n" @@ -3862,9 +3864,7 @@ class TestOther : public TestFixture { " v.clear();\n" "}\n"); ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'p' can be declared as pointer to const\n" - "[test.cpp:2]: (style) Variable 'p' can be declared as pointer to const\n" // duplicate - "[test.cpp:5]: (style) Variable 'p' can be declared as pointer to const\n" - "[test.cpp:5]: (style) Variable 'p' can be declared as pointer to const\n", // duplicate + "[test.cpp:5]: (style) Variable 'p' can be declared as pointer to const\n", errout.str()); check("void f() {\n" @@ -3927,8 +3927,7 @@ class TestOther : public TestFixture { " g(1, p);\n" " h(p);\n" "}\n"); - ASSERT_EQUALS("[test.cpp:3]: (style) Parameter 'p' can be declared as pointer to const\n" - "[test.cpp:3]: (style) Parameter 'p' can be declared as pointer to const\n", // duplicate + ASSERT_EQUALS("[test.cpp:3]: (style) Parameter 'p' can be declared as pointer to const\n", errout.str()); check("void f(int, const int*);\n" @@ -4075,8 +4074,7 @@ class TestOther : public TestFixture { " void* p = &i;\n" " std::cout << p << '\\n';\n" "}\n"); - ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'p' can be declared as pointer to const\n" - "[test.cpp:2]: (style) Variable 'p' can be declared as pointer to const\n", // duplicate + ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'p' can be declared as pointer to const\n", errout.str()); check("struct S { const T* t; };\n" // #12206 @@ -4092,10 +4090,14 @@ class TestOther : public TestFixture { " delete[] b;\n" "}\n"); ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'a1' can be declared as pointer to const\n" - "[test.cpp:1]: (style) Parameter 'a2' can be declared as pointer to const\n" - "[test.cpp:1]: (style) Parameter 'a1' can be declared as pointer to const\n" "[test.cpp:1]: (style) Parameter 'a2' can be declared as pointer to const\n", errout.str()); + + check("int f(int* p) {\n" // #11713 + " return 0;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n", + errout.str()); } void switchRedundantAssignmentTest() { @@ -7785,8 +7787,7 @@ class TestOther : public TestFixture { " int end = x->first;\n" "}"); ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3]: (style, inconclusive) Same expression used in consecutive assignments of 'start' and 'end'.\n" - "[test.cpp:2]: (style) Parameter 'x' can be declared as pointer to const\n" - "[test.cpp:2]: (style) Parameter 'x' can be declared as pointer to const\n", // duplicate + "[test.cpp:2]: (style) Parameter 'x' can be declared as pointer to const\n", errout.str()); check("struct SW { int first; };\n" @@ -7795,8 +7796,7 @@ class TestOther : public TestFixture { " int end = x->first;\n" "}"); ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3]: (style, inconclusive) Same expression used in consecutive assignments of 'start' and 'end'.\n" - "[test.cpp:2]: (style) Parameter 'x' can be declared as pointer to const\n" - "[test.cpp:2]: (style) Parameter 'x' can be declared as pointer to const\n", // duplicate + "[test.cpp:2]: (style) Parameter 'x' can be declared as pointer to const\n", errout.str()); check("struct Foo { int f() const; };\n" @@ -8000,9 +8000,7 @@ class TestOther : public TestFixture { " if ((*p > 0)) {}\n" "}\n"); ASSERT_EQUALS( - "[test.cpp:3]: (style) Variable 'p' can be declared as pointer to const\n" - "[test.cpp:3]: (style) Variable 'p' can be declared as pointer to const\n" // duplicate - "[test.cpp:3]: (style) Variable 'p' can be declared as pointer to const\n", // duplicate + "[test.cpp:3]: (style) Variable 'p' can be declared as pointer to const\n", errout.str()); check("void f() {\n" @@ -8013,9 +8011,7 @@ class TestOther : public TestFixture { "}\n"); TODO_ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) The comparison '*p < 0' is always false.\n" "[test.cpp:2] -> [test.cpp:4]: (style) The comparison '*p > 0' is always false.\n", - "[test.cpp:3]: (style) Variable 'p' can be declared as pointer to const\n" - "[test.cpp:3]: (style) Variable 'p' can be declared as pointer to const\n" // duplicate - "[test.cpp:3]: (style) Variable 'p' can be declared as pointer to const\n", // duplicate + "[test.cpp:3]: (style) Variable 'p' can be declared as pointer to const\n", errout.str()); check("void f() {\n" @@ -8637,13 +8633,17 @@ class TestOther : public TestFixture { " char *a; a = new char[1024];\n" " delete[] (a + 10);\n" "}"); - ASSERT_EQUALS("[test.cpp:3]: (error) Mismatching address is deleted. The address you get from new must be deleted without offset.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n" + "[test.cpp:3]: (error) Mismatching address is deleted. The address you get from new must be deleted without offset.\n", + errout.str()); check("void foo(char *p) {\n" " char *a; a = new char;\n" " delete a + 10;\n" "}"); - ASSERT_EQUALS("[test.cpp:3]: (error) Mismatching address is deleted. The address you get from new must be deleted without offset.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n" + "[test.cpp:3]: (error) Mismatching address is deleted. The address you get from new must be deleted without offset.\n", + errout.str()); check("void foo(char *p) {\n" " char *a; a = new char;\n" @@ -8675,7 +8675,9 @@ class TestOther : public TestFixture { " bar()\n" " delete a + 10;\n" "}"); - ASSERT_EQUALS("[test.cpp:4]: (error) Mismatching address is deleted. The address you get from new must be deleted without offset.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'p' can be declared as pointer to const\n" + "[test.cpp:4]: (error) Mismatching address is deleted. The address you get from new must be deleted without offset.\n", + errout.str()); check("void foo(size_t xx) {\n" " char *ptr; ptr = malloc(42);\n" @@ -8691,9 +8693,7 @@ class TestOther : public TestFixture { " free(otherPtr - xx - 1);\n" "}"); ASSERT_EQUALS( - "[test.cpp:2]: (style) Variable 'ptr' can be declared as pointer to const\n" - "[test.cpp:2]: (style) Variable 'ptr' can be declared as pointer to const\n" // duplicate - "[test.cpp:2]: (style) Variable 'ptr' can be declared as pointer to const\n", // duplicate + "[test.cpp:2]: (style) Variable 'ptr' can be declared as pointer to const\n", errout.str()); } @@ -9272,8 +9272,7 @@ class TestOther : public TestFixture { " x = dostuff();\n" "}"); ASSERT_EQUALS( - "test.cpp:2:style:Variable 'x' can be declared as pointer to const\n" - "test.cpp:2:style:Variable 'x' can be declared as pointer to const\n", // duplicate + "test.cpp:2:style:Variable 'x' can be declared as pointer to const\n", errout.str()); check("void f() {\n" @@ -9282,8 +9281,7 @@ class TestOther : public TestFixture { " x = dostuff();\n" "}"); ASSERT_EQUALS( - "test.cpp:2:style:Variable 'x' can be declared as pointer to const\n" - "test.cpp:2:style:Variable 'x' can be declared as pointer to const\n", // duplicate + "test.cpp:2:style:Variable 'x' can be declared as pointer to const\n", errout.str()); check("int foo() {\n" // #4420 @@ -9418,9 +9416,7 @@ class TestOther : public TestFixture { " }\n" "}"); ASSERT_EQUALS("test.cpp:2:style:The scope of the variable 'p' can be reduced.\n" - "test.cpp:2:style:Variable 'p' can be declared as pointer to const\n" - "test.cpp:2:style:Variable 'p' can be declared as pointer to const\n" // duplicate - "test.cpp:2:style:Variable 'p' can be declared as pointer to const\n", // duplicate + "test.cpp:2:style:Variable 'p' can be declared as pointer to const\n", errout.str()); check("void foo() {\n" @@ -9513,8 +9509,7 @@ class TestOther : public TestFixture { " a = p;\n" "}"); ASSERT_EQUALS( - "[test.cpp:2]: (style) Variable 'a' can be declared as pointer to const\n" - "[test.cpp:2]: (style) Variable 'a' can be declared as pointer to const\n", // duplicate + "[test.cpp:2]: (style) Variable 'a' can be declared as pointer to const\n", errout.str()); check("void f() {\n" @@ -9523,8 +9518,7 @@ class TestOther : public TestFixture { " a = p;\n" "}"); ASSERT_EQUALS( - "[test.cpp:2]: (style) Variable 'a' can be declared as pointer to const\n" - "[test.cpp:2]: (style) Variable 'a' can be declared as pointer to const\n", // duplicate + "[test.cpp:2]: (style) Variable 'a' can be declared as pointer to const\n", errout.str()); } @@ -9783,8 +9777,7 @@ class TestOther : public TestFixture { " p = dostuff();\n" "}"); ASSERT_EQUALS( - "test.cpp:2:style:Variable 'p' can be declared as pointer to const\n" - "test.cpp:2:style:Variable 'p' can be declared as pointer to const\n", // duplicate + "test.cpp:2:style:Variable 'p' can be declared as pointer to const\n", errout.str()); // "trivial" initialization => do not warn @@ -11614,9 +11607,7 @@ class TestOther : public TestFixture { ASSERT_EQUALS( "[test.cpp:2] -> [test.cpp:4] -> [test.cpp:3] -> [test.cpp:5] -> [test.cpp:6]: (error) Comparing pointers that point to different objects\n" "[test.cpp:4]: (style) Variable 'xp' can be declared as pointer to const\n" - "[test.cpp:5]: (style) Variable 'yp' can be declared as pointer to const\n" - "[test.cpp:4]: (style) Variable 'xp' can be declared as pointer to const\n" // duplicate - "[test.cpp:5]: (style) Variable 'yp' can be declared as pointer to const\n", // duplicate + "[test.cpp:5]: (style) Variable 'yp' can be declared as pointer to const\n", errout.str()); check("bool f() {\n" @@ -11639,9 +11630,7 @@ class TestOther : public TestFixture { ASSERT_EQUALS( "[test.cpp:3] -> [test.cpp:5] -> [test.cpp:4] -> [test.cpp:6] -> [test.cpp:7]: (error) Comparing pointers that point to different objects\n" "[test.cpp:5]: (style) Variable 'xp' can be declared as pointer to const\n" - "[test.cpp:6]: (style) Variable 'yp' can be declared as pointer to const\n" - "[test.cpp:5]: (style) Variable 'xp' can be declared as pointer to const\n" // duplicate - "[test.cpp:6]: (style) Variable 'yp' can be declared as pointer to const\n", // duplicate + "[test.cpp:6]: (style) Variable 'yp' can be declared as pointer to const\n", errout.str()); check("struct A {int data;};\n" @@ -11655,9 +11644,7 @@ class TestOther : public TestFixture { ASSERT_EQUALS( "[test.cpp:2] -> [test.cpp:3] -> [test.cpp:5] -> [test.cpp:2] -> [test.cpp:4] -> [test.cpp:6] -> [test.cpp:7]: (error) Comparing pointers that point to different objects\n" "[test.cpp:5]: (style) Variable 'xp' can be declared as pointer to const\n" - "[test.cpp:6]: (style) Variable 'yp' can be declared as pointer to const\n" - "[test.cpp:5]: (style) Variable 'xp' can be declared as pointer to const\n" // duplicate - "[test.cpp:6]: (style) Variable 'yp' can be declared as pointer to const\n", // duplicate + "[test.cpp:6]: (style) Variable 'yp' can be declared as pointer to const\n", errout.str()); check("bool f(int * xp, int* yp) {\n" @@ -11683,9 +11670,7 @@ class TestOther : public TestFixture { " return xp > yp;\n" "}"); ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'xp' can be declared as pointer to const\n" - "[test.cpp:4]: (style) Variable 'yp' can be declared as pointer to const\n" - "[test.cpp:3]: (style) Variable 'xp' can be declared as pointer to const\n" // duplicate - "[test.cpp:4]: (style) Variable 'yp' can be declared as pointer to const\n", // duplicate + "[test.cpp:4]: (style) Variable 'yp' can be declared as pointer to const\n", errout.str()); check("bool f(const int * xp, const int* yp) {\n" @@ -11717,9 +11702,7 @@ class TestOther : public TestFixture { " return xp > yp;\n" "}"); ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'xp' can be declared as pointer to const\n" - "[test.cpp:6]: (style) Variable 'yp' can be declared as pointer to const\n" - "[test.cpp:5]: (style) Variable 'xp' can be declared as pointer to const\n" // duplicate - "[test.cpp:6]: (style) Variable 'yp' can be declared as pointer to const\n", // duplicate + "[test.cpp:6]: (style) Variable 'yp' can be declared as pointer to const\n", errout.str()); check("struct S { int i; };\n" // #11576