Fixed #8735 (FP oppositeInnerCondition - regression)

This commit is contained in:
Daniel Marjamäki 2018-10-07 18:30:29 +02:00
parent d9e1cc957b
commit f961324d45
2 changed files with 34 additions and 0 deletions

View File

@ -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;

View File

@ -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());