aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSergio Martins <iamsergio@gmail.com>2017-12-01 14:10:49 +0000
committerSergio Martins <iamsergio@gmail.com>2017-12-01 14:10:49 +0000
commit41e79d655cd7133459706e17ab8cf794ce4e5251 (patch)
tree9dbc86fca6a4ad2f821c3b8dde2fae38176442b5 /src
parent21b73fbb4f49f6ef3f4dbc9d15165e67e70dfd8b (diff)
connect-3arg-lambda: refactor this check
No longer advises to pass 'this' as 3rd argument, because it might make sense to pass another object there, should be the user to decide.
Diffstat (limited to 'src')
-rw-r--r--src/checks/level1/connect-3arg-lambda.cpp39
1 files changed, 22 insertions, 17 deletions
diff --git a/src/checks/level1/connect-3arg-lambda.cpp b/src/checks/level1/connect-3arg-lambda.cpp
index e036f6f8..12148907 100644
--- a/src/checks/level1/connect-3arg-lambda.cpp
+++ b/src/checks/level1/connect-3arg-lambda.cpp
@@ -52,31 +52,30 @@ void Connect3argLambda::VisitStmt(clang::Stmt *stmt)
if (!lambda)
return;
- // The sender can be: this
- auto senderThis = HierarchyUtils::unpeal<CXXThisExpr>(callExpr->getArg(0), HierarchyUtils::IgnoreImplicitCasts);
+ DeclRefExpr *senderDeclRef = nullptr;
+ MemberExpr *senderMemberExpr = nullptr;
- // Or it can be: a declref (variable)
- DeclRefExpr *senderDeclRef = senderThis ? nullptr : HierarchyUtils::getFirstChildOfType2<DeclRefExpr>(callExpr->getArg(0));
+ Stmt *s = callExpr->getArg(0);
+ while (s) {
+ if ((senderDeclRef = dyn_cast<DeclRefExpr>(s)))
+ break;
+ if ((senderMemberExpr = dyn_cast<MemberExpr>(s)))
+ break;
- // If this is referenced inside the lambda body, for example, by calling a member function
- auto thisExprs = HierarchyUtils::getStatements<CXXThisExpr>(lambda->getBody());
- const bool lambdaHasThis = !thisExprs.empty();
+ s = HierarchyUtils::getFirstChild(s);
+ }
- // The variables used inside the lambda
- auto declrefs = HierarchyUtils::getStatements<DeclRefExpr>(lambda->getBody());
- // If lambda doesn't do anything interesting, don't warn
- if (declrefs.empty() && !lambdaHasThis)
- return;
+ // The sender can be: this
+ CXXThisExpr* senderThis = HierarchyUtils::unpeal<CXXThisExpr>(callExpr->getArg(0), HierarchyUtils::IgnoreImplicitCasts);
- if (lambdaHasThis && !senderThis && QtUtils::isQObject(thisExprs[0]->getType())) {
- emitWarning(stmt->getLocStart(), "Pass 'this' as the 3rd connect parameter");
- return;
- }
+ // The variables used inside the lambda
+ auto declrefs = HierarchyUtils::getStatements<DeclRefExpr>(lambda->getBody());
ValueDecl *senderDecl = senderDeclRef ? senderDeclRef->getDecl() : nullptr;
- // We'll only warn if the lambda is dereferencing another QObject (besides the sender).
+
+ // We'll only warn if the lambda is dereferencing another QObject (besides the sender)
bool found = false;
for (auto declref : declrefs) {
ValueDecl *decl = declref->getDecl();
@@ -89,6 +88,12 @@ void Connect3argLambda::VisitStmt(clang::Stmt *stmt)
}
}
+ if (!found) {
+ auto thisexprs = HierarchyUtils::getStatements<CXXThisExpr>(lambda->getBody());
+ if (!thisexprs.empty() && !senderThis)
+ found = true;
+ }
+
if (found)
emitWarning(stmt->getLocStart(), "Pass a context object as 3rd connect parameter");
}