diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2016-12-09 20:00:26 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2016-12-09 20:00:26 +0100 |
commit | cbf5b21f2a65bbb342295200f6ad93a00f90733e (patch) | |
tree | 2920078d64bccf3cff38ad35a1d5b0899470f471 /compilerplugins/clang/vclwidgets.cxx | |
parent | c260580daa4fe78093265c1359c4d54677d76470 (diff) |
Catch some misuses of VclPtr construction
...that go unnoticed due to the non-explicit VclPtr::oeprator reference_type *
Change-Id: Ia63edf8425d3ecb7c7f98eb56a710ac0cceccb67
Diffstat (limited to 'compilerplugins/clang/vclwidgets.cxx')
-rw-r--r-- | compilerplugins/clang/vclwidgets.cxx | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/compilerplugins/clang/vclwidgets.cxx b/compilerplugins/clang/vclwidgets.cxx index bb0ad54c8051..e90e40fe6e39 100644 --- a/compilerplugins/clang/vclwidgets.cxx +++ b/compilerplugins/clang/vclwidgets.cxx @@ -825,19 +825,38 @@ bool VCLWidgets::VisitCXXConstructExpr( const CXXConstructExpr* constructExpr ) if (ignoreLocation(constructExpr)) { return true; } - StringRef aFileName = compiler.getSourceManager().getFilename(compiler.getSourceManager().getSpellingLoc(constructExpr->getLocStart())); - if (aFileName == SRCDIR "/include/vcl/vclptr.hxx") - return true; if (constructExpr->getConstructionKind() != CXXConstructExpr::CK_Complete) { return true; } const CXXConstructorDecl* pConstructorDecl = constructExpr->getConstructor(); const CXXRecordDecl* recordDecl = pConstructorDecl->getParent(); if (isDerivedFromVclReferenceBase(recordDecl)) { - report( - DiagnosticsEngine::Warning, - "Calling constructor of a VclReferenceBase-derived type directly; all such creation should go via VclPtr<>::Create", - constructExpr->getExprLoc()); + StringRef aFileName = compiler.getSourceManager().getFilename(compiler.getSourceManager().getSpellingLoc(constructExpr->getLocStart())); + if (aFileName != SRCDIR "/include/vcl/vclptr.hxx") { + report( + DiagnosticsEngine::Warning, + "Calling constructor of a VclReferenceBase-derived type directly; all such creation should go via VclPtr<>::Create", + constructExpr->getExprLoc()); + } + } else if (auto d = dyn_cast<ClassTemplateSpecializationDecl>(recordDecl)) { + if (d->getTemplateArgs().size() == 1) { + auto check = loplugin::DeclCheck(recordDecl); + if ((check.Class("ScopedVclPtr").GlobalNamespace() + || check.Class("ScopedVclPtrInstance").GlobalNamespace() + || check.Class("VclPtr").GlobalNamespace() + || check.Class("VclPtrInstance").GlobalNamespace())) + { + auto t = d->getTemplateArgs()[0].getAsType(); + if (!containsVclReferenceBaseSubclass(t)) { + report( + DiagnosticsEngine::Warning, + ("constructing an instance of %0 where the argument" + " type %1 is not derived from VclReferenceBase"), + constructExpr->getExprLoc()) + << recordDecl << t << constructExpr->getSourceRange(); + } + } + } } return true; } |