diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 51124c45d1c..d4670ffc317 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2323,18 +2323,12 @@ static bool isConstStatement(const Token *tok, const Library& library, bool plat static bool isVoidStmt(const Token *tok) { - if (Token::simpleMatch(tok, "( void")) + if (Token::simpleMatch(tok, "( void") && !(tok->astOperand1() && (tok->astOperand1()->isLiteral() || isNullOperand(tok->astOperand1())))) return true; - if (isCPPCast(tok) && tok->astOperand1() && Token::Match(tok->astOperand1()->next(), "< void *| >")) + if (isCPPCast(tok) && tok->astOperand1() && Token::Match(tok->astOperand1()->next(), "< void *| >") && + !(tok->astOperand2() && (tok->astOperand2()->isLiteral() || isNullOperand(tok->astOperand2())))) return true; - const Token *tok2 = tok; - while (tok2->astOperand1()) - tok2 = tok2->astOperand1(); - if (Token::simpleMatch(tok2->previous(), ")") && Token::simpleMatch(tok2->linkAt(-1), "( void")) - return true; - if (Token::simpleMatch(tok2, "( void")) - return true; - return Token::Match(tok2->previous(), "delete|throw|return"); + return false; } static bool isConstTop(const Token *tok) @@ -2425,10 +2419,6 @@ void CheckOtherImpl::checkIncompleteStatement() void CheckOtherImpl::constStatementError(const Token *tok, const std::string &type, bool inconclusive) { - const Token *valueTok = tok; - while (valueTok && valueTok->isCast()) - valueTok = valueTok->astOperand2() ? valueTok->astOperand2() : valueTok->astOperand1(); - std::string msg; if (Token::simpleMatch(tok, "==")) msg = "Found suspicious equality comparison. Did you intend to assign a value instead?"; @@ -2436,26 +2426,24 @@ void CheckOtherImpl::constStatementError(const Token *tok, const std::string &ty msg = "Found suspicious operator '" + tok->str() + "', result is not used."; else if (Token::Match(tok, "%var%")) msg = "Unused variable value '" + tok->str() + "'"; - else if (isConstant(valueTok)) { + else if (isConstant(tok)) { std::string typeStr("string"); - if (valueTok->isNumber()) + if (tok->isNumber()) typeStr = "numeric"; - else if (valueTok->isBoolean()) + else if (tok->isBoolean()) typeStr = "bool"; - else if (valueTok->tokType() == Token::eChar) + else if (tok->tokType() == Token::eChar) typeStr = "character"; - else if (isNullOperand(valueTok)) - typeStr = "NULL"; - else if (valueTok->isEnumerator()) + else if (isNullOperand(tok)) + typeStr = "null"; + else if (tok->isEnumerator()) typeStr = "enumerator"; msg = "Redundant code: Found a statement that begins with " + typeStr + " constant."; } else if (!tok) msg = "Redundant code: Found a statement that begins with " + type + " constant."; - else if (tok->isCast() && tok->tokType() == Token::Type::eExtendedOp) { - msg = "Redundant code: Found unused cast "; - msg += valueTok ? "of expression '" + valueTok->expressionString() + "'." : "expression."; - } + else if (tok->isCast() && tok->tokType() == Token::Type::eExtendedOp) + msg = "Redundant code: Found unused cast in expression '" + tok->expressionString() + "'."; else if (tok->str() == "?" && tok->tokType() == Token::Type::eExtendedOp) msg = "Redundant code: Found unused result of ternary operator."; else if (tok->str() == "." && tok->tokType() == Token::Type::eOther) diff --git a/test/cli/proj-inline-suppress/cfg.c b/test/cli/proj-inline-suppress/cfg.c index b597217fa32..42709095dcf 100644 --- a/test/cli/proj-inline-suppress/cfg.c +++ b/test/cli/proj-inline-suppress/cfg.c @@ -2,9 +2,9 @@ void f() { #if DEF_1 // cppcheck-suppress id - (void)0; + ; #endif // cppcheck-suppress id - (void)0; + ; } diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index b72b6524872..366e1b0a39a 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -180,9 +180,25 @@ class TestIncompleteStatement : public TestFixture { } void void0() { // #6327 - check("void f() { (void*)0; }"); + check("#define assert(x) ((void)0)\n" + "void f(int* p) {\n" + " assert(p);\n" + "}\n"); ASSERT_EQUALS("", errout_str()); + check("void f() { (void*)0; }"); + ASSERT_EQUALS("[test.cpp:1:12]: (warning) Redundant code: Found unused cast in expression '(void*)0'. [constStatement]\n", errout_str()); + + check("void f() {\n" // #13148 + " static_cast(1);\n" + " static_cast(nullptr);\n" + " (void)NULL;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:22]: (warning) Redundant code: Found unused cast in expression 'static_cast(1)'. [constStatement]\n" + "[test.cpp:3:22]: (warning) Redundant code: Found unused cast in expression 'static_cast(nullptr)'. [constStatement]\n" + "[test.cpp:4:5]: (warning) Redundant code: Found unused cast in expression '(void)NULL'. [constStatement]\n", + errout_str()); + check("#define X 0\n" "void f() { X; }"); ASSERT_EQUALS("", errout_str()); @@ -432,11 +448,11 @@ class TestIncompleteStatement : public TestFixture { "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("[test.cpp:2:5]: (warning) Redundant code: Found a statement that begins with numeric constant. [constStatement]\n" "[test.cpp:3:6]: (warning) Redundant code: Found a statement that begins with numeric constant. [constStatement]\n" - "[test.cpp:4:5]: (warning) Redundant code: Found a statement that begins with numeric constant. [constStatement]\n" - "[test.cpp:5:6]: (warning) Redundant code: Found a statement that begins with numeric constant. [constStatement]\n" + "[test.cpp:4:5]: (warning) Redundant code: Found unused cast in expression '(char)1'. [constStatement]\n" + "[test.cpp:5:6]: (warning) Redundant code: Found unused cast in expression '(char)1'. [constStatement]\n" "[test.cpp:6:5]: (warning, inconclusive) Found suspicious operator '!', result is not used. [constStatement]\n" "[test.cpp:7:6]: (warning, inconclusive) Found suspicious operator '!', result is not used. [constStatement]\n" - "[test.cpp:8:5]: (warning) Redundant code: Found unused cast of expression '!x'. [constStatement]\n" + "[test.cpp:8:5]: (warning) Redundant code: Found unused cast in expression '(unsigned int)!x'. [constStatement]\n" "[test.cpp:9:5]: (warning, inconclusive) Found suspicious operator '~', result is not used. [constStatement]\n", errout_str()); @@ -447,7 +463,7 @@ class TestIncompleteStatement : public TestFixture { ASSERT_EQUALS("", errout_str()); check("void f(int x) { static_cast(x); }"); - ASSERT_EQUALS("[test.cpp:1:38]: (warning) Redundant code: Found unused cast of expression 'x'. [constStatement]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:1:38]: (warning) Redundant code: Found unused cast in expression 'static_cast(x)'. [constStatement]\n", errout_str()); check("void f(int x, int* p) {\n" " static_cast(x);\n" @@ -465,9 +481,9 @@ class TestIncompleteStatement : public TestFixture { " static_cast((char)i);\n" " (char)static_cast(i);\n" "}\n"); - ASSERT_EQUALS("[test.cpp:2:5]: (warning) Redundant code: Found unused cast of expression 'i'. [constStatement]\n" - "[test.cpp:3:23]: (warning) Redundant code: Found unused cast of expression 'i'. [constStatement]\n" - "[test.cpp:4:5]: (warning) Redundant code: Found unused cast of expression 'i'. [constStatement]\n", + ASSERT_EQUALS("[test.cpp:2:5]: (warning) Redundant code: Found unused cast in expression '(float)(char)i'. [constStatement]\n" + "[test.cpp:3:23]: (warning) Redundant code: Found unused cast in expression 'static_cast((char)i)'. [constStatement]\n" + "[test.cpp:4:5]: (warning) Redundant code: Found unused cast in expression '(char)static_cast(i)'. [constStatement]\n", errout_str()); check("namespace M {\n" @@ -476,7 +492,7 @@ class TestIncompleteStatement : public TestFixture { "void f(int i) {\n" " (M::N::T)i;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:5:5]: (warning) Redundant code: Found unused cast of expression 'i'. [constStatement]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:5:5]: (warning) Redundant code: Found unused cast in expression '(char)i'. [constStatement]\n", errout_str()); check("void f(int (g)(int a, int b)) {\n" // #10873 " int p = 0, q = 1;\n" @@ -528,7 +544,7 @@ class TestIncompleteStatement : public TestFixture { " for (L\"y\"; ;) {}\n" "}\n"); ASSERT_EQUALS("[test.cpp:2:10]: (warning) Unused variable value 'i' [constStatement]\n" - "[test.cpp:3:10]: (warning) Redundant code: Found unused cast of expression 'i'. [constStatement]\n" + "[test.cpp:3:10]: (warning) Redundant code: Found unused cast in expression '(long)i'. [constStatement]\n" "[test.cpp:4:10]: (warning) Redundant code: Found a statement that begins with numeric constant. [constStatement]\n" "[test.cpp:5:10]: (warning) Redundant code: Found a statement that begins with bool constant. [constStatement]\n" "[test.cpp:6:10]: (warning) Redundant code: Found a statement that begins with character constant. [constStatement]\n" @@ -696,8 +712,8 @@ class TestIncompleteStatement : public TestFixture { " NULL;\n" " nullptr;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:2:5]: (warning) Redundant code: Found a statement that begins with NULL constant. [constStatement]\n" - "[test.cpp:3:5]: (warning) Redundant code: Found a statement that begins with NULL constant. [constStatement]\n", + ASSERT_EQUALS("[test.cpp:2:5]: (warning) Redundant code: Found a statement that begins with null constant. [constStatement]\n" + "[test.cpp:3:5]: (warning) Redundant code: Found a statement that begins with null constant. [constStatement]\n", errout_str()); check("struct S { int i; };\n" // #6504 diff --git a/test/testother.cpp b/test/testother.cpp index fa6899cf543..286a0c0550b 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -3914,7 +3914,9 @@ class TestOther : public TestFixture { " (void)(true);\n" " if (r) {}\n" "}\n"); - ASSERT_EQUALS("[test.cpp:1:13]: (style) Parameter 'r' can be declared as reference to const [constParameterReference]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:2:5]: (warning) Redundant code: Found unused cast in expression '(void)(true)'. [constStatement]\n" + "[test.cpp:1:13]: (style) Parameter 'r' can be declared as reference to const [constParameterReference]\n", + errout_str()); check("struct S { void f(int&); };\n" // #12216 "void g(S& s, int& r, void (S::* p2m)(int&)) {\n" @@ -7012,7 +7014,8 @@ class TestOther : public TestFixture { " std::pair(1, 2);\n" " (void)0;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:2:10]: (style) Instance of 'std::string' object is destroyed immediately. [unusedScopedObject]\n" + ASSERT_EQUALS("[test.cpp:5:5]: (warning) Redundant code: Found unused cast in expression '(void)0'. [constStatement]\n" + "[test.cpp:2:10]: (style) Instance of 'std::string' object is destroyed immediately. [unusedScopedObject]\n" "[test.cpp:3:10]: (style) Instance of 'std::string' object is destroyed immediately. [unusedScopedObject]\n" "[test.cpp:4:10]: (style) Instance of 'std::pair' object is destroyed immediately. [unusedScopedObject]\n", errout_str());