Skip to content

Commit 9c0834b

Browse files
Fix #14530 FP redundantCopyLocalConst with dissimilar types (danmar#8259)
Co-authored-by: chrchr-github <noreply@github.com>
1 parent a54b894 commit 9c0834b

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

lib/checkother.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3294,9 +3294,11 @@ static bool constructorTakesReference(const Scope * const classScope)
32943294

32953295
static bool isLargeObject(const Variable* var, const Settings& settings)
32963296
{
3297-
return var && !var->isGlobal() &&
3298-
(!var->type() || !var->type()->classScope ||
3299-
(var->valueType() && var->valueType()->getSizeOf(settings, ValueType::Accuracy::LowerBound, ValueType::SizeOf::Pointer) > 2 * settings.platform.sizeof_pointer));
3297+
if (!var || var->isGlobal() || !var->valueType())
3298+
return false;
3299+
ValueType vt = *var->valueType();
3300+
vt.reference = Reference::None;
3301+
return vt.getSizeOf(settings, ValueType::Accuracy::LowerBound, ValueType::SizeOf::Pointer) > 2 * settings.platform.sizeof_pointer;
33003302
}
33013303

33023304
//---------------------------------------------------------------------------
@@ -3332,13 +3334,15 @@ static bool checkFunctionReturnsRef(const Token* tok, const Settings& settings)
33323334
return false;
33333335
}
33343336

3335-
static bool checkVariableAssignment(const Token* tok, const Settings& settings)
3337+
static bool checkVariableAssignment(const Token* tok, const ValueType* vtLhs, const Settings& settings)
33363338
{
33373339
if (!Token::Match(tok, "%var% ;"))
33383340
return false;
33393341
const Variable* var = tok->variable();
33403342
if (!var || !isLargeObject(var, settings))
33413343
return false;
3344+
if (!vtLhs || !vtLhs->isTypeEqual(var->valueType()))
3345+
return false;
33423346
if (findVariableChanged(tok->tokAt(2), tok->scope()->bodyEnd, /*indirect*/ 0, var->declarationId(), /*globalvar*/ false, settings))
33433347
return false;
33443348
if (var->isLocal() || (var->isArgument() && !var->isReference()))
@@ -3381,7 +3385,7 @@ void CheckOther::checkRedundantCopy()
33813385
const Token* tok = startTok->next()->astOperand2();
33823386
if (!tok)
33833387
continue;
3384-
if (!checkFunctionReturnsRef(tok, *mSettings) && !checkVariableAssignment(tok, *mSettings))
3388+
if (!checkFunctionReturnsRef(tok, *mSettings) && !checkVariableAssignment(tok, var->valueType(), *mSettings))
33853389
continue;
33863390
redundantCopyError(startTok, startTok->str());
33873391
}

test/testother.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9944,6 +9944,21 @@ class TestOther : public TestFixture {
99449944
"}\n");
99459945
ASSERT_EQUALS("[test.cpp:7:17]: (performance, inconclusive) Use const reference for 'c' to avoid unnecessary data copying. [redundantCopyLocalConst]\n",
99469946
errout_str());
9947+
9948+
check("int f(const char* c) {\n" // #14530
9949+
" std::string s = c;\n"
9950+
" return s.rfind('.');\n"
9951+
"}\n"
9952+
"struct M {\n"
9953+
" M(const std::array<double, 9>& a);\n"
9954+
" double m[3][3];\n"
9955+
" double trace() const;\n"
9956+
"};\n"
9957+
"double g(const std::array<double, 9>& a) {\n"
9958+
" M m = a;\n"
9959+
" return m.trace();\n"
9960+
"}\n");
9961+
ASSERT_EQUALS("", errout_str());
99479962
}
99489963

99499964
void checkNegativeShift() {

0 commit comments

Comments
 (0)