summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2017-01-31 14:46:38 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2017-02-01 12:15:22 +0000
commit2489000d3fd66319a8355fd4e37cfdfda47296d0 (patch)
treecaad79e7b5bec3863604b20190b682c0d73d2b25 /compilerplugins
parent595848c85acc2609fcc48a40c7a9f216a2722cd8 (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.cxx47
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");
}