summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2017-09-26 09:53:13 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2017-09-26 11:27:08 +0200
commitade276923280230a93d3fbd44b7066b2e9d5f93b (patch)
treeb23a3f752fadfc1a518d56ea51c43da74eda3cc0 /compilerplugins
parentcae335091776738fdb2dfb295033803279d30409 (diff)
improve unnecessarycatchthrow plugin
it is not legal to eliminate a catch/re-throw where the re-throw expliciting mentions the exception variable and the exception variable is a non-final class Change-Id: I7fd88b0d004d2efa66aef2c0876e07f203da3c28 Reviewed-on: https://gerrit.libreoffice.org/42782 Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk> Tested-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/test/unnecessarycatchthrow.cxx23
-rw-r--r--compilerplugins/clang/unnecessarycatchthrow.cxx9
2 files changed, 32 insertions, 0 deletions
diff --git a/compilerplugins/clang/test/unnecessarycatchthrow.cxx b/compilerplugins/clang/test/unnecessarycatchthrow.cxx
index 5fb8d83bf9a6..a9b32d86fa84 100644
--- a/compilerplugins/clang/test/unnecessarycatchthrow.cxx
+++ b/compilerplugins/clang/test/unnecessarycatchthrow.cxx
@@ -30,6 +30,29 @@ int main()
std::cout << "test";
throw;
}
+
+}
+
+void test1()
+{
+ // cannot remove catch/throw where the throw is of a non-final class
+ struct B {};
+ struct D: B {};
+ try {
+ throw D();
+ } catch (B & b) {
+ throw b; // must not be removed
+ }
+};
+
+void test2()
+{
+ struct F final {};
+ try {
+ throw F();
+ } catch (F const & f) { // expected-error {{unnecessary catch and throw [loplugin:unnecessarycatchthrow]}}
+ throw f;
+ }
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/compilerplugins/clang/unnecessarycatchthrow.cxx b/compilerplugins/clang/unnecessarycatchthrow.cxx
index c69713799a82..948394e9e37a 100644
--- a/compilerplugins/clang/unnecessarycatchthrow.cxx
+++ b/compilerplugins/clang/unnecessarycatchthrow.cxx
@@ -58,6 +58,15 @@ bool UnnecessaryCatchThrow::VisitCXXTryStmt(CXXTryStmt const * tryStmt)
auto subExpr = throwExpr->getSubExpr();
if (subExpr)
{
+ if (auto cxxConstructExpr = dyn_cast<CXXConstructExpr>(subExpr)) {
+ if (!cxxConstructExpr->getConstructor()->isCopyConstructor())
+ return true;
+ if (!cxxConstructExpr->getConstructor()->getParent()->hasAttr<FinalAttr>())
+ return true;
+ if (cxxConstructExpr->getNumArgs() != 1)
+ return true;
+ subExpr = cxxConstructExpr->getArg(0);
+ }
auto declRefExpr = dyn_cast<DeclRefExpr>(subExpr->IgnoreImpCasts());
if (!declRefExpr)
return true;