Fix FP passedByValue for unions / FN passedByValue for array members (#3784)
This commit is contained in:
parent
127b3bb1c4
commit
0807924d32
|
@ -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)
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue