diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 709031847..b3da83ec7 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -42,6 +42,7 @@ #include #include #include +#include //--------------------------------------------------------------------------- @@ -1155,6 +1156,13 @@ static int estimateSize(const Type* type, const Settings* settings, const Symbol return 0; int cumulatedSize = 0; + const bool isUnion = type->classScope->type == Scope::ScopeType::eUnion; + const auto accumulateSize = [](int& cumulatedSize, int size, bool isUnion) -> void { + if (isUnion) + cumulatedSize = std::max(cumulatedSize, size); + else + cumulatedSize += size; + }; for (const Variable&var : type->classScope->varlist) { int size = 0; if (var.isStatic()) @@ -1169,9 +1177,11 @@ static int estimateSize(const Type* type, const Settings* settings, const Symbol size = symbolDatabase->sizeOfType(var.typeStartToken()); if (var.isArray()) - cumulatedSize += size * var.dimension(0); - else - cumulatedSize += size; + size *= std::accumulate(var.dimensions().begin(), var.dimensions().end(), 1, [](int v, const Dimension& d) { + return v *= d.num; + }); + + accumulateSize(cumulatedSize, size, isUnion); } for (const Type::BaseInfo &baseInfo : type->derivedFrom) { if (baseInfo.type && baseInfo.type->classScope) diff --git a/test/testother.cpp b/test/testother.cpp index 01ef808cc..5badbe7aa 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -1665,6 +1665,18 @@ private: "void foo(X x4){}\n"); ASSERT_EQUALS("", errout.str()); + check("union U {\n" + " char* pc;\n" + " short* ps;\n" + " int* pi;\n" + "};\n" + "void f(U u) {}\n"); + ASSERT_EQUALS("", errout.str()); + + check("struct S { char A[8][8]; };\n" + "void f(S s) {}\n"); + ASSERT_EQUALS("[test.cpp:2]: (performance) Function parameter 's' should be passed by const reference.\n", errout.str()); + Settings settings1; settings1.platform(Settings::Win64); check("using ui64 = unsigned __int64;\n"