From d6e7f4065ac9505b83e8caaab463a8833e74bc0e Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Thu, 5 Dec 2024 21:39:47 +0100 Subject: [PATCH] Fix #12894 FP redundantAssignment with call to operator= (#7012) --- lib/astutils.cpp | 32 ++++++++++++++++++-------------- test/testother.cpp | 17 +++++++++++++++++ 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 2d9f3002cdd..c27936c3bc1 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -1117,19 +1117,23 @@ bool exprDependsOnThis(const Token* expr, bool onVar, nonneg int depth) ++depth; // calling nonstatic method? - if (Token::Match(expr, "%name% (") && expr->function() && expr->function()->nestedIn && expr->function()->nestedIn->isClassOrStruct() && !expr->function()->isStatic()) { - // is it a method of this? - const Scope* fScope = expr->scope(); - while (!fScope->functionOf && fScope->nestedIn) - fScope = fScope->nestedIn; - - const Scope* classScope = fScope->functionOf; - if (classScope && classScope->function) - classScope = classScope->function->token->scope(); - - if (classScope && classScope->isClassOrStruct()) - return contains(classScope->findAssociatedScopes(), expr->function()->nestedIn); - return false; + if (Token::Match(expr, "%name% (")) { + if (expr->function() && expr->function()->nestedIn && expr->function()->nestedIn->isClassOrStruct() && !expr->function()->isStatic()) { + // is it a method of this? + const Scope* fScope = expr->scope(); + while (!fScope->functionOf && fScope->nestedIn) + fScope = fScope->nestedIn; + + const Scope* classScope = fScope->functionOf; + if (classScope && classScope->function) + classScope = classScope->function->token->scope(); + + if (classScope && classScope->isClassOrStruct()) + return contains(classScope->findAssociatedScopes(), expr->function()->nestedIn); + return false; + } + if (expr->isOperatorKeyword() && !Token::simpleMatch(expr->next()->astParent(), ".")) + return true; } if (onVar && expr->variable()) { const Variable* var = expr->variable(); @@ -3014,7 +3018,7 @@ bool isThisChanged(const Token* tok, int indirect, const Settings& settings) if (tok->previous()->function()) { return (!tok->previous()->function()->isConst() && !tok->previous()->function()->isStatic()); } - if (!tok->previous()->isKeyword()) { + if (!tok->previous()->isKeyword() || tok->previous()->isOperatorKeyword()) { return true; } } diff --git a/test/testother.cpp b/test/testother.cpp index bb566e1e843..8dc184765e3 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -10534,6 +10534,23 @@ class TestOther : public TestFixture { " return j;\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("struct S {\n" // #12894 + " std::string a;\n" + " void f(const S& s);\n" + " void g(const S& s);\n" + "};\n" + "void S::f(const S& s) {\n" + " std::string x = a;\n" + " this->operator=(s);\n" + " a = x;\n" + "}\n" + "void S::g(const S& s) {\n" + " std::string x = a;\n" + " operator=(s);\n" + " a = x;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void varFuncNullUB() { // #4482