summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2016-12-09 20:00:26 +0100
committerStephan Bergmann <sbergman@redhat.com>2016-12-09 20:00:26 +0100
commitcbf5b21f2a65bbb342295200f6ad93a00f90733e (patch)
tree2920078d64bccf3cff38ad35a1d5b0899470f471 /compilerplugins
parentc260580daa4fe78093265c1359c4d54677d76470 (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')
-rw-r--r--compilerplugins/clang/vclwidgets.cxx33
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;
}