Fix FP passedByValue for unions / FN passedByValue for array members (#3784)

This commit is contained in:
chrchr-github 2022-02-01 17:17:08 +01:00 committed by GitHub
parent 127b3bb1c4
commit 0807924d32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 3 deletions

View File

@ -42,6 +42,7 @@
#include <set> #include <set>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <numeric>
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1155,6 +1156,13 @@ static int estimateSize(const Type* type, const Settings* settings, const Symbol
return 0; return 0;
int cumulatedSize = 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) { for (const Variable&var : type->classScope->varlist) {
int size = 0; int size = 0;
if (var.isStatic()) if (var.isStatic())
@ -1169,9 +1177,11 @@ static int estimateSize(const Type* type, const Settings* settings, const Symbol
size = symbolDatabase->sizeOfType(var.typeStartToken()); size = symbolDatabase->sizeOfType(var.typeStartToken());
if (var.isArray()) if (var.isArray())
cumulatedSize += size * var.dimension(0); size *= std::accumulate(var.dimensions().begin(), var.dimensions().end(), 1, [](int v, const Dimension& d) {
else return v *= d.num;
cumulatedSize += size; });
accumulateSize(cumulatedSize, size, isUnion);
} }
for (const Type::BaseInfo &baseInfo : type->derivedFrom) { for (const Type::BaseInfo &baseInfo : type->derivedFrom) {
if (baseInfo.type && baseInfo.type->classScope) if (baseInfo.type && baseInfo.type->classScope)

View File

@ -1665,6 +1665,18 @@ private:
"void foo(X x4){}\n"); "void foo(X x4){}\n");
ASSERT_EQUALS("", errout.str()); 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; Settings settings1;
settings1.platform(Settings::Win64); settings1.platform(Settings::Win64);
check("using ui64 = unsigned __int64;\n" check("using ui64 = unsigned __int64;\n"