diff options
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; } |