Skip to content

Commit 0807924

Browse files
Fix FP passedByValue for unions / FN passedByValue for array members (#3784)
1 parent 127b3bb commit 0807924

2 files changed

Lines changed: 25 additions & 3 deletions

File tree

lib/checkother.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include <set>
4343
#include <type_traits>
4444
#include <utility>
45+
#include <numeric>
4546

4647
//---------------------------------------------------------------------------
4748

@@ -1155,6 +1156,13 @@ static int estimateSize(const Type* type, const Settings* settings, const Symbol
11551156
return 0;
11561157

11571158
int cumulatedSize = 0;
1159+
const bool isUnion = type->classScope->type == Scope::ScopeType::eUnion;
1160+
const auto accumulateSize = [](int& cumulatedSize, int size, bool isUnion) -> void {
1161+
if (isUnion)
1162+
cumulatedSize = std::max(cumulatedSize, size);
1163+
else
1164+
cumulatedSize += size;
1165+
};
11581166
for (const Variable&var : type->classScope->varlist) {
11591167
int size = 0;
11601168
if (var.isStatic())
@@ -1169,9 +1177,11 @@ static int estimateSize(const Type* type, const Settings* settings, const Symbol
11691177
size = symbolDatabase->sizeOfType(var.typeStartToken());
11701178

11711179
if (var.isArray())
1172-
cumulatedSize += size * var.dimension(0);
1173-
else
1174-
cumulatedSize += size;
1180+
size *= std::accumulate(var.dimensions().begin(), var.dimensions().end(), 1, [](int v, const Dimension& d) {
1181+
return v *= d.num;
1182+
});
1183+
1184+
accumulateSize(cumulatedSize, size, isUnion);
11751185
}
11761186
for (const Type::BaseInfo &baseInfo : type->derivedFrom) {
11771187
if (baseInfo.type && baseInfo.type->classScope)

test/testother.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,6 +1665,18 @@ class TestOther : public TestFixture {
16651665
"void foo(X x4){}\n");
16661666
ASSERT_EQUALS("", errout.str());
16671667

1668+
check("union U {\n"
1669+
" char* pc;\n"
1670+
" short* ps;\n"
1671+
" int* pi;\n"
1672+
"};\n"
1673+
"void f(U u) {}\n");
1674+
ASSERT_EQUALS("", errout.str());
1675+
1676+
check("struct S { char A[8][8]; };\n"
1677+
"void f(S s) {}\n");
1678+
ASSERT_EQUALS("[test.cpp:2]: (performance) Function parameter 's' should be passed by const reference.\n", errout.str());
1679+
16681680
Settings settings1;
16691681
settings1.platform(Settings::Win64);
16701682
check("using ui64 = unsigned __int64;\n"

0 commit comments

Comments
 (0)