Set struct size cutoff in passedByValue check to 2*sizeof_pointer
Struct arguments are either pushed to the stack or passed in the registers. Since both methods operate on machine words it is logical to tie the maximum size of a struct argument that doesn't trigger passedByValue diagnostic to the size of the machine word. Also guessed size of STL classes is set to 3*sizeof_pointer, this better represents reality and ensures that structs containing them will still trigger passedByValue.
This commit is contained in:
parent
c185a8aae9
commit
ff38cc5c13
|
@ -1344,7 +1344,7 @@ static std::size_t estimateSize(const Type* type, const Settings* settings, cons
|
|||
else if (i->type() && i->type()->classScope)
|
||||
size = estimateSize(i->type(), settings, symbolDatabase, recursionDepth+1);
|
||||
else if (i->isStlStringType() || (i->isStlType() && Token::Match(i->typeStartToken(), "std :: %type% <") && !Token::simpleMatch(i->typeStartToken()->linkAt(3), "> ::")))
|
||||
size = 16; // Just guess
|
||||
size = 3 * settings->sizeof_pointer; // Just guess
|
||||
else
|
||||
size = symbolDatabase->sizeOfType(i->typeStartToken());
|
||||
|
||||
|
@ -1385,7 +1385,7 @@ void CheckOther::checkPassByReference()
|
|||
// Ensure that it is a large object.
|
||||
if (!var->type()->classScope)
|
||||
inconclusive = true;
|
||||
else if (estimateSize(var->type(), _settings, symbolDatabase) <= 8)
|
||||
else if (estimateSize(var->type(), _settings, symbolDatabase) <= 2 * _settings->sizeof_pointer)
|
||||
continue;
|
||||
} else
|
||||
continue;
|
||||
|
|
|
@ -1551,14 +1551,49 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("class X {\n"
|
||||
" uint64_t i;\n"
|
||||
" char a[1024];\n"
|
||||
"};\n"
|
||||
"class Y : X {\n"
|
||||
" uint64_t j;\n"
|
||||
" char b;\n"
|
||||
"};\n"
|
||||
"void f(Y y) {\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:7]: (performance) Function parameter 'y' should be passed by reference.\n", errout.str());
|
||||
|
||||
check("class X {\n"
|
||||
" void* a;\n"
|
||||
" void* b;\n"
|
||||
"};\n"
|
||||
"class Y {\n"
|
||||
" void* a;\n"
|
||||
" void* b;\n"
|
||||
" char c;\n"
|
||||
"};\n"
|
||||
"void f(X x, Y y) {\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:7]: (performance) Function parameter 'y' should be passed by reference.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:10]: (performance) Function parameter 'y' should be passed by reference.\n", errout.str());
|
||||
|
||||
const auto originalPlatform = _settings.platformType;
|
||||
|
||||
_settings.platform(cppcheck::Platform::Unix32);
|
||||
check("class X {\n"
|
||||
" uint64_t a;\n"
|
||||
" uint64_t b;\n"
|
||||
"};\n"
|
||||
"void f(X x) {\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:5]: (performance) Function parameter 'x' should be passed by reference.\n", errout.str());
|
||||
|
||||
_settings.platform(cppcheck::Platform::Unix64);
|
||||
check("class X {\n"
|
||||
" uint64_t a;\n"
|
||||
" uint64_t b;\n"
|
||||
"};\n"
|
||||
"void f(X x) {\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
_settings.platform(originalPlatform);
|
||||
}
|
||||
|
||||
void switchRedundantAssignmentTest() {
|
||||
|
|
Loading…
Reference in New Issue