diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-01-31 14:46:38 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-02-01 12:15:22 +0000 |
commit | 2489000d3fd66319a8355fd4e37cfdfda47296d0 (patch) | |
tree | caad79e7b5bec3863604b20190b682c0d73d2b25 /compilerplugins | |
parent | 595848c85acc2609fcc48a40c7a9f216a2722cd8 (diff) |
loplugin:useuniqueptr extend to check local vars
just the simple and obvious case for now, of a local var being allocated
and deleted inside a single local block, and the delete happening at the
end of the block
Change-Id: I3a7a094da543debdcd2374737c2ecff91d644625
Reviewed-on: https://gerrit.libreoffice.org/33749
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/useuniqueptr.cxx | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/compilerplugins/clang/useuniqueptr.cxx b/compilerplugins/clang/useuniqueptr.cxx index 82d95e56c45a..155fa0e2b568 100644 --- a/compilerplugins/clang/useuniqueptr.cxx +++ b/compilerplugins/clang/useuniqueptr.cxx @@ -32,7 +32,8 @@ public: TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } - bool VisitCXXDestructorDecl(const CXXDestructorDecl* ); + bool VisitCXXDestructorDecl(const CXXDestructorDecl * ); + bool VisitCompoundStmt(const CompoundStmt * ); }; bool UseUniquePtr::VisitCXXDestructorDecl(const CXXDestructorDecl* destructorDecl) @@ -130,6 +131,50 @@ bool UseUniquePtr::VisitCXXDestructorDecl(const CXXDestructorDecl* destructorDec return true; } +bool UseUniquePtr::VisitCompoundStmt(const CompoundStmt* compoundStmt) +{ + if (ignoreLocation(compoundStmt)) + return true; + if (isInUnoIncludeFile(compoundStmt->getLocStart())) + return true; + if (compoundStmt->size() == 0) { + return true; + } + + const CXXDeleteExpr* deleteExpr = dyn_cast<CXXDeleteExpr>(compoundStmt->body_back()); + if (deleteExpr == nullptr) { + return true; + } + + const ImplicitCastExpr* pCastExpr = dyn_cast<ImplicitCastExpr>(deleteExpr->getArgument()); + if (!pCastExpr) + return true; + const DeclRefExpr* declRefExpr = dyn_cast<DeclRefExpr>(pCastExpr->getSubExpr()); + if (!declRefExpr) + return true; + const VarDecl* varDecl = dyn_cast<VarDecl>(declRefExpr->getDecl()); + if (!varDecl) + return true; + if (!varDecl->hasInit() || !dyn_cast<CXXNewExpr>(varDecl->getInit())) + return true; + // determine if the var is declared inside the same block as the delete. + // @TODO there should surely be a better way to do this + if (varDecl->getLocStart() < compoundStmt->getLocStart()) + return true; + + report( + DiagnosticsEngine::Warning, + "deleting a local variable at the end of a block, is a sure sign it should be using std::unique_ptr for that var", + deleteExpr->getLocStart()) + << deleteExpr->getSourceRange(); + report( + DiagnosticsEngine::Note, + "var is here", + varDecl->getLocStart()) + << varDecl->getSourceRange(); + return true; +} + loplugin::Plugin::Registration< UseUniquePtr > X("useuniqueptr"); } |