diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 1a42f8ab820..2961873de26 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -3327,9 +3327,13 @@ void CheckClass::checkReturnByReference() for (const Function& func : classScope->functionList) { if (Function::returnsPointer(&func) || Function::returnsReference(&func) || Function::returnsStandardType(&func)) continue; + if (func.isImplicitlyVirtual()) + continue; if (const Variable* var = getSingleReturnVar(func.functionScope)) { if (!var->valueType()) continue; + if (var->isArgument()) + continue; const bool isContainer = var->valueType()->type == ValueType::Type::CONTAINER && var->valueType()->container; const bool isView = isContainer && var->valueType()->container->view; bool warn = isContainer && !isView; diff --git a/test/testclass.cpp b/test/testclass.cpp index 4d62db1eadb..b0ffbb6b550 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -8960,21 +8960,34 @@ class TestClass : public TestFixture { } void returnByReference() { - checkReturnByReference("struct T { int a[10]; };" // #12546 - "struct S {" - " T t;" - " int i;" - " std::string s;" - " T getT() const { return t; }" - " int getI() const { return i; }" - " std::string getS() const { return s; }" - " unknown_t f() { return; }" - "};"); - ASSERT_EQUALS("[test.cpp:1]: (performance) Function 'getT()' should return member 't' by const reference.\n" - "[test.cpp:1]: (performance) Function 'getS()' should return member 's' by const reference.\n", + checkReturnByReference("struct T { int a[10]; };\n" // #12546 + "struct S {\n" + " T t;\n" + " int i;\n" + " std::string s;\n" + " T getT() const { return t; }\n" + " int getI() const { return i; }\n" + " std::string getS() const { return s; }\n" + " unknown_t f() { return; }\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:6]: (performance) Function 'getT()' should return member 't' by const reference.\n" + "[test.cpp:8]: (performance) Function 'getS()' should return member 's' by const reference.\n", errout_str()); - } + checkReturnByReference("struct B {\n" // #12608 + " virtual std::string f() { return \"abc\"; }\n" + "};\n" + "struct D : B {\n" + " std::string f() override { return s; }\n" + " std::string s;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + checkReturnByReference("struct S {\n" + " std::string f(std::string s) { return s; }\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + } }; REGISTER_TEST(TestClass)