From 8eb16edf4f431823ecb52a02766f42103991f5d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 22 Nov 2025 09:46:16 +0100 Subject: [PATCH 1/2] Fix #12503 (usability: bogus suggestion in functionStatic message) --- lib/checkclass.cpp | 21 ++--- man/checkers/functionConst.md | 101 ++++++++++++++++++++++ man/checkers/functionStatic.md | 64 ++++++++++++++ test/testclass.cpp | 150 ++++++++++++++++----------------- 4 files changed, 247 insertions(+), 89 deletions(-) create mode 100644 man/checkers/functionConst.md create mode 100644 man/checkers/functionStatic.md diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index ec6c00b8dc4..f141283547e 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -2132,10 +2132,6 @@ void CheckClass::thisSubtractionError(const Token *tok) void CheckClass::checkConst() { - // This is an inconclusive check. False positives: #3322. - if (!mSettings->certainty.isEnabled(Certainty::inconclusive)) - return; - if (!mSettings->severity.isEnabled(Severity::style) && !mSettings->isPremiumEnabled("functionConst") && !mSettings->isPremiumEnabled("functionStatic")) @@ -2222,6 +2218,9 @@ void CheckClass::checkConst() const bool suggestStatic = memberAccessed != MemberAccess::MEMBER && !func.isOperator(); if ((returnsPtrOrRef || func.isConst() || func.hasLvalRefQualifier()) && !suggestStatic) continue; + if (!suggestStatic && !mSettings->certainty.isEnabled(Certainty::inconclusive)) + // functionConst is inconclusive. False positives: #3322. + continue; if (suggestStatic && func.isConst()) { const auto overloads = func.getOverloadedFunctions(); if (overloads.size() > 1 && std::any_of(overloads.begin(), overloads.end(), [&](const Function* ovl) { @@ -2719,16 +2718,10 @@ void CheckClass::checkConstError2(const Token *tok1, const Token *tok2, const st } else { const std::string msg = foundAllBaseClasses ? - "Technically the member function '$symbol' can be static (but you may consider moving to unnamed namespace).\nThe member function '$symbol' can be made a static " : - "Either there is a missing 'override', or the member function '$symbol' can be static.\nUnless it overrides a base class member, the member function '$symbol' can be made a static "; - reportError(toks, Severity::performance, "functionStatic", - "$symbol:" + classname + "::" + funcname +"\n" - + msg + - "function. Making a function static can bring a performance benefit since no 'this' instance is " - "passed to the function. This change should not cause compiler errors but it does not " - "necessarily make sense conceptually. Think about your design and the task of the function first - " - "is it a function that must not access members of class instances? And maybe it is more appropriate " - "to move this function to an unnamed namespace.", CWE398, Certainty::inconclusive); + "The member function '$symbol' can be static." : + "Either there is a missing 'override', or the member function '$symbol' can be static."; + reportError(toks, Severity::style, "functionStatic", + "$symbol:" + classname + "::" + funcname +"\n" + msg, CWE398, Certainty::normal); } } diff --git a/man/checkers/functionConst.md b/man/checkers/functionConst.md new file mode 100644 index 00000000000..acbc0e1dfd4 --- /dev/null +++ b/man/checkers/functionConst.md @@ -0,0 +1,101 @@ +# functionConst + +**Message**: Technically the member function 'x' can be const
+**Category**: Robustness
+**Severity**: Style (Inconclusive)
+**Language**: C++ + +## Description + +This checker identifies member functions that do not modify any member variables and therefore could be declared as `const`. A const member function promises not to modify the object's state and enables the function to be called on const objects. + +The danger is that a const member function is allowed to have side effects outside the object. If you create a member function that formats the hard drive using +system calls it might be technically possible to make the function const, but is it "correct"? Using a const object is not supposed to have side effects. + +For methods that has no side effects whatsoever; making them const is recommended. + +The checker analyzes member functions and detects when: +- The function only reads member variables (never writes to them) +- The function only calls other const member functions +- The function only modifies parameters passed by reference or pointer (not member variables) +- The function performs operations that don't change the object's logical state + +This warning is marked as **inconclusive** because while the function can technically be made const, it may not always be "correct". + +This warning helps improve code quality by: +- Making the function's non-modifying nature explicit +- Enabling the function to be called on const objects +- Improving const-correctness throughout the codebase +- Helping with compiler optimizations +- Making code intentions clearer to other developers + +## Motivation + +The motivation of this checker is to improve robustness by making the code more const-correct. + +## How to fix + +Add the `const` keyword after the function signature to indicate that the function does not modify the object's state. + +Before: +```cpp +class Rectangle { + int width, height; +public: + int getWidth() { return width; } + int getHeight() { return height; } + int getArea() { return width * height; } + + void printInfo() { + std::cout << "Width: " << width << ", Height: " << height << std::endl; + } + + bool isSquare() { + return width == height; + } + + void copyDataTo(Rectangle& other) { + other.width = width; + other.height = height; + } +}; +``` + +After: +```cpp +class Rectangle { + int width, height; +public: + int getWidth() const { return width; } + int getHeight() const { return height; } + int getArea() const { return width * height; } + + void printInfo() const { + std::cout << "Width: " << width << ", Height: " << height << std::endl; + } + + bool isSquare() const { + return width == height; + } + + void copyDataTo(Rectangle& other) const { + other.width = width; + other.height = height; + } +}; +``` + +## Related checkers + +- `functionStatic` - for member functions that can be declared static +- `constParameter` - for function parameters that can be const +- `constParameterReference` - for reference parameters that can be const +- `constParameterPointer` - for pointer parameters that can be const +- `constVariable` - for local variables that can be const +- `constVariableReference` - for local reference variables that can be const + +## Notes + +- This check is marked as **inconclusive** because the decision to make a function const should also consider the conceptual design +- Virtual functions should be carefully considered before making them const, as this affects the entire inheritance hierarchy +- Think about whether the function's purpose is to query state (should be const) or to perform an action (may not need to be const) diff --git a/man/checkers/functionStatic.md b/man/checkers/functionStatic.md new file mode 100644 index 00000000000..896dd2c936e --- /dev/null +++ b/man/checkers/functionStatic.md @@ -0,0 +1,64 @@ +# functionStatic + +**Message**: The member function 'x' can be static
+**Category**: Readability
+**Severity**: Style
+**Language**: C++ + +## Description + +This checker identifies member functions that do not access any non-static member variables or call any non-static member functions. Such functions can be declared as `static` to indicate that they don't require an object instance to operate. + +This warning helps improve code quality by: +- Making the function's independence from object state explicit +- Enabling the function to be called without creating an object instance +- Clarifying the function's scope and dependencies + +## Motivation + +The motivation of this checker is to improve readability. + +## How to fix + +Add the `static` keyword to the function declaration to indicate that it doesn't require an object instance. + +Before: +```cpp +class Calculator { +public: + int add(int a, int b) { + return a + b; // Only uses parameters + } + + void printMessage() { + std::cout << "Hello World" << std::endl; // Uses no instance data + } + + bool isValidNumber(int num) { + return num > 0 && num < 1000; // Pure function + } +}; +``` + +After: +```cpp +class Calculator { +public: + static int add(int a, int b) { + return a + b; // Can be called as Calculator::add(5, 3) + } + + static void printMessage() { + std::cout << "Hello World" << std::endl; // Can be called without instance + } + + static bool isValidNumber(int num) { + return num > 0 && num < 1000; // Clearly indicates no state dependency + } +}; +``` + +## Related checkers + +- `functionConst` - for member functions that can be declared const + diff --git a/test/testclass.cpp b/test/testclass.cpp index 8b4af350178..21457f15bfc 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -3686,13 +3686,13 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" " const std::string foo() { return \"\"; }\n" "};"); - ASSERT_EQUALS("[test.cpp:2:23]: (performance, inconclusive) Technically the member function 'Fred::foo' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2:23]: (style) The member function 'Fred::foo' can be static. [functionStatic]\n", errout_str()); checkConst("class Fred {\n" " std::string s;\n" " const std::string & foo() { return \"\"; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:25]: (performance, inconclusive) Technically the member function 'Fred::foo' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:25]: (style) The member function 'Fred::foo' can be static. [functionStatic]\n", errout_str()); // constructors can't be const.. checkConst("class Fred {\n" @@ -3731,7 +3731,7 @@ class TestClass : public TestFixture { " int x;\n" " void b() { a(); }\n" "};"); - ASSERT_EQUALS("[test.cpp:4:10]: (performance, inconclusive) Technically the member function 'Fred::b' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:4:10]: (style) The member function 'Fred::b' can be static. [functionStatic]\n", errout_str()); // static functions can't be const.. checkConst("class foo\n" @@ -3745,7 +3745,7 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" " const std::string foo() const throw() { return \"\"; }\n" "};"); - ASSERT_EQUALS("[test.cpp:2:23]: (performance, inconclusive) Technically the member function 'Fred::foo' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2:23]: (style) The member function 'Fred::foo' can be static. [functionStatic]\n", errout_str()); } void const2() { @@ -3857,7 +3857,7 @@ class TestClass : public TestFixture { " const std::string & foo();\n" "};\n" "const std::string & Fred::foo() { return \"\"; }"); - ASSERT_EQUALS("[test.cpp:3:25] -> [test.cpp:5:27]: (performance, inconclusive) Technically the member function 'Fred::foo' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:25] -> [test.cpp:5:27]: (style) The member function 'Fred::foo' can be static. [functionStatic]\n", errout_str()); // functions with a function call to a non-const member can't be const.. (#1305) checkConst("class Fred\n" @@ -3993,7 +3993,7 @@ class TestClass : public TestFixture { "void Fred::foo() { }" "void Fred::foo(std::string & a) { a = s; }" "void Fred::foo(const std::string & a) { s = a; }"); - ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:7:12]: (performance, inconclusive) Technically the member function 'Fred::foo' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n" + ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:7:12]: (style) The member function 'Fred::foo' can be static. [functionStatic]\n" "[test.cpp:4:10] -> [test.cpp:7:32]: (style, inconclusive) Technically the member function 'Fred::foo' can be const. [functionConst]\n", errout_str()); // check functions with different or missing parameter names @@ -4010,11 +4010,11 @@ class TestClass : public TestFixture { "void Fred::foo3(int a, int b) { }\n" "void Fred::foo4(int a, int b) { }\n" "void Fred::foo5(int, int) { }"); - ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:9:12]: (performance, inconclusive) Technically the member function 'Fred::foo1' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n" - "[test.cpp:4:10] -> [test.cpp:10:12]: (performance, inconclusive) Technically the member function 'Fred::foo2' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n" - "[test.cpp:5:10] -> [test.cpp:11:12]: (performance, inconclusive) Technically the member function 'Fred::foo3' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n" - "[test.cpp:6:10] -> [test.cpp:12:12]: (performance, inconclusive) Technically the member function 'Fred::foo4' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n" - "[test.cpp:7:10] -> [test.cpp:13:12]: (performance, inconclusive) Technically the member function 'Fred::foo5' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:9:12]: (style) The member function 'Fred::foo1' can be static. [functionStatic]\n" + "[test.cpp:4:10] -> [test.cpp:10:12]: (style) The member function 'Fred::foo2' can be static. [functionStatic]\n" + "[test.cpp:5:10] -> [test.cpp:11:12]: (style) The member function 'Fred::foo3' can be static. [functionStatic]\n" + "[test.cpp:6:10] -> [test.cpp:12:12]: (style) The member function 'Fred::foo4' can be static. [functionStatic]\n" + "[test.cpp:7:10] -> [test.cpp:13:12]: (style) The member function 'Fred::foo5' can be static. [functionStatic]\n", errout_str()); // check nested classes checkConst("class Fred {\n" @@ -4245,7 +4245,7 @@ class TestClass : public TestFixture { "public:\n" " void foo() { }\n" "};"); - ASSERT_EQUALS("[test.cpp:4:10]: (performance, inconclusive) Technically the member function 'Fred::foo' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:4:10]: (style) The member function 'Fred::foo' can be static. [functionStatic]\n", errout_str()); checkConst("struct fast_string\n" "{\n" @@ -4682,7 +4682,7 @@ class TestClass : public TestFixture { "public:\n" " void set(int i) { x = i; }\n" "};"); - ASSERT_EQUALS("[test.cpp:4:10]: (performance, inconclusive) Technically the member function 'Fred::set' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:4:10]: (style) The member function 'Fred::set' can be static. [functionStatic]\n", errout_str()); } void const19() { @@ -4922,7 +4922,7 @@ class TestClass : public TestFixture { " UnknownScope::x = x_;\n" " }\n" "};"); - ASSERT_EQUALS("[test.cpp:4:17]: (performance, inconclusive) Technically the member function 'AA::vSetXPos' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:4:17]: (style) The member function 'AA::vSetXPos' can be static. [functionStatic]\n", errout_str()); } @@ -5097,7 +5097,7 @@ class TestClass : public TestFixture { "public:\n" " void f(){}\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Either there is a missing 'override', or the member function 'derived::f' can be static. [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) Either there is a missing 'override', or the member function 'derived::f' can be static. [functionStatic]\n", errout_str()); } void const34() { // ticket #1964 @@ -5350,7 +5350,7 @@ class TestClass : public TestFixture { "{\n" "}"); - ASSERT_EQUALS("[test.cpp:5:10] -> [test.cpp:7:12]: (performance, inconclusive) Technically the member function 'Fred::f' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:5:10] -> [test.cpp:7:12]: (style) The member function 'Fred::f' can be static. [functionStatic]\n", errout_str()); checkConst("class Fred\n" "{\n" @@ -5364,7 +5364,7 @@ class TestClass : public TestFixture { "{\n" "}"); - ASSERT_EQUALS("[test.cpp:7:10] -> [test.cpp:9:12]: (performance, inconclusive) Technically the member function 'Fred::f' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:7:10] -> [test.cpp:9:12]: (style) The member function 'Fred::f' can be static. [functionStatic]\n", errout_str()); checkConst("namespace NS {\n" " class Fred\n" @@ -5380,7 +5380,7 @@ class TestClass : public TestFixture { " }\n" "}"); - ASSERT_EQUALS("[test.cpp:8:14] -> [test.cpp:10:16]: (performance, inconclusive) Technically the member function 'NS::Fred::f' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:8:14] -> [test.cpp:10:16]: (style) The member function 'NS::Fred::f' can be static. [functionStatic]\n", errout_str()); checkConst("namespace NS {\n" " class Fred\n" @@ -5396,7 +5396,7 @@ class TestClass : public TestFixture { "{\n" "}"); - ASSERT_EQUALS("[test.cpp:8:14] -> [test.cpp:11:16]: (performance, inconclusive) Technically the member function 'NS::Fred::f' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:8:14] -> [test.cpp:11:16]: (style) The member function 'NS::Fred::f' can be static. [functionStatic]\n", errout_str()); checkConst("class Foo {\n" " class Fred\n" @@ -5412,7 +5412,7 @@ class TestClass : public TestFixture { "{\n" "}"); - ASSERT_EQUALS("[test.cpp:8:14] -> [test.cpp:11:17]: (performance, inconclusive) Technically the member function 'Foo::Fred::f' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:8:14] -> [test.cpp:11:17]: (style) The member function 'Foo::Fred::f' can be static. [functionStatic]\n", errout_str()); } void const43() { // ticket 2377 @@ -5501,7 +5501,7 @@ class TestClass : public TestFixture { " };\n" "}"); - ASSERT_EQUALS("[test.cpp:8:13]: (performance, inconclusive) Technically the member function 'tools::WorkspaceControl::toGrid' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:8:13]: (style) The member function 'tools::WorkspaceControl::toGrid' can be static. [functionStatic]\n", errout_str()); } void const46() { // ticket 2663 @@ -5516,8 +5516,8 @@ class TestClass : public TestFixture { " }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:9]: (performance, inconclusive) Technically the member function 'Altren::fun1' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n" - "[test.cpp:7:9]: (performance, inconclusive) Technically the member function 'Altren::fun2' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:9]: (style) The member function 'Altren::fun1' can be static. [functionStatic]\n" + "[test.cpp:7:9]: (style) The member function 'Altren::fun2' can be static. [functionStatic]\n", errout_str()); } void const47() { // ticket 2670 @@ -5528,7 +5528,7 @@ class TestClass : public TestFixture { " void bar() { foo(); }\n" "};"); - ASSERT_EQUALS("[test.cpp:4:8]: (performance, inconclusive) Technically the member function 'Altren::foo' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:4:8]: (style) The member function 'Altren::foo' can be static. [functionStatic]\n", errout_str()); checkConst("class Altren {\n" "public:\n" @@ -5537,7 +5537,7 @@ class TestClass : public TestFixture { " void bar() { foo(1); }\n" "};"); - ASSERT_EQUALS("[test.cpp:4:8]: (performance, inconclusive) Technically the member function 'Altren::foo' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n" + ASSERT_EQUALS("[test.cpp:4:8]: (style) The member function 'Altren::foo' can be static. [functionStatic]\n" "[test.cpp:5:8]: (style, inconclusive) Technically the member function 'Altren::bar' can be const. [functionConst]\n", errout_str()); } @@ -5628,7 +5628,7 @@ class TestClass : public TestFixture { "private:\n" " int bar;\n" "};"); - ASSERT_EQUALS("[test.cpp:2:10]: (performance, inconclusive) Technically the member function 'foo::DoSomething' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2:10]: (style) The member function 'foo::DoSomething' can be static. [functionStatic]\n", errout_str()); } void const53() { // ticket 3049 @@ -5672,7 +5672,7 @@ class TestClass : public TestFixture { " switch (x) { }\n" " }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'MyObject::foo' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'MyObject::foo' can be static. [functionStatic]\n", errout_str()); checkConst("class A\n" "{\n" @@ -5712,7 +5712,7 @@ class TestClass : public TestFixture { "\n" " return RET_NOK;\n" "}"); - ASSERT_EQUALS("[test.cpp:4:24] -> [test.cpp:9:19]: (performance, inconclusive) Technically the member function 'A::f' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:4:24] -> [test.cpp:9:19]: (style) The member function 'A::f' can be static. [functionStatic]\n", errout_str()); checkConst("class MyObject {\n" "public:\n" @@ -5720,7 +5720,7 @@ class TestClass : public TestFixture { " for (int i = 0; i < 5; i++) { }\n" " }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'MyObject::foo' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'MyObject::foo' can be static. [functionStatic]\n", errout_str()); } void const57() { // tickets #2669 and #2477 @@ -5745,9 +5745,9 @@ class TestClass : public TestFixture { "private:\n" " MyGUI::IntCoord mCoordValue;\n" "};"); - TODO_ASSERT_EQUALS("[test.cpp:7:13]: (performance, inconclusive) Technically the member function 'MyGUI::types::TCoord::size' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n" + TODO_ASSERT_EQUALS("[test.cpp:7:13]: (style) The member function 'MyGUI::types::TCoord::size' can be static. [functionStatic]\n" "[test.cpp:15]: (style, inconclusive) Technically the member function 'SelectorControl::getSize' can be const.\n", - "[test.cpp:7:13]: (performance, inconclusive) Technically the member function 'MyGUI::types::TCoord::size' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + "[test.cpp:7:13]: (style) The member function 'MyGUI::types::TCoord::size' can be static. [functionStatic]\n", errout_str()); checkConst("struct Foo {\n" " Bar b;\n" @@ -5778,7 +5778,7 @@ class TestClass : public TestFixture { " b.run();\n" " }\n" "};"); - ASSERT_EQUALS("[test.cpp:2:10]: (performance, inconclusive) Technically the member function 'Bar::run' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n" + ASSERT_EQUALS("[test.cpp:2:10]: (style) The member function 'Bar::run' can be static. [functionStatic]\n" "[test.cpp:6:10]: (style, inconclusive) Technically the member function 'Foo::foo' can be const. [functionConst]\n", errout_str()); } @@ -5788,14 +5788,14 @@ class TestClass : public TestFixture { " f.clear();\n" " }\n" "};"); - ASSERT_EQUALS("[test.cpp:2:10]: (performance, inconclusive) Technically the member function 'MyObject::foo' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2:10]: (style) The member function 'MyObject::foo' can be static. [functionStatic]\n", errout_str()); checkConst("struct MyObject {\n" " int foo(Foo f) {\n" " return f.length();\n" " }\n" "};"); - ASSERT_EQUALS("[test.cpp:2:9]: (performance, inconclusive) Technically the member function 'MyObject::foo' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2:9]: (style) The member function 'MyObject::foo' can be static. [functionStatic]\n", errout_str()); checkConst("struct MyObject {\n" " Foo f;\n" @@ -5883,7 +5883,7 @@ class TestClass : public TestFixture { " inherited::set(inherited::Key(key));\n" " }\n" "};\n", dinit(CheckConstOptions, $.inconclusive = false)); - ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:4:23]: (performance, inconclusive) Either there is a missing 'override', or the member function 'MixerParticipant::GetAudioFrame' can be static. [functionStatic]\n", + ASSERT_EQUALS("[test.cpp:2:9] -> [test.cpp:4:23]: (style) Either there is a missing 'override', or the member function 'MixerParticipant::GetAudioFrame' can be static. [functionStatic]\n", errout_str()); } @@ -6202,7 +6202,7 @@ class TestClass : public TestFixture { " if (N::i) {}\n" " }\n" "};\n"); - ASSERT_EQUALS("[test.cpp:4:10]: (performance, inconclusive) Technically the member function 'S::f' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:4:10]: (style) The member function 'S::f' can be static. [functionStatic]\n", errout_str()); checkConst("int i = 0;\n" "struct S {\n" @@ -6211,7 +6211,7 @@ class TestClass : public TestFixture { " if (::i) {}\n" " }\n" "};\n"); - ASSERT_EQUALS("[test.cpp:4:10]: (performance, inconclusive) Technically the member function 'S::f' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:4:10]: (style) The member function 'S::f' can be static. [functionStatic]\n", errout_str()); checkConst("namespace N {\n" " struct S {\n" @@ -6234,7 +6234,7 @@ class TestClass : public TestFixture { "void S::f(const T* t) {\n" " const_cast(t)->e();\n" "};\n"); - ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:7:9]: (performance, inconclusive) Technically the member function 'S::f' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", + ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:7:9]: (style) The member function 'S::f' can be static. [functionStatic]\n", errout_str()); } @@ -6280,7 +6280,7 @@ class TestClass : public TestFixture { " return nullptr;\n" " }\n" "};\n"); - ASSERT_EQUALS("[test.cpp:3:11]: (performance, inconclusive) Technically the member function 'A::f' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", + ASSERT_EQUALS("[test.cpp:3:11]: (style) The member function 'A::f' can be static. [functionStatic]\n", errout_str()); } @@ -6311,10 +6311,10 @@ class TestClass : public TestFixture { "void S::n() {\n" " this->h();\n" "}\n"); - ASSERT_EQUALS("[test.cpp:4:10] -> [test.cpp:11:9]: (performance, inconclusive) Technically the member function 'S::g' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n" - "[test.cpp:5:10] -> [test.cpp:14:9]: (performance, inconclusive) Technically the member function 'S::h' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n" + ASSERT_EQUALS("[test.cpp:4:10] -> [test.cpp:11:9]: (style) The member function 'S::g' can be static. [functionStatic]\n" + "[test.cpp:5:10] -> [test.cpp:14:9]: (style) The member function 'S::h' can be static. [functionStatic]\n" "[test.cpp:6:10] -> [test.cpp:17:9]: (style, inconclusive) Technically the member function 'S::k' can be const. [functionConst]\n" - "[test.cpp:7:10] -> [test.cpp:21:9]: (performance, inconclusive) Technically the member function 'S::m' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", + "[test.cpp:7:10] -> [test.cpp:21:9]: (style) The member function 'S::m' can be static. [functionStatic]\n", errout_str()); } @@ -6674,7 +6674,7 @@ class TestClass : public TestFixture { " }\n" "};\n"); ASSERT_EQUALS("[test.cpp:3:9]: (style, inconclusive) Technically the member function 'S::f' can be const. [functionConst]\n" - "[test.cpp:8:9]: (performance, inconclusive) Technically the member function 'S::g' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", + "[test.cpp:8:9]: (style) The member function 'S::g' can be static. [functionStatic]\n", errout_str()); checkConst("class C {\n" // #11653 @@ -6685,7 +6685,7 @@ class TestClass : public TestFixture { " if (b)\n" " f(false);\n" "}\n"); - ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:5:9]: (performance, inconclusive) Technically the member function 'C::f' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", + ASSERT_EQUALS("[test.cpp:3:10] -> [test.cpp:5:9]: (style) The member function 'C::f' can be static. [functionStatic]\n", errout_str()); } @@ -6948,8 +6948,8 @@ class TestClass : public TestFixture { " return foo3();\n" " }\n" "};"); - ASSERT_EQUALS("[test.cpp:11:9]: (performance, inconclusive) Technically the member function 'Foo::bar3' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n" - "[test.cpp:14:9]: (performance, inconclusive) Technically the member function 'Foo::bar4' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:11:9]: (style) The member function 'Foo::bar3' can be static. [functionStatic]\n" + "[test.cpp:14:9]: (style) The member function 'Foo::bar4' can be static. [functionStatic]\n", errout_str()); } void const_passThisToMemberOfOtherClass() { @@ -6967,7 +6967,7 @@ class TestClass : public TestFixture { " f.foo();\n" " }\n" "};"); - ASSERT_EQUALS("[test.cpp:2:10]: (performance, inconclusive) Technically the member function 'Foo::foo' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2:10]: (style) The member function 'Foo::foo' can be static. [functionStatic]\n", errout_str()); checkConst("struct A;\n" // #5839 - operator() "struct B {\n" @@ -7035,25 +7035,25 @@ class TestClass : public TestFixture { "class Fred {\n" " void nextA() { return ++a; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a;\n" "class Fred {\n" " void nextA() { return --a; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a;\n" "class Fred {\n" " void nextA() { return a++; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a;\n" "class Fred {\n" " void nextA() { return a--; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("struct S {\n" // #10077 " int i{};\n" @@ -7099,31 +7099,31 @@ class TestClass : public TestFixture { "class Fred {\n" " void nextA() { return a=1; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a;\n" "class Fred {\n" " void nextA() { return a-=1; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a;\n" "class Fred {\n" " void nextA() { return a+=1; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a;\n" "class Fred {\n" " void nextA() { return a*=-1; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a;\n" "class Fred {\n" " void nextA() { return a/=-2; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); } void constassign2() { @@ -7155,31 +7155,31 @@ class TestClass : public TestFixture { "class Fred {\n" " void nextA() { return s.a=1; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("struct A { int a; } s;\n" "class Fred {\n" " void nextA() { return s.a-=1; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("struct A { int a; } s;\n" "class Fred {\n" " void nextA() { return s.a+=1; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("struct A { int a; } s;\n" "class Fred {\n" " void nextA() { return s.a*=-1; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("struct A { int a; } s;\n" "class Fred {\n" " void nextA() { return s.a/=-2; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("struct A { int a; };\n" "class Fred {\n" @@ -7247,25 +7247,25 @@ class TestClass : public TestFixture { "class Fred {\n" " void nextA() { return ++a[0]; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a[2];\n" "class Fred {\n" " void nextA() { return --a[0]; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a[2];\n" "class Fred {\n" " void nextA() { return a[0]++; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a[2];\n" "class Fred {\n" " void nextA() { return a[0]--; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); } void constassignarray() { @@ -7303,31 +7303,31 @@ class TestClass : public TestFixture { "class Fred {\n" " void nextA() { return a[0]=1; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a[2];\n" "class Fred {\n" " void nextA() { return a[0]-=1; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a[2];\n" "class Fred {\n" " void nextA() { return a[0]+=1; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a[2];\n" "class Fred {\n" " void nextA() { return a[0]*=-1; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); checkConst("int a[2];\n" "class Fred {\n" " void nextA() { return a[0]/=-2; }\n" "};"); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'Fred::nextA' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'Fred::nextA' can be static. [functionStatic]\n", errout_str()); } // return pointer/reference => not const @@ -7354,7 +7354,7 @@ class TestClass : public TestFixture { checkConst("class Fred {\n" " UNKNOWN a() { return 0; };\n" "};"); - TODO_ASSERT_EQUALS("[test.cpp:2]: (performance, inconclusive) Technically the member function 'Fred::a' can be static.\n", "", errout_str()); + TODO_ASSERT_EQUALS("[test.cpp:2]: (style) The member function 'Fred::a' can be static.\n", "", errout_str()); // #1579 - HDC checkConst("class Fred {\n" @@ -7370,7 +7370,7 @@ class TestClass : public TestFixture { " void f() const { };\n" " void a() { f(); };\n" "};"); - ASSERT_EQUALS("[test.cpp:2:10]: (performance, inconclusive) Technically the member function 'Fred::f' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n" + ASSERT_EQUALS("[test.cpp:2:10]: (style) The member function 'Fred::f' can be static. [functionStatic]\n" "[test.cpp:3:10]: (style, inconclusive) Technically the member function 'Fred::a' can be const. [functionConst]\n", errout_str()); // ticket #1593 @@ -7631,10 +7631,10 @@ class TestClass : public TestFixture { "};"; checkConst(code); - ASSERT_EQUALS("[test.cpp:3:10]: (performance, inconclusive) Technically the member function 'foo::f' can be static (but you may consider moving to unnamed namespace). [functionStatic]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'foo::f' can be static. [functionStatic]\n", errout_str()); - checkConst(code, dinit(CheckConstOptions, $.inconclusive = false)); // TODO: Set inconclusive to true (preprocess it) - ASSERT_EQUALS("", errout_str()); + checkConst(code, dinit(CheckConstOptions, $.inconclusive = false)); + ASSERT_EQUALS("[test.cpp:3:10]: (style) The member function 'foo::f' can be static. [functionStatic]\n", errout_str()); } void constFriend() { // ticket #1921 From 6ef134b9fef648961312df126c76a30055275ac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 22 Nov 2025 12:42:16 +0100 Subject: [PATCH 2/2] fix --- test/cli/proj-inline-suppress-unusedFunction/B.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cli/proj-inline-suppress-unusedFunction/B.hpp b/test/cli/proj-inline-suppress-unusedFunction/B.hpp index aca79e88167..71fad0ab3fd 100644 --- a/test/cli/proj-inline-suppress-unusedFunction/B.hpp +++ b/test/cli/proj-inline-suppress-unusedFunction/B.hpp @@ -2,5 +2,5 @@ class B { public: B(); - void unusedFunctionTest(); + static void unusedFunctionTest(); };