Fix FP of duplicateCondition when modifying the this variable
This commit is contained in:
parent
7d9220e96c
commit
450bdfedf3
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue