summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2016-08-26 12:40:43 +0200
committerStephan Bergmann <sbergman@redhat.com>2016-08-26 12:40:43 +0200
commit28cb2c1764f2365d69ce09cb69f0f5a676458a33 (patch)
tree614b44a9dc1b4928af5db1880e9869cd3e997eb1 /compilerplugins
parent6a1bebcc890c04acdc79236ff54cdd49b27be71a (diff)
loplugin:refcounting: also cover temporaries being directly stack managed
Change-Id: Ib0f7c60df1d2fba0d4d9d3fa6faf3bb97867ebc0
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/refcounting.cxx42
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;