diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2019-04-12 18:39:22 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2019-04-15 08:37:54 +0200 |
commit | b52f309f2b9037ee53ab8ac2d66967c012ba82f1 (patch) | |
tree | 4a4ace081c742af0cef50909e06394d9aef80345 /compilerplugins | |
parent | 897493fbd34a1bd10320767b48cbf04d422f89b3 (diff) |
improve loplugin simplifyconstruct
to find stuff like
OUString s = OUString("xxx")
Change-Id: Ie7ed074c1ae012734c67a2a89c564c1900a4ab04
Reviewed-on: https://gerrit.libreoffice.org/70697
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/sharedvisitor/sharedvisitor.cxx | 5 | ||||
-rw-r--r-- | compilerplugins/clang/simplifyconstruct.cxx | 37 | ||||
-rw-r--r-- | compilerplugins/clang/test/simplifyconstruct.cxx | 31 |
3 files changed, 73 insertions, 0 deletions
diff --git a/compilerplugins/clang/sharedvisitor/sharedvisitor.cxx b/compilerplugins/clang/sharedvisitor/sharedvisitor.cxx index 5b72c329691d..66e43b96f67b 100644 --- a/compilerplugins/clang/sharedvisitor/sharedvisitor.cxx +++ b/compilerplugins/clang/sharedvisitor/sharedvisitor.cxx @@ -626,6 +626,11 @@ public: if( !externVar->VisitVarDecl( arg )) externVar = nullptr; } + if( simplifyConstruct != nullptr ) + { + if( !simplifyConstruct->VisitVarDecl( arg )) + simplifyConstruct = nullptr; + } if( stringStatic != nullptr ) { if( !stringStatic->VisitVarDecl( arg )) diff --git a/compilerplugins/clang/simplifyconstruct.cxx b/compilerplugins/clang/simplifyconstruct.cxx index 652a980cec6a..c3e28ce7bcda 100644 --- a/compilerplugins/clang/simplifyconstruct.cxx +++ b/compilerplugins/clang/simplifyconstruct.cxx @@ -31,6 +31,7 @@ public: virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } bool VisitCXXConstructExpr(CXXConstructExpr const*); + bool VisitVarDecl(VarDecl const*); // ignore some contexts within which nullptr is fine bool TraverseReturnStmt(ReturnStmt*) { return true; } @@ -69,6 +70,42 @@ bool SimplifyConstruct::VisitCXXConstructExpr(CXXConstructExpr const* constructE return true; } +bool SimplifyConstruct::VisitVarDecl(VarDecl const* varDecl) +{ + if (ignoreLocation(varDecl)) + return true; + // cannot use OUString s("xxx") style syntax in a parameter + if (isa<ParmVarDecl>(varDecl)) + return true; + varDecl = varDecl->getCanonicalDecl(); + if (!varDecl->getInit()) + return true; + if (varDecl->getInitStyle() != VarDecl::InitializationStyle::CInit) + return true; + if (!varDecl->getType()->isRecordType()) + return true; + if (isa<AutoType>(varDecl->getType())) + return true; + + auto init = varDecl->getInit()->IgnoreImplicit(); + auto functionalCast = dyn_cast<CXXFunctionalCastExpr>(init); + if (!functionalCast) + return true; + + // e.g. the LANGUAGE_DONTKNOW defines + if (compiler.getSourceManager().isMacroBodyExpansion(compat::getBeginLoc(init))) + return true; + + // varDecl->getInit()->IgnoreImplicit()->dump(); + // varDecl->getType()->dump(); + // varDecl->getType()->getUnqualifiedDesugaredType()->dump(); + + report(DiagnosticsEngine::Warning, "simplify", varDecl->getLocation()) + << varDecl->getSourceRange(); + + return true; +} + loplugin::Plugin::Registration<SimplifyConstruct> simplifyconstruct("simplifyconstruct", true); } diff --git a/compilerplugins/clang/test/simplifyconstruct.cxx b/compilerplugins/clang/test/simplifyconstruct.cxx index ca4b3a1a198c..8fbffc8ba2d7 100644 --- a/compilerplugins/clang/test/simplifyconstruct.cxx +++ b/compilerplugins/clang/test/simplifyconstruct.cxx @@ -10,6 +10,8 @@ #include <memory> #include <rtl/ref.hxx> +namespace test1 +{ struct Foo { void acquire(); @@ -27,8 +29,11 @@ class Foo1 { } }; +} // no warning expected when using std::unique_ptr constructor with a custom deleter +namespace test2 +{ struct ITypeLib { }; @@ -43,5 +48,31 @@ void func2() p->Release(); }); } +} + +namespace test3 +{ +struct Foo +{ + void acquire(); + void release(); +}; +void f(Foo* f) +{ + // expected-error@+1 {{simplify [loplugin:simplifyconstruct]}} + rtl::Reference<Foo> x = rtl::Reference(f); +} +} + +// no warning expected +namespace test4 +{ +struct Foo +{ + void acquire(); + void release(); +}; +void f(Foo* f) { auto x = rtl::Reference(f); } +} /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |