diff options
author | Sergio Martins <sergio.martins@kdab.com> | 2017-11-18 13:53:10 +0000 |
---|---|---|
committer | Sergio Martins <iamsergio@gmail.com> | 2017-11-18 13:56:08 +0000 |
commit | 26f030d043032ad1e5fe8d0f9f8becb8c449b87d (patch) | |
tree | 43c838ad51e6fd246224e851dd939c410f215d35 /src | |
parent | ad1efd24b4183e093247a6b788f9cc9e2c79e403 (diff) |
Introduce lambda-unique-connection
Qt::UniqueConnection only works with member functions, not functors
or lambdas.
CCMAIL: filipe.azevedo@kdab.com
Diffstat (limited to 'src')
-rw-r--r-- | src/checks/level0/README-lambda-unique-connection.md | 4 | ||||
-rw-r--r-- | src/checks/level0/lambda-unique-connection.cpp | 91 | ||||
-rw-r--r-- | src/checks/level0/lambda-unique-connection.h | 38 |
3 files changed, 133 insertions, 0 deletions
diff --git a/src/checks/level0/README-lambda-unique-connection.md b/src/checks/level0/README-lambda-unique-connection.md new file mode 100644 index 00000000..453f3a28 --- /dev/null +++ b/src/checks/level0/README-lambda-unique-connection.md @@ -0,0 +1,4 @@ +# lambda-unique-connection + +Finds usages of `Qt::UniqueConnection` when the slot is a functor, lambda or non-member function. +That `connect()` overload does not support `Qt::UniqueConnection`. diff --git a/src/checks/level0/lambda-unique-connection.cpp b/src/checks/level0/lambda-unique-connection.cpp new file mode 100644 index 00000000..ad058efe --- /dev/null +++ b/src/checks/level0/lambda-unique-connection.cpp @@ -0,0 +1,91 @@ +/* + This file is part of the clazy static checker. + + Copyright (C) 2017 Sergio Martins <smartins@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "lambda-unique-connection.h" +#include "Utils.h" +#include "HierarchyUtils.h" +#include "QtUtils.h" +#include "TypeUtils.h" +#include "checkmanager.h" +#include "AccessSpecifierManager.h" +#include "ClazyContext.h" + +#include <clang/AST/AST.h> + +using namespace clang; +using namespace std; + + +LambdaUniqueConnection::LambdaUniqueConnection(const std::string &name, ClazyContext *context) + : CheckBase(name, context) +{ +} + +void LambdaUniqueConnection::VisitStmt(clang::Stmt *stmt) +{ + auto call = dyn_cast<CallExpr>(stmt); + if (!call) + return; + + // We want this signature: + // connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type) + + FunctionDecl *func = call->getDirectCallee(); + if (!func || func->getNumParams() != 5 || !func->isTemplateInstantiation() || !QtUtils::isConnect(func) || !QtUtils::connectHasPMFStyle(func)) + return; + + Expr *typeArg = call->getArg(4); // The type + + vector<DeclRefExpr*> result; + HierarchyUtils::getChilds(typeArg, result); + + bool found = false; + for (auto declRef : result) { + if (auto enumConstant = dyn_cast<EnumConstantDecl>(declRef->getDecl())) { + if (enumConstant->getName() == "UniqueConnection") { + found = true; + break; + } + } + } + + if (!found) + return; + + FunctionTemplateSpecializationInfo *tsi = func->getTemplateSpecializationInfo(); + if (!tsi) + return; + FunctionTemplateDecl *temp = tsi->getTemplate(); + const TemplateParameterList *tempParams = temp->getTemplateParameters(); + if (tempParams->size() != 2) + return; + + CXXMethodDecl *method = QtUtils::pmfFromConnect(call, 3); + if (method) { + // How else to detect if it's the right overload ? It's all templated stuff with the same + // names for all the template arguments + return; + } + + emitWarning(typeArg, "UniqueConnection is not supported with non-member functions"); +} + +REGISTER_CHECK("lambda-unique-connection", LambdaUniqueConnection, CheckLevel0) diff --git a/src/checks/level0/lambda-unique-connection.h b/src/checks/level0/lambda-unique-connection.h new file mode 100644 index 00000000..41d83af2 --- /dev/null +++ b/src/checks/level0/lambda-unique-connection.h @@ -0,0 +1,38 @@ +/* + This file is part of the clazy static checker. + + Copyright (C) 2017 Sergio Martins <smartins@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef CLAZY_LAMBDA_UNIQUE_CONNECTION_H +#define CLAZY_LAMBDA_UNIQUE_CONNECTION_H + +#include "checkbase.h" + + +/** + * See README-lambda-unique-connection.md for more info. + */ +class LambdaUniqueConnection : public CheckBase +{ +public: + explicit LambdaUniqueConnection(const std::string &name, ClazyContext *context); + void VisitStmt(clang::Stmt *stmt) override; +}; + +#endif |