From d3d40fd599465461e4b1bd63e3fed2170abfe225 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 14 Mar 2022 14:14:32 +0100 Subject: [PATCH] Fix #10868/#10869 FN: constStatement, handle unused character constants (#3898) * Fix #10868 FN: constStatement, handle unused character constants * simpleMatch * Fix #10869 FN: constStatement * Format --- lib/checkother.cpp | 13 +++++++--- test/testincompletestatement.cpp | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index a928358bc..814b8edd9 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1763,7 +1763,7 @@ static bool isConstStatement(const Token *tok, bool cpp) return isWithoutSideEffects(cpp, tok->astOperand1()) && isConstStatement(tok->astOperand1(), cpp); if (Token::Match(tok, "( %type%")) return isConstStatement(tok->astOperand1(), cpp); - if (Token::simpleMatch(tok, ",")) + if (Token::Match(tok, ",|.")) return isConstStatement(tok->astOperand2(), cpp); if (Token::simpleMatch(tok, "?") && Token::simpleMatch(tok->astOperand2(), ":")) // ternary operator return isConstStatement(tok->astOperand1(), cpp) && isConstStatement(tok->astOperand2()->astOperand1(), cpp) && isConstStatement(tok->astOperand2()->astOperand2(), cpp); @@ -1838,7 +1838,10 @@ void CheckOther::checkIncompleteStatement() const Token *rtok = nextAfterAstRightmostLeaf(tok); if (!Token::simpleMatch(tok->astParent(), ";") && !Token::simpleMatch(rtok, ";") && - !Token::Match(tok->previous(), ";|}|{ %any% ;") && !(mTokenizer->isCPP() && tok->isCast() && !tok->astParent())) + !Token::Match(tok->previous(), ";|}|{ %any% ;") && + !(mTokenizer->isCPP() && tok->isCast() && !tok->astParent()) && + !Token::simpleMatch(tok->tokAt(-2), "for (") && + !Token::Match(tok->tokAt(-1), "%var% [")) continue; // Skip statement expressions if (Token::simpleMatch(rtok, "; } )")) @@ -1869,12 +1872,14 @@ void CheckOther::constStatementError(const Token *tok, const std::string &type, msg = "Found suspicious operator '" + tok->str() + "'"; else if (Token::Match(tok, "%var%")) msg = "Unused variable value '" + tok->str() + "'"; - else if (Token::Match(valueTok, "%str%|%num%|%bool%")) { + else if (Token::Match(valueTok, "%str%|%num%|%bool%|%char%")) { std::string typeStr("string"); if (valueTok->isNumber()) typeStr = "numeric"; else if (valueTok->isBoolean()) typeStr = "bool"; + else if (valueTok->tokType() == Token::eChar) + typeStr = "character"; msg = "Redundant code: Found a statement that begins with " + typeStr + " constant."; } else if (!tok) @@ -1885,6 +1890,8 @@ void CheckOther::constStatementError(const Token *tok, const std::string &type, } 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) + msg = "Redundant code: Found unused member access."; else { reportError(tok, Severity::debug, "debug", "constStatementError not handled."); return; diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index c16b713a2..7bac14db0 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -429,6 +429,49 @@ private: " b = (b ? true : false);\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("void f(int i) {\n" + " for (i; ;) {}\n" + " for ((long)i; ;) {}\n" + " for (1; ;) {}\n" + " for (true; ;) {}\n" + " for ('a'; ;) {}\n" + " for (L'b'; ;) {}\n" + " for (\"x\"; ;) {}\n" + " for (L\"y\"; ;) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2]: (warning) Unused variable value 'i'\n" + "[test.cpp:3]: (warning) Redundant code: Found unused cast of expression 'i'.\n" + "[test.cpp:4]: (warning) Redundant code: Found a statement that begins with numeric constant.\n" + "[test.cpp:5]: (warning) Redundant code: Found a statement that begins with bool constant.\n" + "[test.cpp:6]: (warning) Redundant code: Found a statement that begins with character constant.\n" + "[test.cpp:7]: (warning) Redundant code: Found a statement that begins with character constant.\n" + "[test.cpp:8]: (warning) Redundant code: Found a statement that begins with string constant.\n" + "[test.cpp:9]: (warning) Redundant code: Found a statement that begins with string constant.\n", + errout.str()); + + check("struct S { bool b{}; };\n" + "struct T {\n" + " S s[2];\n" + " void g();\n" + "};\n" + "void f(const S& r, const S* p) {\n" + " r.b;\n" + " p->b;\n" + " S s;\n" + " (s.b);\n" + " T t, u[2];\n" + " t.s[1].b;\n" + " t.g();\n" + " u[0].g();\n" + " u[1].s[0].b;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:7]: (warning) Redundant code: Found unused member access.\n" + "[test.cpp:8]: (warning) Redundant code: Found unused member access.\n" + "[test.cpp:10]: (warning) Redundant code: Found unused member access.\n" + "[test.cpp:12]: (warning) Redundant code: Found unused member access.\n" + "[test.cpp:15]: (warning) Redundant code: Found unused member access.\n", + errout.str()); } void vardecl() {