diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 3800b9251..f78401158 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2757,6 +2757,10 @@ void CheckOther::checkRedundantCopy() if (!Token::Match(tok->link(), ") )| ;")) // bailout for usage like "const A a = getA()+3" continue; + const Token* dot = tok->astOperand1(); + if (Token::simpleMatch(dot, ".") && dot->astOperand1() && isVariableChanged(dot->astOperand1()->variable(), mSettings, mTokenizer->isCPP())) + continue; + const Function* func = tok->previous()->function(); if (func && func->tokenDef->strAt(-1) == "&") { redundantCopyError(startTok, startTok->str()); diff --git a/test/testother.cpp b/test/testother.cpp index 11d4dd482..187707b89 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -7521,7 +7521,7 @@ private: " }\n" "}"; check(code5618, nullptr, false, true); - TODO_ASSERT_EQUALS("", "[test.cpp:7]: (performance, inconclusive) Use const reference for 'temp' to avoid unnecessary data copying.\n", errout.str()); + ASSERT_EQUALS("", errout.str()); check(code5618, nullptr, false, false); ASSERT_EQUALS("", errout.str()); @@ -7544,6 +7544,19 @@ private: " const CD cd(CD::getOne());\n" "}", nullptr, false, true); ASSERT_EQUALS("", errout.str()); + + check("struct S {\n" // #10545 + " int modify();\n" + " const std::string& get() const;\n" + "};\n" + "std::string f(S& s) {\n" + " const std::string old = s.get();\n" + " int i = s.modify();\n" + " if (i != 0)\n" + " return old;\n" + " return {};\n" + "}", nullptr, /*experimental*/ false, /*inconclusive*/ true); + ASSERT_EQUALS("", errout.str()); } void checkNegativeShift() {