Fix false positive from issue 8612 (#1285)
This commit is contained in:
parent
03b2e0eee7
commit
daacf27c2e
|
@ -1949,6 +1949,17 @@ void CheckOther::checkDuplicateExpression()
|
||||||
isSameExpression(_tokenizer->isCPP(), true, tok->next(), nextAssign->next(), _settings->library, true) &&
|
isSameExpression(_tokenizer->isCPP(), true, tok->next(), nextAssign->next(), _settings->library, true) &&
|
||||||
isSameExpression(_tokenizer->isCPP(), true, tok->astOperand2(), nextAssign->astOperand2(), _settings->library, true) &&
|
isSameExpression(_tokenizer->isCPP(), true, tok->astOperand2(), nextAssign->astOperand2(), _settings->library, true) &&
|
||||||
!isUniqueExpression(tok->astOperand2())) {
|
!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);
|
duplicateAssignExpressionError(var1, var2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,6 +134,7 @@ private:
|
||||||
TEST_CASE(oppositeExpression);
|
TEST_CASE(oppositeExpression);
|
||||||
TEST_CASE(duplicateVarExpression);
|
TEST_CASE(duplicateVarExpression);
|
||||||
TEST_CASE(duplicateVarExpressionUnique);
|
TEST_CASE(duplicateVarExpressionUnique);
|
||||||
|
TEST_CASE(duplicateVarExpressionAssign);
|
||||||
|
|
||||||
TEST_CASE(checkSignOfUnsignedVariable);
|
TEST_CASE(checkSignOfUnsignedVariable);
|
||||||
TEST_CASE(checkSignOfPointer);
|
TEST_CASE(checkSignOfPointer);
|
||||||
|
@ -4173,6 +4174,57 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
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() {
|
void checkSignOfUnsignedVariable() {
|
||||||
check(
|
check(
|
||||||
"void foo() {\n"
|
"void foo() {\n"
|
||||||
|
|
Loading…
Reference in New Issue