bump product version to 6.4.0.3
[LibreOffice.git] / compilerplugins / clang / unnecessarycatchthrow.cxx
blob903e903823ab0da74b8a571a48ec7450ef78736d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #ifndef LO_CLANG_SHARED_PLUGINS
12 #include <cassert>
13 #include <string>
14 #include <iostream>
15 #include <fstream>
16 #include <set>
18 #include <clang/AST/CXXInheritance.h>
19 #include "compat.hxx"
20 #include "plugin.hxx"
22 /**
23 look for unnecessary blocks that just catch and rethrow:
24 try {
25 stuff
26 } catch (exception const &) {
27 throw;
31 namespace {
33 class UnnecessaryCatchThrow:
34 public loplugin::FilteringPlugin<UnnecessaryCatchThrow>
36 public:
37 explicit UnnecessaryCatchThrow(loplugin::InstantiationData const & data): FilteringPlugin(data) {}
39 virtual void run() override
41 TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
44 bool VisitCXXTryStmt(CXXTryStmt const *);
47 bool UnnecessaryCatchThrow::VisitCXXTryStmt(CXXTryStmt const * tryStmt)
49 if (ignoreLocation(tryStmt))
50 return true;
51 if (tryStmt->getNumHandlers() != 1)
52 return true;
53 auto catchStmt = tryStmt->getHandler(0);
54 auto compoundStmt = dyn_cast<CompoundStmt>(catchStmt->getHandlerBlock());
55 if (!compoundStmt || compoundStmt->size() != 1)
56 return true;
57 auto throwExpr = dyn_cast<CXXThrowExpr>(compoundStmt->body_front());
58 if (!throwExpr)
59 return true;
60 auto subExpr = throwExpr->getSubExpr();
61 if (subExpr)
63 if (auto cxxConstructExpr = dyn_cast<CXXConstructExpr>(subExpr)) {
64 if (!cxxConstructExpr->getConstructor()->isCopyConstructor())
65 return true;
66 if (!cxxConstructExpr->getConstructor()->getParent()->hasAttr<FinalAttr>())
67 return true;
68 if (cxxConstructExpr->getNumArgs() != 1)
69 return true;
70 subExpr = cxxConstructExpr->getArg(0);
72 auto declRefExpr = dyn_cast<DeclRefExpr>(subExpr->IgnoreImpCasts());
73 if (!declRefExpr)
74 return true;
75 if (declRefExpr->getDecl() != catchStmt->getExceptionDecl())
76 return true;
79 report( DiagnosticsEngine::Warning, "unnecessary catch and throw",
80 compat::getBeginLoc(catchStmt))
81 << catchStmt->getSourceRange();
82 return true;
86 loplugin::Plugin::Registration< UnnecessaryCatchThrow > unnecessarycatchthrow("unnecessarycatchthrow");
88 } // namespace
90 #endif // LO_CLANG_SHARED_PLUGINS
92 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */