Fix FP of duplicateCondition when modifying the this variable

This commit is contained in:
Paul 2020-07-13 12:40:01 -05:00
parent 7d9220e96c
commit 450bdfedf3
4 changed files with 90 additions and 1 deletions

View File

@ -539,7 +539,10 @@ bool exprDependsOnThis(const Token* expr, nonneg int depth)
// 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()->functionOf;
const Scope *fScope = expr->scope();
while (!fScope->functionOf && fScope->nestedIn)
fScope = fScope->nestedIn;
const Scope *nestedIn = fScope->functionOf;
if (nestedIn && nestedIn->function)
nestedIn = nestedIn->function->token->scope();
while (nestedIn && nestedIn != expr->function()->nestedIn) {
@ -1562,6 +1565,32 @@ bool isVariablesChanged(const Token* start,
return false;
}
bool isThisChanged(const Token* start,
const Token* end,
int indirect,
const Settings* settings,
bool cpp)
{
for (const Token* tok = start; tok != end; tok = tok->next()) {
if (!exprDependsOnThis(tok))
continue;
if (Token::Match(tok->previous(), "%name% (")) {
if (tok->previous()->function()) {
if (!tok->previous()->function()->isConst())
return true;
else
continue;
} else if (!tok->previous()->isKeyword()){
return true;
}
}
if (isVariableChanged(tok, indirect, settings, cpp))
return true;
}
return false;
}
int numberOfArguments(const Token *start)
{
int arguments=0;

View File

@ -192,6 +192,12 @@ bool isVariablesChanged(const Token* start,
const Settings* settings,
bool cpp);
bool isThisChanged(const Token* start,
const Token* end,
int indirect,
const Settings* settings,
bool cpp);
const Token* findVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int varid, bool globalvar, const Settings *settings, bool cpp, int depth = 20);
Token* findVariableChanged(Token *start, const Token *end, int indirect, const nonneg int varid, bool globalvar, const Settings *settings, bool cpp, int depth = 20);

View File

@ -453,6 +453,12 @@ void CheckCondition::duplicateCondition()
bool modified = false;
visitAstNodes(cond1, [&](const Token *tok3) {
if (exprDependsOnThis(tok3)) {
if (isThisChanged(scope.classDef->next(), cond2, false, mSettings, mTokenizer->isCPP())) {
modified = true;
return ChildrenToVisit::done;
}
}
if (tok3->varId() > 0 &&
isVariableChanged(scope.classDef->next(), cond2, tok3->varId(), false, mSettings, mTokenizer->isCPP())) {
modified = true;

View File

@ -3668,6 +3668,54 @@ private:
" if (a.b) {}\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("struct A {\n"
" int a;\n"
" void b() const {\n"
" return a == 1;\n"
" }\n"
" void c();\n"
" void d() {\n"
" if(b()) {\n"
" c();\n"
" }\n"
" if (b()) {\n"
" a = 3;\n"
" }\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("struct A {\n"
" int a;\n"
" void b() const {\n"
" return a == 1;\n"
" }\n"
" void d() {\n"
" if(b()) {\n"
" a = 2;\n"
" }\n"
" if (b()) {\n"
" a = 3;\n"
" }\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("struct A {\n"
" int a;\n"
" void b() const {\n"
" return a == 1;\n"
" }\n"
" void d() {\n"
" if(b()) {\n"
" }\n"
" if (b()) {\n"
" a = 3;\n"
" }\n"
" }\n"
"}\n");
ASSERT_EQUALS("[test.cpp:7] -> [test.cpp:9]: (style) The if condition is the same as the previous if condition\n", errout.str());
}
void checkInvalidTestForOverflow() {