Fixed #1233 (false positive: operator = should check for assignment to self)
This commit is contained in:
parent
686137415f
commit
60ef3ef872
|
@ -998,17 +998,29 @@ static bool hasAssignSelf(const Token * first, const Token * last, const Token *
|
||||||
{
|
{
|
||||||
for (const Token * tok = first; tok && tok != last; tok = tok->next())
|
for (const Token * tok = first; tok && tok != last; tok = tok->next())
|
||||||
{
|
{
|
||||||
if (Token::Match(tok, "if ( this ==|!= & %var% )"))
|
if (Token::Match(tok, "if ("))
|
||||||
{
|
{
|
||||||
if (tok->tokAt(5)->str() == rhs->str())
|
const Token * tok1 = tok->tokAt(2);
|
||||||
|
const Token * tok2 = tok->tokAt(1)->link();
|
||||||
|
|
||||||
|
if (tok1 && tok2)
|
||||||
|
{
|
||||||
|
for (; tok1 && tok1 != tok2; tok1 = tok1->next())
|
||||||
|
{
|
||||||
|
if (Token::Match(tok1, "this ==|!= & %var%"))
|
||||||
|
{
|
||||||
|
if (tok1->tokAt(3)->str() == rhs->str())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (Token::Match(tok, "if ( & %var% ==|!= this )"))
|
else if (Token::Match(tok1, "& %var% ==|!= this"))
|
||||||
{
|
{
|
||||||
if (tok->tokAt(3)->str() == rhs->str())
|
if (tok1->tokAt(1)->str() == rhs->str())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ private:
|
||||||
TEST_CASE(operatorEqToSelf2); // nested class
|
TEST_CASE(operatorEqToSelf2); // nested class
|
||||||
TEST_CASE(operatorEqToSelf3); // multiple inheritance
|
TEST_CASE(operatorEqToSelf3); // multiple inheritance
|
||||||
TEST_CASE(operatorEqToSelf4); // nested class with multiple inheritance
|
TEST_CASE(operatorEqToSelf4); // nested class with multiple inheritance
|
||||||
|
TEST_CASE(operatorEqToSelf5); // ticket # 1233
|
||||||
TEST_CASE(memsetOnStruct);
|
TEST_CASE(memsetOnStruct);
|
||||||
TEST_CASE(memsetOnClass);
|
TEST_CASE(memsetOnClass);
|
||||||
|
|
||||||
|
@ -681,6 +682,78 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void operatorEqToSelf5()
|
||||||
|
{
|
||||||
|
// ticket # 1233
|
||||||
|
checkOpertorEqToSelf(
|
||||||
|
"class A\n"
|
||||||
|
"{\n"
|
||||||
|
"public:\n"
|
||||||
|
" char *s;\n"
|
||||||
|
" A & operator=(const A &a)\n"
|
||||||
|
" {\n"
|
||||||
|
" if((&a!=this))\n"
|
||||||
|
" {\n"
|
||||||
|
" free(s);\n"
|
||||||
|
" s = strdup(a.s);\n"
|
||||||
|
" }\n"
|
||||||
|
" return *this;\n"
|
||||||
|
" }\n"
|
||||||
|
"};");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
checkOpertorEqToSelf(
|
||||||
|
"class A\n"
|
||||||
|
"{\n"
|
||||||
|
"public:\n"
|
||||||
|
" char *s;\n"
|
||||||
|
" A & operator=(const A &a)\n"
|
||||||
|
" {\n"
|
||||||
|
" if(!(&a==this))\n"
|
||||||
|
" {\n"
|
||||||
|
" free(s);\n"
|
||||||
|
" s = strdup(a.s);\n"
|
||||||
|
" }\n"
|
||||||
|
" return *this;\n"
|
||||||
|
" }\n"
|
||||||
|
"};");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
checkOpertorEqToSelf(
|
||||||
|
"class A\n"
|
||||||
|
"{\n"
|
||||||
|
"public:\n"
|
||||||
|
" char *s;\n"
|
||||||
|
" A & operator=(const A &a)\n"
|
||||||
|
" {\n"
|
||||||
|
" if(false==(&a==this))\n"
|
||||||
|
" {\n"
|
||||||
|
" free(s);\n"
|
||||||
|
" s = strdup(a.s);\n"
|
||||||
|
" }\n"
|
||||||
|
" return *this;\n"
|
||||||
|
" }\n"
|
||||||
|
"};");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
checkOpertorEqToSelf(
|
||||||
|
"class A\n"
|
||||||
|
"{\n"
|
||||||
|
"public:\n"
|
||||||
|
" char *s;\n"
|
||||||
|
" A & operator=(const A &a)\n"
|
||||||
|
" {\n"
|
||||||
|
" if(true!=(&a==this))\n"
|
||||||
|
" {\n"
|
||||||
|
" free(s);\n"
|
||||||
|
" s = strdup(a.s);\n"
|
||||||
|
" }\n"
|
||||||
|
" return *this;\n"
|
||||||
|
" }\n"
|
||||||
|
"};");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
// Check that base classes have virtual destructors
|
// Check that base classes have virtual destructors
|
||||||
void checkVirtualDestructor(const char code[])
|
void checkVirtualDestructor(const char code[])
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue