From 2489000d3fd66319a8355fd4e37cfdfda47296d0 Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Tue, 31 Jan 2017 14:46:38 +0200 Subject: 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 Reviewed-by: Noel Grandin --- compilerplugins/clang/useuniqueptr.cxx | 47 +++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'compilerplugins') 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(compoundStmt->body_back()); + if (deleteExpr == nullptr) { + return true; + } + + const ImplicitCastExpr* pCastExpr = dyn_cast(deleteExpr->getArgument()); + if (!pCastExpr) + return true; + const DeclRefExpr* declRefExpr = dyn_cast(pCastExpr->getSubExpr()); + if (!declRefExpr) + return true; + const VarDecl* varDecl = dyn_cast(declRefExpr->getDecl()); + if (!varDecl) + return true; + if (!varDecl->hasInit() || !dyn_cast(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"); } -- cgit