diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-09-22 14:52:24 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-09-23 09:01:46 +0200 |
commit | 2684aefcf5d2804351bda01a2d2fe7bbbd351451 (patch) | |
tree | 5c19a705883a068a4945d7e49376296e341cb191 /compilerplugins/clang/unnecessarycatchthrow.cxx | |
parent | 1fde962b71860d77fb10e9b16c9d5b6c124d9b61 (diff) |
new loplugin unnecessarycatchthrow
Change-Id: Iabab71ee076227bc38447ec109afaea1e53a86a6
Reviewed-on: https://gerrit.libreoffice.org/42643
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins/clang/unnecessarycatchthrow.cxx')
-rw-r--r-- | compilerplugins/clang/unnecessarycatchthrow.cxx | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/compilerplugins/clang/unnecessarycatchthrow.cxx b/compilerplugins/clang/unnecessarycatchthrow.cxx new file mode 100644 index 000000000000..c69713799a82 --- /dev/null +++ b/compilerplugins/clang/unnecessarycatchthrow.cxx @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <cassert> +#include <string> +#include <iostream> +#include <fstream> +#include <set> + +#include <clang/AST/CXXInheritance.h> +#include "compat.hxx" +#include "plugin.hxx" + +/** +look for unnecessary blocks that just catch and rethrow: + try { + stuff + } catch (exception const &) { + throw; + } +*/ + +namespace { + +class UnnecessaryCatchThrow: + public RecursiveASTVisitor<UnnecessaryCatchThrow>, public loplugin::Plugin +{ +public: + explicit UnnecessaryCatchThrow(InstantiationData const & data): Plugin(data) {} + + virtual void run() override + { + TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); + } + + bool VisitCXXTryStmt(CXXTryStmt const *); +}; + +bool UnnecessaryCatchThrow::VisitCXXTryStmt(CXXTryStmt const * tryStmt) +{ + if (ignoreLocation(tryStmt)) + return true; + if (tryStmt->getNumHandlers() != 1) + return true; + auto catchStmt = tryStmt->getHandler(0); + auto compoundStmt = dyn_cast<CompoundStmt>(catchStmt->getHandlerBlock()); + if (!compoundStmt || compoundStmt->size() != 1) + return true; + auto throwExpr = dyn_cast<CXXThrowExpr>(compoundStmt->body_front()); + if (!throwExpr) + return true; + auto subExpr = throwExpr->getSubExpr(); + if (subExpr) + { + auto declRefExpr = dyn_cast<DeclRefExpr>(subExpr->IgnoreImpCasts()); + if (!declRefExpr) + return true; + if (declRefExpr->getDecl() != catchStmt->getExceptionDecl()) + return true; + } + + report( DiagnosticsEngine::Warning, "unnecessary catch and throw", + catchStmt->getLocStart()) + << catchStmt->getSourceRange(); + return true; +} + + +loplugin::Plugin::Registration< UnnecessaryCatchThrow > X("unnecessarycatchthrow"); + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |