New warning: warn about redundant code in condition.
This commit is contained in:
parent
6ba2534f32
commit
cae605b1ec
|
@ -607,6 +607,12 @@ void CheckCondition::checkIncorrectLogicOperator()
|
|||
}
|
||||
|
||||
else if (Token::Match(tok, "&&|%oror%")) {
|
||||
if (tok->str() == "||" && tok->astOperand1() && tok->astOperand2() && tok->astOperand2()->str() == "&&") {
|
||||
const Token* tok2 = tok->astOperand2()->astOperand1();
|
||||
if (isOppositeCond(tok->astOperand1(), tok2, _settings->library.functionpure)) {
|
||||
redundantConditionError(tok, tok2->expressionString() + ". 'A && (!A || B)' is equivalent to 'A || B'");
|
||||
}
|
||||
}
|
||||
// Comparison #1 (LHS)
|
||||
const Token *comp1 = tok->astOperand1();
|
||||
if (comp1 && comp1->str() == tok->str())
|
||||
|
|
|
@ -1178,7 +1178,7 @@ std::string Token::expressionString() const
|
|||
{
|
||||
const Token * const top = this;
|
||||
const Token *start = top;
|
||||
while (start->astOperand1() && start->astOperand2())
|
||||
while (start->astOperand1() && (start->astOperand2() || Token::simpleMatch(start, "( )")))
|
||||
start = start->astOperand1();
|
||||
const Token *end = top;
|
||||
while (end->astOperand1() && (end->astOperand2() || end->isUnaryPreOp())) {
|
||||
|
|
|
@ -1281,6 +1281,60 @@ private:
|
|||
" if (x = b < 0 ? 1 : 2) {}\n" // don't simplify and verify this code
|
||||
"}", false);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f() {\n"
|
||||
" int y = rand(), z = rand();\n"
|
||||
" if (y || (!y && z));\n"
|
||||
"}", false);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (style) Redundant condition: !y. 'A && (!A || B)' is equivalent to 'A || B'\n", errout.str());
|
||||
|
||||
check("void f() {\n"
|
||||
" int y = rand(), z = rand();\n"
|
||||
" if (y || !y && z);\n"
|
||||
"}", false);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (style) Redundant condition: !y. 'A && (!A || B)' is equivalent to 'A || B'\n", errout.str());
|
||||
|
||||
check("void f() {\n"
|
||||
" if (!a || a && b) {}\n"
|
||||
"}", false);
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: a. 'A && (!A || B)' is equivalent to 'A || B'\n", errout.str());
|
||||
|
||||
|
||||
check("void f() {\n"
|
||||
" if (!tok->next()->function() || \n"
|
||||
" (tok->next()->function() && tok->next()->function()->isConstructor()));\n"
|
||||
"}", false);
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: tok.next().function(). 'A && (!A || B)' is equivalent to 'A || B'\n", errout.str());
|
||||
|
||||
check("void f() {\n"
|
||||
" if (!tok->next()->function() || \n"
|
||||
" (!tok->next()->function() && tok->next()->function()->isConstructor()));\n"
|
||||
"}", false);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f() {\n"
|
||||
" if (!tok->next()->function() || \n"
|
||||
" (!tok2->next()->function() && tok->next()->function()->isConstructor()));\n"
|
||||
"}", false);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f() {\n"
|
||||
" if (!tok->next(1)->function(1) || \n"
|
||||
" (tok->next(1)->function(1) && tok->next(1)->function(1)->isConstructor()));\n"
|
||||
"}", false);
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: tok.next(1).function(1). 'A && (!A || B)' is equivalent to 'A || B'\n", errout.str());
|
||||
|
||||
check("void f() {\n"
|
||||
" if (!tok->next()->function(1) || \n"
|
||||
" (tok->next()->function(2) && tok->next()->function()->isConstructor()));\n"
|
||||
"}", false);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f() {\n"
|
||||
" int y = rand(), z = rand();\n"
|
||||
" if (y==0 || y!=0 && z);\n"
|
||||
"}", false);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (style) Redundant condition: y. 'A && (!A || B)' is equivalent to 'A || B'\n", errout.str());
|
||||
}
|
||||
|
||||
// clarify conditions with bitwise operator and comparison
|
||||
|
|
Loading…
Reference in New Issue