| 1806 | //--------------------------------------------------------------------------- |
| 1807 | |
| 1808 | void CheckClassImpl::operatorEqToSelf() |
| 1809 | { |
| 1810 | if (!mSettings.severity.isEnabled(Severity::warning) && !mSettings.isPremiumEnabled("operatorEqToSelf")) |
| 1811 | return; |
| 1812 | |
| 1813 | logChecker("CheckClass::operatorEqToSelf"); // warning |
| 1814 | |
| 1815 | for (const Scope * scope : mSymbolDatabase->classAndStructScopes) { |
| 1816 | // skip classes with multiple inheritance |
| 1817 | if (scope->definedType->derivedFrom.size() > 1) |
| 1818 | continue; |
| 1819 | |
| 1820 | for (const Function &func : scope->functionList) { |
| 1821 | if (func.type == FunctionType::eOperatorEqual && func.hasBody()) { |
| 1822 | // make sure that the operator takes an object of the same type as *this, otherwise we can't detect self-assignment checks |
| 1823 | if (func.argumentList.empty()) |
| 1824 | continue; |
| 1825 | const Token* typeTok = func.argumentList.front().typeEndToken(); |
| 1826 | while (typeTok->str() == "const" || typeTok->str() == "&" || typeTok->str() == "*") |
| 1827 | typeTok = typeTok->previous(); |
| 1828 | if (typeTok->str() != scope->className) |
| 1829 | continue; |
| 1830 | |
| 1831 | // make sure return signature is correct |
| 1832 | if (Token::Match(func.retDef, "%type% &") && func.retDef->str() == scope->className) { |
| 1833 | // find the parameter name |
| 1834 | const Token *rhs = func.argumentList.cbegin()->nameToken(); |
| 1835 | const Token* out_ifStatementScopeStart = nullptr; |
| 1836 | if (!hasAssignSelf(&func, rhs, out_ifStatementScopeStart)) { |
| 1837 | if (hasAllocation(&func, scope)) |
| 1838 | operatorEqToSelfError(func.token); |
| 1839 | } else if (out_ifStatementScopeStart != nullptr) { |
| 1840 | if (hasAllocationInIfScope(&func, scope, out_ifStatementScopeStart)) |
| 1841 | operatorEqToSelfError(func.token); |
| 1842 | } |
| 1843 | } |
| 1844 | } |
| 1845 | } |
| 1846 | } |
| 1847 | } |
| 1848 | |
| 1849 | bool CheckClassImpl::hasAllocationInIfScope(const Function *func, const Scope* scope, const Token *ifStatementScopeStart) const |
| 1850 | { |