diff --git a/lib/checkother.cpp b/lib/checkother.cpp index c4c4cf049b2..536911a05a5 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -3294,9 +3294,11 @@ static bool constructorTakesReference(const Scope * const classScope) static bool isLargeObject(const Variable* var, const Settings& settings) { - return var && !var->isGlobal() && - (!var->type() || !var->type()->classScope || - (var->valueType() && var->valueType()->getSizeOf(settings, ValueType::Accuracy::LowerBound, ValueType::SizeOf::Pointer) > 2 * settings.platform.sizeof_pointer)); + if (!var || var->isGlobal() || !var->valueType()) + return false; + ValueType vt = *var->valueType(); + vt.reference = Reference::None; + return vt.getSizeOf(settings, ValueType::Accuracy::LowerBound, ValueType::SizeOf::Pointer) > 2 * settings.platform.sizeof_pointer; } //--------------------------------------------------------------------------- @@ -3332,13 +3334,15 @@ static bool checkFunctionReturnsRef(const Token* tok, const Settings& settings) return false; } -static bool checkVariableAssignment(const Token* tok, const Settings& settings) +static bool checkVariableAssignment(const Token* tok, const ValueType* vtLhs, const Settings& settings) { if (!Token::Match(tok, "%var% ;")) return false; const Variable* var = tok->variable(); if (!var || !isLargeObject(var, settings)) return false; + if (!vtLhs || !vtLhs->isTypeEqual(var->valueType())) + return false; if (findVariableChanged(tok->tokAt(2), tok->scope()->bodyEnd, /*indirect*/ 0, var->declarationId(), /*globalvar*/ false, settings)) return false; if (var->isLocal() || (var->isArgument() && !var->isReference())) @@ -3381,7 +3385,7 @@ void CheckOther::checkRedundantCopy() const Token* tok = startTok->next()->astOperand2(); if (!tok) continue; - if (!checkFunctionReturnsRef(tok, *mSettings) && !checkVariableAssignment(tok, *mSettings)) + if (!checkFunctionReturnsRef(tok, *mSettings) && !checkVariableAssignment(tok, var->valueType(), *mSettings)) continue; redundantCopyError(startTok, startTok->str()); } diff --git a/test/testother.cpp b/test/testother.cpp index c2781cbab6c..670e1559d60 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -9944,6 +9944,21 @@ class TestOther : public TestFixture { "}\n"); ASSERT_EQUALS("[test.cpp:7:17]: (performance, inconclusive) Use const reference for 'c' to avoid unnecessary data copying. [redundantCopyLocalConst]\n", errout_str()); + + check("int f(const char* c) {\n" // #14530 + " std::string s = c;\n" + " return s.rfind('.');\n" + "}\n" + "struct M {\n" + " M(const std::array& a);\n" + " double m[3][3];\n" + " double trace() const;\n" + "};\n" + "double g(const std::array& a) {\n" + " M m = a;\n" + " return m.trace();\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void checkNegativeShift() {