summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2019-04-12 18:39:22 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2019-04-15 08:37:54 +0200
commitb52f309f2b9037ee53ab8ac2d66967c012ba82f1 (patch)
tree4a4ace081c742af0cef50909e06394d9aef80345 /compilerplugins
parent897493fbd34a1bd10320767b48cbf04d422f89b3 (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.cxx5
-rw-r--r--compilerplugins/clang/simplifyconstruct.cxx37
-rw-r--r--compilerplugins/clang/test/simplifyconstruct.cxx31
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: */