diff options
author | Noel Grandin <noel@peralex.com> | 2015-01-09 11:33:52 +0200 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2015-04-09 20:10:00 +0100 |
commit | eabaca0cf1382242c6f68084ece93e35cd8fab04 (patch) | |
tree | 033dbe93bf8bb7e024661c7cae67c6330c5cb057 /compilerplugins | |
parent | 1798a4433280a6cae38fe535fb043a8e27d7f95a (diff) |
vcl:compilerplugin: new rule, no passing of vcl::Window by VclPtr
to prevent problems with accidentally deleting an object by doing this:
Button *pButton = new Button(NULL);
...
pButton->callAMethodThatTakesARef(pButton);
Since we take a ref as we construct a temporary VclReference<> - but
this will dispose & delete the pButton as we return to the frame doing
the callAMethod
Change-Id: I60fc211b27fe7ff463aa58f1da106f430fc65529
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/vclwidgets.cxx | 53 |
1 files changed, 21 insertions, 32 deletions
diff --git a/compilerplugins/clang/vclwidgets.cxx b/compilerplugins/clang/vclwidgets.cxx index 896cd3f38889..1f8e05b9692f 100644 --- a/compilerplugins/clang/vclwidgets.cxx +++ b/compilerplugins/clang/vclwidgets.cxx @@ -37,8 +37,6 @@ public: bool VisitParmVarDecl(ParmVarDecl const * decl); - bool VisitVarDecl( const VarDecl* var ); - bool VisitFunctionDecl( const FunctionDecl* var ); }; @@ -90,7 +88,7 @@ bool VCLWidgets::VisitCXXRecordDecl(const CXXRecordDecl * recordDecl) { } bool foundVclPtr = false; for(auto fieldDecl : recordDecl->fields()) { - if (fieldDecl->getType().getAsString().find("VclPtr")==0) { + if (fieldDecl->getType().getAsString().find("VclPtr") != std::string::npos) { foundVclPtr = true; break; } @@ -153,38 +151,24 @@ bool VCLWidgets::VisitFieldDecl(const FieldDecl * fieldDecl) { return true; } -bool VCLWidgets::VisitParmVarDecl(ParmVarDecl const * pvDecl) { +bool VCLWidgets::VisitParmVarDecl(ParmVarDecl const * pvDecl) +{ if (ignoreLocation(pvDecl)) { return true; } - // check if this parameter is derived from Window - if (isPointerToWindowSubclass(pvDecl->getType())) { - report( - DiagnosticsEngine::Remark, - "vcl::Window subclass passed as a pointer parameter, should be wrapped in VclPtr.", - pvDecl->getLocation()) - << pvDecl->getSourceRange(); - } - return true; -} - -bool VCLWidgets::VisitVarDecl( const VarDecl* varDecl ) -{ - if (ignoreLocation(varDecl)) { + // ignore the stuff in the VclPtr template class + const CXXMethodDecl *pMethodDecl = dyn_cast<CXXMethodDecl>(pvDecl->getDeclContext()); + if (pMethodDecl + && pMethodDecl->getParent()->getQualifiedNameAsString().find("VclPtr") != std::string::npos) { return true; } - if (!varDecl->isLocalVarDecl()) - return true; - - // check if this variables type is derived from Window - if (isPointerToWindowSubclass(varDecl->getType())) { + if (pvDecl->getType().getAsString().find("VclPtr") != std::string::npos) { report( - DiagnosticsEngine::Remark, - "vcl::Window subclass declared as a pointer var, should be wrapped in VclPtr.", - varDecl->getLocation()) - << varDecl->getSourceRange(); + DiagnosticsEngine::Warning, + "vcl::Window subclass passed as a VclPtr parameter, should be passed as a raw pointer.", + pvDecl->getLocation()) + << pvDecl->getSourceRange(); } - return true; } @@ -193,12 +177,17 @@ bool VCLWidgets::VisitFunctionDecl( const FunctionDecl* functionDecl ) if (ignoreLocation(functionDecl)) { return true; } + // ignore the stuff in the VclPtr template class + const CXXMethodDecl *pMethodDecl = dyn_cast<CXXMethodDecl>(functionDecl); + if (pMethodDecl + && pMethodDecl->getParent()->getQualifiedNameAsString().find("VclPtr") != std::string::npos) { + return true; + } QualType t1 { compat::getReturnType(*functionDecl) }; - // check if this variables type is derived from Window - if (isPointerToWindowSubclass(t1)) { + if (t1.getAsString().find("VclPtr") != std::string::npos) { report( - DiagnosticsEngine::Remark, - "vcl::Window subclass declared as a return type from a method/function, should be wrapped in VclPtr.", + DiagnosticsEngine::Warning, + "VclPtr declared as a return type from a method/function, should be passed as a raw pointer.", functionDecl->getLocation()) << functionDecl->getSourceRange(); } |