File indexing completed on 2024-05-12 05:41:02

0001 /*
0002     SPDX-FileCopyrightText: 2018 Sergio Martins <smartins@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "qstring-varargs.h"
0008 #include "StringUtils.h"
0009 
0010 #include <clang/AST/Decl.h>
0011 #include <clang/AST/DeclCXX.h>
0012 #include <clang/AST/Expr.h>
0013 #include <clang/AST/OperationKinds.h>
0014 #include <clang/AST/Stmt.h>
0015 #include <clang/AST/Type.h>
0016 #include <clang/Basic/LLVM.h>
0017 #include <llvm/ADT/StringRef.h>
0018 #include <llvm/Support/Casting.h>
0019 
0020 class ClazyContext;
0021 
0022 using namespace clang;
0023 
0024 QStringVarargs::QStringVarargs(const std::string &name, ClazyContext *context)
0025     : CheckBase(name, context, Option_CanIgnoreIncludes)
0026 {
0027 }
0028 
0029 void QStringVarargs::VisitStmt(clang::Stmt *stmt)
0030 {
0031     auto *binop = dyn_cast<BinaryOperator>(stmt);
0032     if (!binop || binop->getOpcode() != BO_Comma) {
0033         return;
0034     }
0035 
0036     auto *callexpr = dyn_cast<CallExpr>(binop->getLHS());
0037     if (!callexpr) {
0038         return;
0039     }
0040 
0041     FunctionDecl *func = callexpr->getDirectCallee();
0042     if (!func || clazy::name(func) != "__builtin_trap") {
0043         return;
0044     }
0045 
0046     QualType qt = binop->getRHS()->getType();
0047     CXXRecordDecl *record = qt->getAsCXXRecordDecl();
0048     if (!record) {
0049         return;
0050     }
0051 
0052     StringRef name = clazy::name(record);
0053     if (name == "QString" || name == "QByteArray") {
0054         emitWarning(stmt, std::string("Passing ") + name.data() + std::string(" to variadic function"));
0055     }
0056 }