diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2016-08-26 12:40:43 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2016-08-26 12:40:43 +0200 |
commit | 28cb2c1764f2365d69ce09cb69f0f5a676458a33 (patch) | |
tree | 614b44a9dc1b4928af5db1880e9869cd3e997eb1 /compilerplugins | |
parent | 6a1bebcc890c04acdc79236ff54cdd49b27be71a (diff) |
loplugin:refcounting: also cover temporaries being directly stack managed
Change-Id: Ib0f7c60df1d2fba0d4d9d3fa6faf3bb97867ebc0
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/refcounting.cxx | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/compilerplugins/clang/refcounting.cxx b/compilerplugins/clang/refcounting.cxx index 523f0486eafc..97eea57ba5f7 100644 --- a/compilerplugins/clang/refcounting.cxx +++ b/compilerplugins/clang/refcounting.cxx @@ -53,6 +53,14 @@ public: bool VisitVarDecl(const VarDecl *); bool VisitFunctionDecl(const FunctionDecl *); + // Creation of temporaries with one argument are represented by + // CXXFunctionalCastExpr, while any other number of arguments are + // represented by CXXTemporaryObjectExpr: + bool VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr const * expr) + { return visitTemporaryObjectExpr(expr); } + bool VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr const * expr) + { return visitTemporaryObjectExpr(expr); } + bool WalkUpFromObjCIvarDecl(ObjCIvarDecl * decl) { // Don't recurse into WalkUpFromFieldDecl, as VisitFieldDecl calls // FieldDecl::getParent, which triggers an assertion at least with @@ -63,6 +71,8 @@ public: private: void checkUnoReference(QualType qt, const Decl* decl, const std::string& rParentName, const std::string& rDeclName); + + bool visitTemporaryObjectExpr(Expr const * expr); }; bool BaseCheckNotSubclass(const CXXRecordDecl *BaseDefinition, void *p) { @@ -343,6 +353,38 @@ void RefCounting::checkUnoReference(QualType qt, const Decl* decl, const std::st } } +bool RefCounting::visitTemporaryObjectExpr(Expr const * expr) { + if (ignoreLocation(expr)) { + return true; + } + auto t = expr->getType(); + if (containsSvRefBaseSubclass(t.getTypePtr())) { + report( + DiagnosticsEngine::Warning, + ("Temporary object of SvRefBase subclass %0 being directly stack" + " managed, should be managed via tools::SvRef"), + expr->getLocStart()) + << t.getUnqualifiedType() << expr->getSourceRange(); + } else if (containsSalhelperReferenceObjectSubclass(t.getTypePtr())) { + report( + DiagnosticsEngine::Warning, + ("Temporary object of salhelper::SimpleReferenceObject subclass %0" + " being directly stack managed, should be managed via" + " rtl::Reference"), + expr->getLocStart()) + << t.getUnqualifiedType() << expr->getSourceRange(); + } else if (containsXInterfaceSubclass(t)) { + report( + DiagnosticsEngine::Warning, + ("Temporary object of css::uno::XInterface subclass %0 being" + " directly stack managed, should be managed via" + " css::uno::Reference"), + expr->getLocStart()) + << t.getUnqualifiedType() << expr->getSourceRange(); + } + return true; +} + bool RefCounting::VisitFieldDecl(const FieldDecl * fieldDecl) { if (ignoreLocation(fieldDecl)) { return true; |