aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSergio Martins <sergio.martins@kdab.com>2017-11-18 13:53:10 +0000
committerSergio Martins <iamsergio@gmail.com>2017-11-18 13:56:08 +0000
commit26f030d043032ad1e5fe8d0f9f8becb8c449b87d (patch)
tree43c838ad51e6fd246224e851dd939c410f215d35 /src
parentad1efd24b4183e093247a6b788f9cc9e2c79e403 (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.md4
-rw-r--r--src/checks/level0/lambda-unique-connection.cpp91
-rw-r--r--src/checks/level0/lambda-unique-connection.h38
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