Fixed #6764 (False positive redundantCondition - !(i>1) is not i<1)
This commit is contained in:
parent
02df692b0b
commit
af4a4663e2
|
@ -358,7 +358,13 @@ void CheckCondition::multiConditionError(const Token *tok, unsigned int line1)
|
||||||
// Detect oppositing inner and outer conditions
|
// Detect oppositing inner and outer conditions
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
static bool isOppositeCond(const Token * const cond1, const Token * const cond2, const std::set<std::string> &constFunctions)
|
/**
|
||||||
|
* Are two conditions opposite
|
||||||
|
* @param isNot do you want to know if cond1 is !cond2 or if cond1 and cond2 are non-overlapping. true: cond1==!cond2 false: cond1==true => cond2==false
|
||||||
|
* @param cond1 condition1
|
||||||
|
* @param cond2 condition2
|
||||||
|
*/
|
||||||
|
static bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const cond2, const std::set<std::string> &constFunctions)
|
||||||
{
|
{
|
||||||
if (!cond1 || !cond2)
|
if (!cond1 || !cond2)
|
||||||
return false;
|
return false;
|
||||||
|
@ -392,11 +398,11 @@ static bool isOppositeCond(const Token * const cond1, const Token * const cond2,
|
||||||
return ((comp1 == "==" && comp2 == "!=") ||
|
return ((comp1 == "==" && comp2 == "!=") ||
|
||||||
(comp1 == "!=" && comp2 == "==") ||
|
(comp1 == "!=" && comp2 == "==") ||
|
||||||
(comp1 == "<" && comp2 == ">=") ||
|
(comp1 == "<" && comp2 == ">=") ||
|
||||||
(comp1 == "<" && comp2 == ">") ||
|
|
||||||
(comp1 == "<=" && comp2 == ">") ||
|
(comp1 == "<=" && comp2 == ">") ||
|
||||||
(comp1 == ">" && comp2 == "<=") ||
|
(comp1 == ">" && comp2 == "<=") ||
|
||||||
(comp1 == ">" && comp2 == "<") ||
|
(comp1 == ">=" && comp2 == "<") ||
|
||||||
(comp1 == ">=" && comp2 == "<"));
|
(!isNot && ((comp1 == "<" && comp2 == ">") ||
|
||||||
|
(comp1 == ">" && comp2 == "<"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckCondition::oppositeInnerCondition()
|
void CheckCondition::oppositeInnerCondition()
|
||||||
|
@ -488,7 +494,7 @@ void CheckCondition::oppositeInnerCondition()
|
||||||
const Token *cond1 = scope->classDef->next()->astOperand2();
|
const Token *cond1 = scope->classDef->next()->astOperand2();
|
||||||
const Token *cond2 = ifToken->next()->astOperand2();
|
const Token *cond2 = ifToken->next()->astOperand2();
|
||||||
|
|
||||||
if (isOppositeCond(cond1, cond2, _settings->library.functionpure))
|
if (isOppositeCond(false, cond1, cond2, _settings->library.functionpure))
|
||||||
oppositeInnerConditionError(scope->classDef, cond2);
|
oppositeInnerConditionError(scope->classDef, cond2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -624,7 +630,7 @@ void CheckCondition::checkIncorrectLogicOperator()
|
||||||
tok->astOperand1() &&
|
tok->astOperand1() &&
|
||||||
tok->astOperand2() &&
|
tok->astOperand2() &&
|
||||||
(tok->astOperand1()->isName() || tok->astOperand2()->isName()) &&
|
(tok->astOperand1()->isName() || tok->astOperand2()->isName()) &&
|
||||||
isOppositeCond(tok->astOperand1(), tok->astOperand2(), _settings->library.functionpure)) {
|
isOppositeCond(true, tok->astOperand1(), tok->astOperand2(), _settings->library.functionpure)) {
|
||||||
|
|
||||||
const bool alwaysTrue(tok->str() == "||");
|
const bool alwaysTrue(tok->str() == "||");
|
||||||
incorrectLogicOperatorError(tok, tok->expressionString(), alwaysTrue);
|
incorrectLogicOperatorError(tok, tok->expressionString(), alwaysTrue);
|
||||||
|
@ -633,7 +639,7 @@ void CheckCondition::checkIncorrectLogicOperator()
|
||||||
else if (Token::Match(tok, "&&|%oror%")) {
|
else if (Token::Match(tok, "&&|%oror%")) {
|
||||||
if (printStyle && (tok->str() == "||") && tok->astOperand1() && tok->astOperand2() && tok->astOperand2()->str() == "&&") {
|
if (printStyle && (tok->str() == "||") && tok->astOperand1() && tok->astOperand2() && tok->astOperand2()->str() == "&&") {
|
||||||
const Token* tok2 = tok->astOperand2()->astOperand1();
|
const Token* tok2 = tok->astOperand2()->astOperand1();
|
||||||
if (isOppositeCond(tok->astOperand1(), tok2, _settings->library.functionpure)) {
|
if (isOppositeCond(true, tok->astOperand1(), tok2, _settings->library.functionpure)) {
|
||||||
redundantConditionError(tok, tok2->expressionString() + ". 'A && (!A || B)' is equivalent to 'A || B'");
|
redundantConditionError(tok, tok2->expressionString() + ". 'A && (!A || B)' is equivalent to 'A || B'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -897,6 +897,16 @@ private:
|
||||||
" if (i || !i) {}\n"
|
" if (i || !i) {}\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: i||!i.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: i||!i.\n", errout.str());
|
||||||
|
|
||||||
|
check("void f(int a, int b) {\n"
|
||||||
|
" if (a>b || a<=b) {}\n"
|
||||||
|
"}");
|
||||||
|
TODO_ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: a>b||a<=b.\n", "", errout.str());
|
||||||
|
|
||||||
|
check("void f(int a, int b) {\n"
|
||||||
|
" if (a>b || a<b) {}\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void secondAlwaysTrueFalseWhenFirstTrueError() {
|
void secondAlwaysTrueFalseWhenFirstTrueError() {
|
||||||
|
@ -1343,6 +1353,11 @@ private:
|
||||||
" if (y==0 || y!=0 && z);\n"
|
" if (y==0 || y!=0 && z);\n"
|
||||||
"}", false);
|
"}", false);
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Redundant condition: y. 'A && (!A || B)' is equivalent to 'A || B'\n", errout.str());
|
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 (x>0 || (x<0 && y)) {}\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// clarify conditions with bitwise operator and comparison
|
// clarify conditions with bitwise operator and comparison
|
||||||
|
|
Loading…
Reference in New Issue