Fixed #8735 (FP oppositeInnerCondition - regression)
This commit is contained in:
parent
d9e1cc957b
commit
f961324d45
|
@ -166,6 +166,21 @@ static bool isAliased(const Token * startTok, const Token * endTok, unsigned int
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool exprDependsOnThis(const Token *expr)
|
||||||
|
{
|
||||||
|
if (!expr)
|
||||||
|
return false;
|
||||||
|
// calling nonstatic method?
|
||||||
|
if (Token::Match(expr->previous(), "!!:: %name% (") && expr->function() && expr->function()->nestedIn && expr->function()->nestedIn->isClassOrStruct()) {
|
||||||
|
// is it a method of this?
|
||||||
|
const Scope *nestedIn = expr->scope();
|
||||||
|
while (nestedIn && nestedIn != expr->function()->nestedIn)
|
||||||
|
nestedIn = nestedIn->nestedIn;
|
||||||
|
return nestedIn == expr->function()->nestedIn;
|
||||||
|
}
|
||||||
|
return exprDependsOnThis(expr->astOperand1()) || exprDependsOnThis(expr->astOperand2());
|
||||||
|
}
|
||||||
|
|
||||||
/// This takes a token that refers to a variable and it will return the token
|
/// This takes a token that refers to a variable and it will return the token
|
||||||
/// to the expression that the variable is assigned to. If its not valid to
|
/// to the expression that the variable is assigned to. If its not valid to
|
||||||
/// make such substitution then it will return the original token.
|
/// make such substitution then it will return the original token.
|
||||||
|
@ -189,6 +204,9 @@ static const Token * followVariableExpression(const Token * tok, bool cpp, const
|
||||||
const Token * varTok = getVariableInitExpression(var);
|
const Token * varTok = getVariableInitExpression(var);
|
||||||
if (!varTok)
|
if (!varTok)
|
||||||
return tok;
|
return tok;
|
||||||
|
// Bailout. If variable value depends on value of "this".
|
||||||
|
if (exprDependsOnThis(varTok))
|
||||||
|
return tok;
|
||||||
// Skip array access
|
// Skip array access
|
||||||
if (Token::simpleMatch(varTok, "["))
|
if (Token::simpleMatch(varTok, "["))
|
||||||
return tok;
|
return tok;
|
||||||
|
|
|
@ -88,6 +88,7 @@ private:
|
||||||
TEST_CASE(oppositeInnerCondition3);
|
TEST_CASE(oppositeInnerCondition3);
|
||||||
TEST_CASE(oppositeInnerConditionAnd);
|
TEST_CASE(oppositeInnerConditionAnd);
|
||||||
TEST_CASE(oppositeInnerConditionEmpty);
|
TEST_CASE(oppositeInnerConditionEmpty);
|
||||||
|
TEST_CASE(oppositeInnerConditionFollowVar);
|
||||||
|
|
||||||
TEST_CASE(identicalInnerCondition);
|
TEST_CASE(identicalInnerCondition);
|
||||||
|
|
||||||
|
@ -2017,6 +2018,21 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void oppositeInnerConditionFollowVar() {
|
||||||
|
check("struct X {\n"
|
||||||
|
" void f() {\n"
|
||||||
|
" const int flag = get();\n"
|
||||||
|
" if (flag) {\n"
|
||||||
|
" bar();\n"
|
||||||
|
" if (!get()) {}\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
" void bar();\n"
|
||||||
|
" int get() const;\n"
|
||||||
|
"};");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void identicalInnerCondition() {
|
void identicalInnerCondition() {
|
||||||
check("void f1(int a, int b) { if(a==b) if(a==b) {}}");
|
check("void f1(int a, int b) { if(a==b) if(a==b) {}}");
|
||||||
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Identical inner 'if' condition is always true.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Identical inner 'if' condition is always true.\n", errout.str());
|
||||||
|
|
Loading…
Reference in New Issue