diff --git a/lib/checkother.cpp b/lib/checkother.cpp index a8adb6154..51f276c65 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2886,7 +2886,8 @@ void CheckOther::checkRedundantCopy() const Scope* fScope = func->functionScope; if (fScope && fScope->bodyEnd && Token::Match(fScope->bodyEnd->tokAt(-3), "return %var% ;")) { const Token* varTok = fScope->bodyEnd->tokAt(-2); - if (varTok->variable() && !varTok->variable()->isGlobal()) + if (varTok->variable() && !varTok->variable()->isGlobal() && + (!varTok->variable()->type() || estimateSize(varTok->variable()->type(), mSettings, symbolDatabase) > 2 * mSettings->platform.sizeof_pointer)) redundantCopyError(startTok, startTok->str()); } } diff --git a/test/testother.cpp b/test/testother.cpp index 4358a5287..d3bb8e4d9 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -8427,7 +8427,7 @@ private: "}"); ASSERT_EQUALS("[test.cpp:3]: (performance, inconclusive) Use const reference for 'a' to avoid unnecessary data copying.\n", errout.str()); - check("class A{public:A(){}};\n" + check("class A { public: A() {} char x[100]; };\n" "const A& getA(){static A a;return a;}\n" "int main()\n" "{\n" @@ -8453,7 +8453,7 @@ private: "}"); ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:4]: (style) Local variable \'getA\' shadows outer function\n", errout.str()); - check("class A{public:A(){}};\n" + check("class A { public: A() {} char x[100]; };\n" "const A& getA(){static A a;return a;}\n" "int main()\n" "{\n" @@ -8604,6 +8604,19 @@ private: " std::string s = getC().get();\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("struct S {\n" // #12139 + " int x, y;\n" + "};\n" + "struct T {\n" + " S s;\n" + " const S& get() const { return s; }\n" + "};\n" + "void f(const T& t) {\n" + " const S a = t.get();\n" + " if (a.x > a.y) {}\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void checkNegativeShift() {