in src/checks/level2/function-args-by-ref.cpp [97:153]
void FunctionArgsByRef::processFunction(FunctionDecl *func)
{
if (!func || !func->isThisDeclarationADefinition() || func->isDeleted() || shouldIgnoreOperator(func)) {
return;
}
if (m_context->isQtDeveloper() && shouldIgnoreFunction(func)) {
return;
}
Stmt *body = func->getBody();
auto funcParams = Utils::functionParameters(func);
for (unsigned int i = 0; i < funcParams.size(); ++i) {
ParmVarDecl *param = funcParams[i];
const QualType paramQt = clazy::unrefQualType(param->getType());
const Type *paramType = paramQt.getTypePtrOrNull();
if (!paramType || paramType->isIncompleteType() || paramType->isDependentType()) {
continue;
}
if (shouldIgnoreClass(paramType->getAsCXXRecordDecl())) {
continue;
}
clazy::QualTypeClassification classif;
bool success = clazy::classifyQualType(m_context, param->getType(), param, classif, body);
if (!success) {
continue;
}
std::vector<CXXCtorInitializer *> ctorInits = Utils::ctorInitializer(dyn_cast<CXXConstructorDecl>(func), param);
if (Utils::ctorInitializerContainsMove(ctorInits)) {
continue;
}
if (classif.passBigTypeByConstRef || classif.passNonTriviallyCopyableByConstRef) {
std::string error;
std::vector<FixItHint> fixits;
std::string paramStr = param->getType().getAsString(lo());
const std::string funcName = func->getQualifiedNameAsString();
if (const std::string paramName = param->getNameAsString(); !paramName.empty())
paramStr.append(" " + paramName);
if (classif.passNonTriviallyCopyableByConstRef) { // Prefer this warning, because we might otherwise annoy user with specific size of Qt classes
error = funcName + ": Missing reference on non-trivial type (" + paramStr + ')';
} else if (classif.passBigTypeByConstRef) {
error = warningMsgForSmallType(classif.size_of_T, paramStr);
}
addFixits(fixits, func, i);
emitWarning(param->getBeginLoc(), error, fixits);
}
}
}