diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index f8b67684cf5..91a79e51ca8 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -3327,8 +3327,14 @@ static const Variable* getSingleReturnVar(const Scope* scope) { if (!start->astOperand1() || start->str() != "return") return nullptr; const Token* tok = start->astOperand1(); - if (tok->str() == ".") + if (tok->str() == ".") { + const Token* top = tok->astOperand1(); + while (Token::Match(top, "[[.]")) + top = top->astOperand1(); + if (!Token::Match(top, "%var%")) + return nullptr; tok = tok->astOperand2(); + } return tok->variable(); } diff --git a/test/testclass.cpp b/test/testclass.cpp index bac96f1fc92..64913601b65 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -9083,6 +9083,23 @@ class TestClass : public TestFixture { ASSERT_EQUALS("[test.cpp:6]: (performance) Function 'get1()' should return member 'str' by const reference.\n" "[test.cpp:9]: (performance) Function 'get2()' should return member 'strT' by const reference.\n", errout_str()); + + checkReturnByReference("struct S { std::string str; };\n" // #13059 + "struct T {\n" + " S temp() const;\n" + " S s[1];\n" + "};\n" + "struct U {\n" + " std::string get1() const {\n" + " return t.temp().str;\n" + " }\n" + " std::string get2() const {\n" + " return t.s[0].str;\n" + " }\n" + " T t;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:10]: (performance) Function 'get2()' should return member 'str' by const reference.\n", + errout_str()); } };