File indexing completed on 2024-05-12 05:40:58

0001 /*
0002     SPDX-FileCopyrightText: 2016 Sergio Martins <smartins@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "post-event.h"
0008 #include "StringUtils.h"
0009 #include "TypeUtils.h"
0010 
0011 #include <clang/AST/Expr.h>
0012 #include <clang/AST/Stmt.h>
0013 #include <clang/Basic/LLVM.h>
0014 #include <llvm/Support/Casting.h>
0015 
0016 class ClazyContext;
0017 
0018 using namespace clang;
0019 
0020 PostEvent::PostEvent(const std::string &name, ClazyContext *context)
0021     : CheckBase(name, context, Option_CanIgnoreIncludes)
0022 {
0023 }
0024 
0025 void PostEvent::VisitStmt(clang::Stmt *stmt)
0026 {
0027     auto *callexpr = dyn_cast<CallExpr>(stmt);
0028     if (!callexpr) {
0029         return;
0030     }
0031 
0032     auto name = clazy::qualifiedMethodName(callexpr);
0033 
0034     const bool isPostEvent = name == "QCoreApplication::postEvent";
0035     const bool isSendEvent = name == "QCoreApplication::sendEvent";
0036 
0037     // if (!isPostEvent && !isSendEvent)
0038     //  Send event has false-positives
0039     if (!isPostEvent) {
0040         return;
0041     }
0042 
0043     Expr *event = callexpr->getNumArgs() > 1 ? callexpr->getArg(1) : nullptr;
0044     if (!event || clazy::simpleTypeName(event->getType(), lo()) != "QEvent *") {
0045         return;
0046     }
0047 
0048     bool isStack = false;
0049     bool isHeap = false;
0050     clazy::heapOrStackAllocated(event, "QEvent", lo(), isStack, isHeap);
0051 
0052     if (isStack || isHeap) {
0053         if (isSendEvent && isHeap) {
0054             emitWarning(stmt, "Events passed to sendEvent should be stack allocated");
0055         } else if (isPostEvent && isStack) {
0056             emitWarning(stmt, "Events passed to postEvent should be heap allocated");
0057         }
0058     } else {
0059         // It's something else, like an rvalue, ignore it
0060     }
0061 }