Fix false positive from issue 8612 (#1285)
This commit is contained in:
parent
03b2e0eee7
commit
daacf27c2e
|
@ -1949,7 +1949,18 @@ 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())) {
|
||||
duplicateAssignExpressionError(var1, var2);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue