Fix false positive from issue 8612 (#1285)

This commit is contained in:
Paul Fultz II 2018-06-09 17:05:23 -05:00 committed by Daniel Marjamäki
parent 03b2e0eee7
commit daacf27c2e
2 changed files with 64 additions and 1 deletions

View File

@ -1949,6 +1949,17 @@ void CheckOther::checkDuplicateExpression()
isSameExpression(_tokenizer->isCPP(), true, tok->next(), nextAssign->next(), _settings->library, true) &&
isSameExpression(_tokenizer->isCPP(), true, tok->astOperand2(), nextAssign->astOperand2(), _settings->library, true) &&
!isUniqueExpression(tok->astOperand2())) {
bool assigned = false;
const Scope * varScope = var1->scope() ? var1->scope() : &*scope;
for (const Token *assignTok = Token::findsimplematch(var2, ";"); assignTok && assignTok != varScope->bodyEnd; assignTok = assignTok->next()) {
if(Token::Match(assignTok, "%varid% = %var%", var1->varId()) && Token::Match(assignTok, "%var% = %varid%", var2->varId())) {
assigned = true;
}
if(Token::Match(assignTok, "%varid% = %var%", var2->varId()) && Token::Match(assignTok, "%var% = %varid%", var1->varId())) {
assigned = true;
}
}
if(!assigned)
duplicateAssignExpressionError(var1, var2);
}
}

View File

@ -134,6 +134,7 @@ private:
TEST_CASE(oppositeExpression);
TEST_CASE(duplicateVarExpression);
TEST_CASE(duplicateVarExpressionUnique);
TEST_CASE(duplicateVarExpressionAssign);
TEST_CASE(checkSignOfUnsignedVariable);
TEST_CASE(checkSignOfPointer);
@ -4173,6 +4174,57 @@ private:
ASSERT_EQUALS("", errout.str());
}
void duplicateVarExpressionAssign() {
check("struct A { int x; int y; };"
"void use(int);\n"
"void test(A a) {\n"
" int i = a.x;\n"
" int j = a.x;\n"
" use(i);\n"
" i = j;\n"
"}");
ASSERT_EQUALS("", errout.str());
check("struct A { int x; int y; };"
"void use(int);\n"
"void test(A a) {\n"
" int i = a.x;\n"
" int j = a.x;\n"
" use(j);\n"
" j = i;\n"
"}");
ASSERT_EQUALS("", errout.str());
// Issue #8612
check("struct P\n"
"{\n"
" void func();\n"
" bool operator==(const P&) const;\n"
"};\n"
"struct X\n"
"{\n"
" P first;\n"
" P second;\n"
"};\n"
"bool bar();\n"
"void baz(const P&);\n"
"void foo(const X& x)\n"
"{\n"
" P current = x.first;\n"
" P previous = x.first;\n"
" while (true)\n"
" {\n"
" baz(current);\n"
" if (bar() && previous == current)\n"
" {\n"
" current.func();\n"
" }\n"
" previous = current;\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void checkSignOfUnsignedVariable() {
check(
"void foo() {\n"