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>
This commit is contained in:
@@ -30,6 +30,29 @@ int main()
|
|||||||
std::cout << "test";
|
std::cout << "test";
|
||||||
throw;
|
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: */
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
||||||
|
@@ -58,6 +58,15 @@ bool UnnecessaryCatchThrow::VisitCXXTryStmt(CXXTryStmt const * tryStmt)
|
|||||||
auto subExpr = throwExpr->getSubExpr();
|
auto subExpr = throwExpr->getSubExpr();
|
||||||
if (subExpr)
|
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());
|
auto declRefExpr = dyn_cast<DeclRefExpr>(subExpr->IgnoreImpCasts());
|
||||||
if (!declRefExpr)
|
if (!declRefExpr)
|
||||||
return true;
|
return true;
|
||||||
|
Reference in New Issue
Block a user