From 3773d0e875c36347a93f4c9538dc7e9027cce9c2 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Tue, 7 Apr 2020 00:15:15 -0500 Subject: [PATCH] Find more redundant conditions (#2597) --- lib/checkcondition.cpp | 27 +++++++++++++++++++++++++++ test/testcondition.cpp | 10 ++++++++++ 2 files changed, 37 insertions(+) diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index cde8df023..111ce80dc 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -1054,6 +1054,8 @@ void CheckCondition::checkIncorrectLogicOperator() // 'A && (!A || B)' is equivalent to 'A && B' // 'A || (!A && B)' is equivalent to 'A || B' + // 'A && (A || B)' is equivalent to 'A' + // 'A || (A && B)' is equivalent to 'A' if (printStyle && ((tok->str() == "||" && tok->astOperand2()->str() == "&&") || (tok->str() == "&&" && tok->astOperand2()->str() == "||"))) { @@ -1089,6 +1091,31 @@ void CheckCondition::checkIncorrectLogicOperator() "The condition '" + cond1VerboseMsg + "' is equivalent to '" + cond2VerboseMsg + "'."; redundantConditionError(tok, msg, false); continue; + } else if (isSameExpression(mTokenizer->isCPP(), false, tok->astOperand1(), tok2, mSettings->library, true, true)) { + std::string expr1(tok->astOperand1()->expressionString()); + std::string expr2(tok->astOperand2()->astOperand1()->expressionString()); + std::string expr3(tok->astOperand2()->astOperand2()->expressionString()); + // make copy for later because the original string might get overwritten + const std::string expr1VerboseMsg = expr1; + const std::string expr2VerboseMsg = expr2; + const std::string expr3VerboseMsg = expr3; + + if (expr1.length() + expr2.length() + expr3.length() > 50U) { + expr1 = "A"; + expr2 = "A"; + expr3 = "B"; + } + + const std::string cond1 = expr1 + " " + tok->str() + " (" + expr2 + " " + tok->astOperand2()->str() + " " + expr3 + ")"; + const std::string cond2 = expr1; + + const std::string cond1VerboseMsg = expr1VerboseMsg + " " + tok->str() + " " + expr2VerboseMsg + " " + tok->astOperand2()->str() + " " + expr3VerboseMsg; + const std::string cond2VerboseMsg = expr1VerboseMsg; + // for the --verbose message, transform the actual condition and print it + const std::string msg = tok2->expressionString() + ". '" + cond1 + "' is equivalent to '" + cond2 + "'\n" + "The condition '" + cond1VerboseMsg + "' is equivalent to '" + cond2VerboseMsg + "'."; + redundantConditionError(tok, msg, false); + continue; } } diff --git a/test/testcondition.cpp b/test/testcondition.cpp index e7a970e7b..ef59086d7 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -2689,6 +2689,16 @@ private: " if (!x || (x && (2>(y-1)))) {}\n" "}"); ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: x. '!x || (x && 2>(y-1))' is equivalent to '!x || 2>(y-1)'\n", errout.str()); + + check("void f(bool a, bool b) {\n" + " if (a || (a && b)) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: a. 'a || (a && b)' is equivalent to 'a'\n", errout.str()); + + check("void f(bool a, bool b) {\n" + " if (a && (a || b)) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: a. 'a && (a || b)' is equivalent to 'a'\n", errout.str()); } // clarify conditions with bitwise operator and comparison