File indexing completed on 2024-05-12 05:40:56
0001 /* 0002 SPDX-FileCopyrightText: 2016-2017 Sergio Martins <smartins@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "lambda-in-connect.h" 0008 #include "ClazyContext.h" 0009 #include "ContextUtils.h" 0010 #include "HierarchyUtils.h" 0011 #include "QtUtils.h" 0012 #include "StringUtils.h" 0013 0014 #include <clang/AST/Decl.h> 0015 #include <clang/AST/Expr.h> 0016 #include <clang/AST/ExprCXX.h> 0017 #include <clang/AST/LambdaCapture.h> 0018 #include <clang/AST/Stmt.h> 0019 #include <clang/AST/Type.h> 0020 #include <clang/Basic/LLVM.h> 0021 #include <clang/Basic/Lambda.h> 0022 #include <llvm/ADT/iterator_range.h> 0023 #include <llvm/Support/Casting.h> 0024 0025 using namespace clang; 0026 0027 LambdaInConnect::LambdaInConnect(const std::string &name, ClazyContext *context) 0028 : CheckBase(name, context, Option_CanIgnoreIncludes) 0029 { 0030 } 0031 0032 void LambdaInConnect::VisitStmt(clang::Stmt *stmt) 0033 { 0034 auto *lambda = dyn_cast<LambdaExpr>(stmt); 0035 if (!lambda) { 0036 return; 0037 } 0038 0039 auto captures = lambda->captures(); 0040 if (captures.begin() == captures.end()) { 0041 return; 0042 } 0043 0044 auto *callExpr = clazy::getFirstParentOfType<CallExpr>(m_context->parentMap, lambda); 0045 if (clazy::qualifiedMethodName(callExpr) != "QObject::connect") { 0046 return; 0047 } 0048 0049 ValueDecl *senderDecl = clazy::signalSenderForConnect(callExpr); 0050 if (senderDecl) { 0051 const Type *t = senderDecl->getType().getTypePtrOrNull(); 0052 if (t && !t->isPointerType()) { 0053 return; 0054 } 0055 } 0056 0057 ValueDecl *receiverDecl = clazy::signalReceiverForConnect(callExpr); 0058 0059 for (auto capture : captures) { 0060 if (capture.getCaptureKind() == clang::LCK_ByRef) { 0061 auto *declForCapture = capture.getCapturedVar(); 0062 if (declForCapture && declForCapture != receiverDecl && clazy::isValueDeclInFunctionContext(declForCapture)) { 0063 emitWarning(capture.getLocation(), "captured local variable by reference might go out of scope before lambda is called"); 0064 } 0065 } 0066 } 0067 }