diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index fcdb2d594..8f0385803 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -865,6 +865,15 @@ void CheckClass::operatorEqToSelf() for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { if (func->type == Function::eOperatorEqual && func->hasBody) { + // make sure that the operator takes an object of the same type as *this, otherwise we can't detect self-assignment checks + if (func->argumentList.empty()) + continue; + const Token* typeTok = func->argumentList.front().typeEndToken(); + while (typeTok->str() == "const" || typeTok->str() == "&" || typeTok->str() == "*") + typeTok = typeTok->previous(); + if (typeTok->str() != scope->className) + continue; + // make sure return signature is correct if (Token::Match(func->tokenDef->tokAt(-3), ";|}|{|public:|protected:|private: %type% &") && func->tokenDef->strAt(-2) == scope->className) { @@ -1339,7 +1348,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func) } // increment/decrement (member variable?).. - else if (Token::Match(tok1, "++|--")) { + else if (tok1->type() == Token::eIncDecOp) { // var++ and var-- if (Token::Match(tok1->previous(), "%var%") && tok1->previous()->str() != "return") { diff --git a/test/testclass.cpp b/test/testclass.cpp index 9b10d37bb..7b7fdfa78 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -1260,6 +1260,18 @@ private: " return *this;\n" "};"); ASSERT_EQUALS("", errout.str()); + + checkOpertorEqToSelf( + "struct A {\n" + " char *s;\n" + " A& operator=(const B &b);\n" + "};\n" + "A& A::operator=(const B &b) {\n" + " free(s);\n" + " s = strdup(a.s);\n" + " return *this;\n" + "};"); + ASSERT_EQUALS("", errout.str()); } void operatorEqToSelf6() {