[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2023-10-07 Thread Stephan Bergmann (via logerrit)
 compilerplugins/clang/ostr.cxx   |  286 +++
 compilerplugins/clang/test/ostr.cxx  |   98 +
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 3 files changed, 385 insertions(+)

New commits:
commit 7ef3d937415185ef66e32dd3043783eddcd03db5
Author: Stephan Bergmann 
AuthorDate: Fri Oct 6 09:50:54 2023 +0200
Commit: Stephan Bergmann 
CommitDate: Sat Oct 7 22:34:09 2023 +0200

loplugin:ostr: Rewrite some uses of O[U]String to use ""_ostr/u""_ustr 
literals

This is a first cut at rewriting uses of OUString constructed from u"..." as
u"..."_ustr.  It covers the same changes as
 "WIP: Delete OUString 
UTF-16
string literal ctor/assignment op", but does so with automatic rewriting 
(see
e0c33ec15f53a01fa3ee07489871bbe09bb5c9c3 "loplugin:ostr: automatic rewrite",
plus a handful of 002b0a9d5793e07609f953b9961b04bcab7a7e3f "loplugin:ostr:
manual modifications" where automatic rewriting wasn't set up to handle 
macro
bodies).

The compilation-time impact of all those changes appears to be negligible:  
For
some Windows build of mine, just touching the files that would be affected 
by
002b0a9d5793e07609f953b9961b04bcab7a7e3f and
e0c33ec15f53a01fa3ee07489871bbe09bb5c9c3 (but without actually applying 
those
changes yet) and doing `time /opt/lo/bin/make -O check screenshot PKGFORMAT=
gb_SUPPRESS_TESTS=x`, three times in a row reported sample real times of

  21m15.438s  23m17.840s  23m41.529s

and repeating all that with the two changes actually applied reported sample
real times of

  22m43.547s  21m42.687s  23m1.813s

The plugin itself is already prepared to do further rewrites (see the 
TODOs),
which will be done in follow-up commits.

Change-Id: I408ecf056dce1b9da683d7c377b8d9058df1558d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157676
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/ostr.cxx b/compilerplugins/clang/ostr.cxx
new file mode 100644
index ..13fd5df0b29a
--- /dev/null
+++ b/compilerplugins/clang/ostr.cxx
@@ -0,0 +1,286 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+#include 
+#include 
+
+#include "check.hxx"
+#include "compat.hxx"
+#include "plugin.hxx"
+
+// Rewrite some uses of O[U]String to use ""_ostr/u""_ustr literals.
+
+namespace
+{
+class Ostr : public loplugin::FilteringRewritePlugin
+{
+public:
+explicit Ostr(loplugin::InstantiationData const& data)
+: FilteringRewritePlugin(data)
+{
+}
+
+// Needed so that e.g.
+//
+//   struct S { OUString s; };
+//   S s = {u"foo"};
+//
+// is caught:
+bool shouldVisitImplicitCode() const { return true; }
+
+void run() override
+{
+if (compiler.getLangOpts().CPlusPlus)
+{
+TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+}
+}
+
+bool TraverseParmVarDecl(ParmVarDecl* decl)
+{
+// Otherwise,
+//
+//   struct S { void f(int = 0); };
+//   void S::f(int) {}
+//
+// would visit the default argument twice:
+if (decl->hasDefaultArg() && !decl->hasUninstantiatedDefaultArg()
+&& !decl->hasUnparsedDefaultArg() && 
!defaultArgs_.insert(decl->getDefaultArg()).second)
+{
+return true;
+}
+return RecursiveASTVisitor::TraverseParmVarDecl(decl);
+}
+
+bool TraverseCXXFunctionalCastExpr(CXXFunctionalCastExpr* expr)
+{
+functionalCasts_.push(expr);
+auto const ret = 
RecursiveASTVisitor::TraverseCXXFunctionalCastExpr(expr);
+functionalCasts_.pop();
+return ret;
+}
+
+bool VisitCXXConstructExpr(CXXConstructExpr const* expr)
+{
+if (ignoreLocation(expr))
+{
+return true;
+}
+if (!loplugin::DeclCheck(expr->getConstructor()->getParent())
+ .Class("OUString")
+ .Namespace("rtl")
+ .GlobalNamespace())
+{
+return true;
+}
+if (expr->getNumArgs() != 2)
+{
+return true;
+}
+if (!loplugin::TypeCheck(expr->getArg(1)->getType())
+ .Struct("Dummy")
+ .Namespace("libreoffice_internal")
+ .Namespace("rtl")
+ .GlobalNamespace())
+{
+return true;
+}
+auto const e2 = 
dyn_cast(expr->getArg(0)->IgnoreParenImpCasts());
+if 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2023-06-06 Thread Noel Grandin (via logerrit)
 compilerplugins/clang/test/staticmethods.cxx |   16 
 solenv/CompilerTest_compilerplugins_clang.mk |1 +
 2 files changed, 17 insertions(+)

New commits:
commit c28819ace52704494018f14744674fe09af2d593
Author: Noel Grandin 
AuthorDate: Tue Jun 6 10:16:22 2023 +0200
Commit: Noel Grandin 
CommitDate: Tue Jun 6 11:35:08 2023 +0200

add unit test for loplugin:staticmethods

Change-Id: Ied72c83dbc364f96e5b78a3cb915b23a1751ac0e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152646
Tested-by: Jenkins
Reviewed-by: Noel Grandin 

diff --git a/compilerplugins/clang/test/staticmethods.cxx 
b/compilerplugins/clang/test/staticmethods.cxx
new file mode 100644
index ..cd87c930dc23
--- /dev/null
+++ b/compilerplugins/clang/test/staticmethods.cxx
@@ -0,0 +1,16 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+class foo
+{
+// expected-error@+1 {{this member function can be declared static 
[loplugin:staticmethods]}}
+int method1() { return 5; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 05d0d6f3d088..a4bf3dbf45a9 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -77,6 +77,7 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/singlevalfields \
 compilerplugins/clang/test/staticconstfield \
 compilerplugins/clang/test/staticdynamic \
+compilerplugins/clang/test/staticmethods \
 compilerplugins/clang/test/stdfunction \
 compilerplugins/clang/test/stringadd \
 compilerplugins/clang/test/stringconcatauto \


[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2023-03-17 Thread Stephan Bergmann (via logerrit)
 compilerplugins/clang/rangedforcopy.cxx  |5 
 compilerplugins/clang/test/rangedforcopy.cxx |   30 +++
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 3 files changed, 36 insertions(+)

New commits:
commit d9f591bcd99f23d6dbf259107a9985f5e851a541
Author: Stephan Bergmann 
AuthorDate: Fri Mar 17 14:23:40 2023 +0100
Commit: Stephan Bergmann 
CommitDate: Fri Mar 17 16:47:09 2023 +

loplugin:rangedforcopy: Assume non-reference structured binding is 
intentional

See pending  "tdf#148008: 
do not
proceed after the marked range" for a use case.

Change-Id: Ief7cbb215068b6f5428c16a72896ef5612204128
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149056
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/rangedforcopy.cxx 
b/compilerplugins/clang/rangedforcopy.cxx
index 01124bb4d117..b0ab6bf35027 100644
--- a/compilerplugins/clang/rangedforcopy.cxx
+++ b/compilerplugins/clang/rangedforcopy.cxx
@@ -45,6 +45,11 @@ bool RangedForCopy::VisitCXXForRangeStmt( const 
CXXForRangeStmt* stmt )
 const VarDecl* varDecl = stmt->getLoopVariable();
 if (!varDecl)
   return true;
+if (isa(varDecl))
+{
+// Assume that use of a non-reference structured binding is 
intentional:
+return true;
+}
 
 const QualType type = varDecl->getType();
 if (type->isRecordType() && !type->isReferenceType() && 
!type->isPointerType())
diff --git a/compilerplugins/clang/test/rangedforcopy.cxx 
b/compilerplugins/clang/test/rangedforcopy.cxx
new file mode 100644
index ..f4346b18111d
--- /dev/null
+++ b/compilerplugins/clang/test/rangedforcopy.cxx
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+struct S
+{
+int i1;
+int i2;
+};
+
+void f(S const ()[2])
+{
+// expected-error-re@+1 {{Loop variable passed by value, pass by reference 
instead, e.g. 'const {{(struct )?}}S&' [loplugin:rangedforcopy]}}
+for (auto i : a)
+{
+(void)i;
+}
+for (auto[i1, i2] : a)
+{
+(void)i1;
+(void)i2;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index afa7621df37d..8e31cfdfc8f8 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -57,6 +57,7 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/passparamsbyref \
 compilerplugins/clang/test/passstuffbyref \
 compilerplugins/clang/test/pointerbool \
+compilerplugins/clang/test/rangedforcopy \
 compilerplugins/clang/test/reducevarscope \
 compilerplugins/clang/test/redundantcast \
 compilerplugins/clang/test/redundantfcast \


[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2022-11-11 Thread Stephan Bergmann (via logerrit)
 compilerplugins/clang/constmove.cxx  |   85 +++
 compilerplugins/clang/test/constmove.cxx |   25 +++
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 3 files changed, 111 insertions(+)

New commits:
commit 4c9093c95445c154c4ce7db1756ca936ea0752ca
Author: Stephan Bergmann 
AuthorDate: Fri Nov 11 10:09:16 2022 +0100
Commit: Stephan Bergmann 
CommitDate: Fri Nov 11 19:37:16 2022 +0100

New loplugin:constmove

"Find occurrences of std::move on const-qualified types.  While there might
theoretically be legitimate uses for such (for which this plugin would 
generate
false positives and would need to be updated), in practice they tend to 
point at
suspicious code that should be cleaned up in some way."

(All issues found for a Linux build have already been addressed with eleven
recent commits mentioning in their commit messages:  "I came across this 
code
with an upcoming loplugin:constmove that flags suspicious uses of std::move
involving const-qualified types.")

Change-Id: I891a66eb0ec5f9b7d93536bbccea0359893383df
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142589
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/constmove.cxx 
b/compilerplugins/clang/constmove.cxx
new file mode 100644
index ..63bafa188979
--- /dev/null
+++ b/compilerplugins/clang/constmove.cxx
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+// Find occurrences of std::move on const-qualified types.  While there might 
theoretically be
+// legitimate uses for such (for which this plugin would generate false 
positives and would need to
+// be updated), in practice they tend to point at suspicious code that should 
be cleaned up in some
+// way.
+
+#ifndef LO_CLANG_SHARED_PLUGINS
+
+#include "check.hxx"
+#include "plugin.hxx"
+
+namespace
+{
+class ConstMove final : public loplugin::FilteringPlugin
+{
+public:
+explicit ConstMove(loplugin::InstantiationData const& data)
+: FilteringPlugin(data)
+{
+}
+
+bool preRun() override { return compiler.getLangOpts().CPlusPlus; }
+
+void run() override
+{
+if (preRun())
+{
+TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+}
+}
+
+bool VisitCallExpr(CallExpr const* expr)
+{
+if (ignoreLocation(expr))
+{
+return true;
+}
+auto const t = expr->getType();
+if (!t.isConstQualified())
+{
+return true;
+}
+auto const d = expr->getDirectCallee();
+if (d == nullptr)
+{
+return true;
+}
+if (!loplugin::DeclCheck(d).Function("move").StdNamespace())
+{
+return true;
+}
+switch (expr->getNumArgs())
+{
+case 0:
+return true;
+case 1:
+break;
+default:
+if (!isa(expr->getArg(1)))
+{
+return true;
+}
+break;
+}
+report(DiagnosticsEngine::Warning, "suspicious 'std::move' from %0 to 
const-qualified %1",
+   expr->getExprLoc())
+<< expr->getArg(0)->IgnoreImplicit()->getType() << t << 
expr->getSourceRange();
+return true;
+}
+};
+
+static loplugin::Plugin::Registration constmove("constmove");
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/compilerplugins/clang/test/constmove.cxx 
b/compilerplugins/clang/test/constmove.cxx
new file mode 100644
index ..f6d2ed3ac9bf
--- /dev/null
+++ b/compilerplugins/clang/test/constmove.cxx
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+
+struct S
+{
+};
+
+void f(S const& s1, S s2)
+{
+// expected-error-re@+1 {{suspicious 'std::move' from 'const S' to 
const-qualified '{{.+}}' (aka 'const S') [loplugin:constmove]}}
+S v1(std::move(s1));
+(void)v1;
+S v2(std::move(s2));
+(void)v2;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk svx/source vcl/jsdialog

2022-04-30 Thread Noel Grandin (via logerrit)
 compilerplugins/clang/stringviewdangle.cxx  |  117 
 compilerplugins/clang/test/stringviewdangle.cxx |   37 +++
 solenv/CompilerTest_compilerplugins_clang.mk|1 
 svx/source/tbxctrls/StylesPreviewWindow.cxx |4 
 vcl/jsdialog/executor.cxx   |   10 +-
 5 files changed, 162 insertions(+), 7 deletions(-)

New commits:
commit 40077fe30919494f0ecd04c4620cac2334d3d382
Author: Noel Grandin 
AuthorDate: Sat Apr 30 09:10:48 2022 +0200
Commit: Noel Grandin 
CommitDate: Sat Apr 30 21:20:55 2022 +0200

new loplugin:stringviewdangle

to find places where string_view is pointing into a temporary String

Change-Id: Ib530b36f441e95d83d8f687d40a97516a0806721
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133656
Tested-by: Jenkins
Reviewed-by: Noel Grandin 

diff --git a/compilerplugins/clang/stringviewdangle.cxx 
b/compilerplugins/clang/stringviewdangle.cxx
new file mode 100644
index ..99cb852d03b6
--- /dev/null
+++ b/compilerplugins/clang/stringviewdangle.cxx
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#ifndef LO_CLANG_SHARED_PLUGINS
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "plugin.hxx"
+#include "check.hxx"
+#include "compat.hxx"
+#include "config_clang.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/StmtVisitor.h"
+
+/**
+Look for places where we are assigning a temporary O[U]String to a 
std::*string_view, which leads
+to a view pointing to freed memory.
+*/
+
+namespace
+{
+class StringViewDangle : public loplugin::FilteringPlugin
+{
+public:
+explicit StringViewDangle(loplugin::InstantiationData const& data)
+: FilteringPlugin(data)
+{
+}
+
+bool preRun() override { return true; }
+
+virtual void run() override
+{
+if (!preRun())
+return;
+TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+}
+
+bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr const*);
+bool VisitVarDecl(VarDecl const*);
+};
+
+static const Expr* IgnoreImplicitAndConversionOperator(const Expr* expr)
+{
+expr = expr->IgnoreImplicit();
+if (auto memberCall = dyn_cast(expr))
+{
+if (auto conversionDecl = 
dyn_cast_or_null(memberCall->getMethodDecl()))
+{
+if (!conversionDecl->isExplicit())
+expr = 
memberCall->getImplicitObjectArgument()->IgnoreImpCasts();
+}
+}
+return expr;
+}
+
+bool StringViewDangle::VisitCXXOperatorCallExpr(CXXOperatorCallExpr const* 
cxxOperatorCallExpr)
+{
+if (ignoreLocation(cxxOperatorCallExpr))
+return true;
+
+auto op = cxxOperatorCallExpr->getOperator();
+if (op != OO_Equal)
+return true;
+if (!loplugin::TypeCheck(cxxOperatorCallExpr->getType())
+ .ClassOrStruct("basic_string_view")
+ .StdNamespace())
+return true;
+auto expr = 
IgnoreImplicitAndConversionOperator(cxxOperatorCallExpr->getArg(1));
+auto tc = loplugin::TypeCheck(expr->getType());
+if (!tc.Class("OUString").Namespace("rtl").GlobalNamespace()
+&& !tc.Class("OString").Namespace("rtl").GlobalNamespace())
+return true;
+if (!isa(expr))
+return true;
+report(DiagnosticsEngine::Warning, "view pointing into temporary i.e. 
dangling",
+   cxxOperatorCallExpr->getExprLoc())
+<< cxxOperatorCallExpr->getSourceRange();
+return true;
+}
+
+bool StringViewDangle::VisitVarDecl(VarDecl const* varDecl)
+{
+if (ignoreLocation(varDecl))
+return true;
+if 
(!loplugin::TypeCheck(varDecl->getType()).ClassOrStruct("basic_string_view").StdNamespace())
+return true;
+if (!varDecl->hasInit())
+return true;
+auto expr = IgnoreImplicitAndConversionOperator(varDecl->getInit());
+auto tc = loplugin::TypeCheck(expr->getType());
+if (!tc.Class("OUString").Namespace("rtl").GlobalNamespace()
+&& !tc.Class("OString").Namespace("rtl").GlobalNamespace())
+return true;
+if (!isa(expr))
+return true;
+report(DiagnosticsEngine::Warning, "view pointing into temporary i.e. 
dangling",
+   varDecl->getLocation())
+<< varDecl->getSourceRange();
+return true;
+}
+
+loplugin::Plugin::Registration 
stringviewdangle("stringviewdangle");
+}
+
+#endif // LO_CLANG_SHARED_PLUGINS
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/compilerplugins/clang/test/stringviewdangle.cxx 
b/compilerplugins/clang/test/stringviewdangle.cxx
new file mode 100644
index ..0a8d2aa54b44
--- /dev/null
+++ 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2022-03-15 Thread Stephan Bergmann (via logerrit)
 compilerplugins/clang/test/trivialdestructor.cxx |   28 +++
 compilerplugins/clang/trivialdestructor.cxx  |   15 
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 3 files changed, 39 insertions(+), 5 deletions(-)

New commits:
commit c3346dc5731ecadb4762b939b76056eaed193341
Author: Stephan Bergmann 
AuthorDate: Mon Mar 14 21:33:31 2022 +0100
Commit: Stephan Bergmann 
CommitDate: Tue Mar 15 13:40:00 2022 +0100

loplugin:trivialdestructor: Only warn about definitions

Change-Id: I666e72a5c95b48cd5bc0cb775de3ec6a6c82fe39
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131574
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/test/trivialdestructor.cxx 
b/compilerplugins/clang/test/trivialdestructor.cxx
new file mode 100644
index ..16168cb5f927
--- /dev/null
+++ b/compilerplugins/clang/test/trivialdestructor.cxx
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+struct S1
+{
+// expected-note@+1 {{previous declaration is here 
[loplugin:trivialdestructor]}}
+~S1();
+};
+
+// expected-error@+1 {{no need for explicit destructor decl 
[loplugin:trivialdestructor]}}
+S1::~S1() {}
+
+struct S2
+{
+// expected-note@+1 {{previous declaration is here 
[loplugin:trivialdestructor]}}
+~S2();
+};
+
+// expected-error@+1 {{no need for explicit destructor decl 
[loplugin:trivialdestructor]}}
+S2::~S2() = default;
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/compilerplugins/clang/trivialdestructor.cxx 
b/compilerplugins/clang/trivialdestructor.cxx
index 208e4931a152..7ec54045dea7 100644
--- a/compilerplugins/clang/trivialdestructor.cxx
+++ b/compilerplugins/clang/trivialdestructor.cxx
@@ -45,6 +45,8 @@ bool 
TrivialDestructor::VisitCXXDestructorDecl(CXXDestructorDecl const* destruct
 {
 if (ignoreLocation(destructorDecl))
 return true;
+if (!destructorDecl->isThisDeclarationADefinition())
+return true;
 if (!destructorDecl->hasTrivialBody())
 return true;
 if (destructorDecl->isVirtual())
@@ -62,12 +64,15 @@ bool 
TrivialDestructor::VisitCXXDestructorDecl(CXXDestructorDecl const* destruct
 report(DiagnosticsEngine::Warning, "no need for explicit destructor decl",
destructorDecl->getLocation())
 << destructorDecl->getSourceRange();
-if (destructorDecl->getCanonicalDecl() != destructorDecl)
+for (FunctionDecl const* d2 = destructorDecl;;)
 {
-destructorDecl = destructorDecl->getCanonicalDecl();
-report(DiagnosticsEngine::Warning, "no need for explicit destructor 
decl",
-   destructorDecl->getLocation())
-<< destructorDecl->getSourceRange();
+d2 = d2->getPreviousDecl();
+if (d2 == nullptr)
+{
+break;
+}
+report(DiagnosticsEngine::Note, "previous declaration is here", 
d2->getLocation())
+<< d2->getSourceRange();
 }
 return true;
 }
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 66b0579dd69b..b95771b75dff 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -94,6 +94,7 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/stringstatic \
 compilerplugins/clang/test/stringview \
 compilerplugins/clang/test/stringviewparam \
+compilerplugins/clang/test/trivialdestructor \
 compilerplugins/clang/test/typedefparam \
 compilerplugins/clang/test/typeidcomparison \
 compilerplugins/clang/test/unnecessarycatchthrow \


[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk sw/inc sw/source

2022-02-12 Thread Stephan Bergmann (via logerrit)
 compilerplugins/clang/test/typeidcomparison.cxx |   41 ++
 compilerplugins/clang/typeidcomparison.cxx  |   90 
 solenv/CompilerTest_compilerplugins_clang.mk|1 
 sw/inc/istype.hxx   |   21 +
 sw/source/core/access/accmap.cxx|3 
 sw/source/core/doc/doclay.cxx   |3 
 sw/source/uibase/app/docsh2.cxx |7 +
 7 files changed, 161 insertions(+), 5 deletions(-)

New commits:
commit d2ba5d98ec67e684c819ef80421eb496723a8d06
Author: Stephan Bergmann 
AuthorDate: Sat Feb 12 17:10:43 2022 +0100
Commit: Stephan Bergmann 
CommitDate: Sat Feb 12 19:37:43 2022 +0100

Fix some tautological std::type_info (in-)equality comparisons

...which could never succeed.

I became aware of this when Clang 15 trunk -std=c++2b, implementing
 
"Making
std::type_info::operator== constexpr", pointed at two of the broken 
comparisons
with

> sw/source/uibase/app/docsh2.cxx:478:25: error: code will never be 
executed [-Werror,-Wunreachable-code]
> pTmpFrame->GetFrame().Appear();
> ^
> sw/source/uibase/app/docsh2.cxx:475:33: error: code will never be 
executed [-Werror,-Wunreachable-code]
> bOnly = false;
> ^

(It didn't emit warnings pointing at any of the other broken comparisons,
though.)

All of these broken comparisons were regressions introduced with
89d39bc100aabf5dccbe77c0b5c0c85736e85b39 "tdf#94559: 4th step to remove
rtti.hxx", replacing uses of the IS_TYPE macro (from include/tools/rtti.hxx,
meanwhile removed with d64e535fe9a00b671cf1be3eb5632c0d5f4b8bea "Remove 
unused
rtti.hxx").

I now added loplugin:typeidcomparison to also find the other broken 
comparisons
introduced by that commit.  (The remaining cases where that commit replaced 
uses
of TYPE_INFO with typeid comparisons were correct and/or have meanwhile been
replaced with code not using typeid, see
553ee72041d6f66e26156eb1ad0d9e3c13457f7a "simplify some use of typeid" and
d656da9bc4f2df0bb99c65a288847e3fdd43a37c "~SwModify: do not silently 
tolerate
clients registered past death".)

The original IS_TYPE macro made sure not to dereference null pointers,

> #define IS_TYPE(T,pObj) \
> ( pObj && (pObj)->Type() == TYPE(T) )

I don't know if any of the pointers now dereferenced in those typeid 
expressions
can legitimately be null.  But to be on the safe side, I replicated that 
check
in the newly introduced isType (sw/inc/istype.hxx).

(It is interesting to note that none of the static analysis that we 
routinely
employ seems to have noticed these broken comparisons.)

Change-Id: I65baffdd27bac1abf744283ff98c2dc864fa63b4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129865
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/test/typeidcomparison.cxx 
b/compilerplugins/clang/test/typeidcomparison.cxx
new file mode 100644
index ..31ab749a2496
--- /dev/null
+++ b/compilerplugins/clang/test/typeidcomparison.cxx
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+
+struct Base
+{
+virtual ~Base();
+};
+
+struct Derived : Base
+{
+};
+
+void good(Base* p)
+{
+(void)(typeid(*p) == typeid(Derived));
+(void)(typeid(Derived) == typeid(*p));
+(void)(typeid(*p) != typeid(Derived));
+(void)(typeid(Derived) != typeid(*p));
+}
+
+void bad(Base* p)
+{
+// expected-error@+1 {{comparison of type info of mixed pointer and 
non-pointer types 'Base *' and 'Derived' can never succeed 
[loplugin:typeidcomparison]}}
+(void)(typeid(p) == typeid(Derived));
+// expected-error@+1 {{comparison of type info of mixed pointer and 
non-pointer types 'Derived' and 'Base *' can never succeed 
[loplugin:typeidcomparison]}}
+(void)(typeid(Derived) == typeid(p));
+// expected-error@+1 {{comparison of type info of mixed pointer and 
non-pointer types 'Base *' and 'Derived' can never succeed 
[loplugin:typeidcomparison]}}
+(void)(typeid(p) != typeid(Derived));
+// expected-error@+1 {{comparison of type info of mixed pointer and 
non-pointer types 'Derived' and 'Base *' can never succeed 
[loplugin:typeidcomparison]}}
+(void)(typeid(Derived) != typeid(p));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2021-07-14 Thread Noel Grandin (via logerrit)
 compilerplugins/clang/test/weakobject.cxx|   31 
 compilerplugins/clang/weakobject.cxx |  189 +++
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 3 files changed, 85 insertions(+), 136 deletions(-)

New commits:
commit 81697ca63d47decf165420c4373b2b53d7eab385
Author: Noel Grandin 
AuthorDate: Tue Jul 13 15:50:35 2021 +0200
Commit: Noel Grandin 
CommitDate: Wed Jul 14 14:39:39 2021 +0200

new loplugin:weakobject

find classes with more than one copy of OWeakObject in their inheritance
hierarchy, which is dodgy

Change-Id: I4e31bd6db03d25d934b736bd6a9c1b665f976ee2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118855
Tested-by: Jenkins
Reviewed-by: Noel Grandin 

diff --git a/compilerplugins/clang/test/weakobject.cxx 
b/compilerplugins/clang/test/weakobject.cxx
new file mode 100644
index ..7c7da55664d2
--- /dev/null
+++ b/compilerplugins/clang/test/weakobject.cxx
@@ -0,0 +1,31 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "config_clang.h"
+
+namespace cppu
+{
+class OWeakObject
+{
+};
+}
+
+class Foo1 : public cppu::OWeakObject
+{
+};
+class Foo2 : public cppu::OWeakObject
+{
+};
+
+// expected-error@+1 {{more than one copy of cppu::OWeakObject inherited 
[loplugin:weakobject]}}
+class Foo3 : public Foo1, public Foo2
+{
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/compilerplugins/clang/weakobject.cxx 
b/compilerplugins/clang/weakobject.cxx
index 055110ef9331..4801953cc44a 100644
--- a/compilerplugins/clang/weakobject.cxx
+++ b/compilerplugins/clang/weakobject.cxx
@@ -2,163 +2,80 @@
 /*
  * This file is part of the LibreOffice project.
  *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Based on LLVM/Clang.
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
  */
-
 #ifndef LO_CLANG_SHARED_PLUGINS
 
-#include "check.hxx"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 #include "plugin.hxx"
+#include "check.hxx"
 
-/* OWeakObject::release() disposes weak references.  If that isn't done
- * because a sub-class improperly overrides release() then
- * OWeakConnectionPoint::m_pObject continues to point to the deleted object
- * and that could result in use-after-free.
- */
-
-namespace {
+/*
+Check for places where we end up with more than one copy of cppu::OweakObject 
in a class, which
+really should not happen - we should be using one of the 
AggImplInheritanceHelper classes then
+to inherit.
+*/
 
-class WeakObject
-: public loplugin::FilteringPlugin
+namespace
+{
+class WeakObject : public loplugin::FilteringPlugin
 {
-
 public:
-explicit WeakObject(loplugin::InstantiationData const& rData): 
FilteringPlugin(rData)
-{}
-
-virtual bool preRun() override {
-return compiler.getLangOpts().CPlusPlus; // no OWeakObject in C
-}
-void run() override {
-if( preRun()) {
-TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
-}
+explicit WeakObject(loplugin::InstantiationData const& data)
+: FilteringPlugin(data)
+{
 }
 
-bool isDerivedFromOWeakObject(CXXMethodDecl const*const pMethodDecl)
+virtual bool preRun() override
 {
-QualType const pClass(pMethodDecl->getParent()->getTypeForDecl(), 0);
-if (loplugin::TypeCheck(pClass).Class("OWeakObject").Namespace("cppu"))
-{
-return true;
-}
-// hopefully it's faster to recurse overridden methods than the
-// thicket of WeakImplHelper32 but that is purely speculation
-for (auto it = pMethodDecl->begin_overridden_methods();
- it != pMethodDecl->end_overridden_methods(); ++it)
-{
-if (isDerivedFromOWeakObject(*it))
-{
-return true;
-}
-}
-return false;
+return true;
 }
 
-bool VisitCXXMethodDecl(CXXMethodDecl const*const pMethodDecl)
+virtual void run() override
 {
-if (ignoreLocation(pMethodDecl)) {
-return true;
-}
-if (!pMethodDecl->isThisDeclarationADefinition()
-|| pMethodDecl->isLateTemplateParsed())
-{
-return true;
-}
-if (!pMethodDecl->isInstance()) {
-return true;
-}
-// this is too "simple", if a NamedDecl class has a getName() member 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2021-06-22 Thread Stephan Bergmann (via logerrit)
 compilerplugins/clang/test/overridevirtual.cxx |   44 +
 solenv/CompilerTest_compilerplugins_clang.mk   |1 
 2 files changed, 45 insertions(+)

New commits:
commit fb3027544fd6ff6bc089d1e24d4f8dd2a0ee1fce
Author: Stephan Bergmann 
AuthorDate: Tue Jun 22 15:22:51 2021 +0200
Commit: Stephan Bergmann 
CommitDate: Tue Jun 22 16:39:33 2021 +0200

Clarify no loplugin:overridevirtual with templated base class

Change-Id: I4128b43f2a928fa5465991cc92b2d62e54e2cfec
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117662
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/test/overridevirtual.cxx 
b/compilerplugins/clang/test/overridevirtual.cxx
new file mode 100644
index ..0f11d86b105d
--- /dev/null
+++ b/compilerplugins/clang/test/overridevirtual.cxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+struct S1
+{
+// expected-note@+1 {{overridden declaration is here 
[loplugin:overridevirtual]}}
+virtual ~S1();
+};
+
+struct S2 : S1
+{
+// expected-error@+1 {{overriding virtual function declaration not marked 
'override' [loplugin:overridevirtual]}}
+~S2();
+};
+
+template  struct T1
+{
+virtual ~T1();
+};
+
+template  struct T2 : T1
+{
+~T2();
+};
+
+template  struct U1
+{
+// expected-note@+1 {{overridden declaration is here 
[loplugin:overridevirtual]}}
+virtual ~U1();
+};
+
+template  struct U2 : U1
+{
+// expected-error@+1 {{overriding virtual function declaration not marked 
'override' [loplugin:overridevirtual]}}
+~U2();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 3a05e8fb2bb3..d3131efd0e7e 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -56,6 +56,7 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/oslendian-1 \
 compilerplugins/clang/test/oslendian-2 \
 compilerplugins/clang/test/oslendian-3 \
+compilerplugins/clang/test/overridevirtual \
 compilerplugins/clang/test/passparamsbyref \
 compilerplugins/clang/test/passstuffbyref \
 compilerplugins/clang/test/pointerbool \
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2021-05-03 Thread Stephan Bergmann (via logerrit)
 compilerplugins/clang/noexcept.cxx   |   82 +++
 compilerplugins/clang/test/noexcept.cxx  |   16 +
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 3 files changed, 99 insertions(+)

New commits:
commit 0d18b90b75c074c0cca4d12a6468f2397909b886
Author: Stephan Bergmann 
AuthorDate: Thu Apr 29 12:00:25 2021 +0200
Commit: Stephan Bergmann 
CommitDate: Mon May 3 11:23:34 2021 +0200

throw() -> noexcept, part 3/3: New loplugin:noexcept

Change-Id: I3ce3fab3e8047be14e003f1f3096b4e2745534e9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115026
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/noexcept.cxx 
b/compilerplugins/clang/noexcept.cxx
new file mode 100644
index ..ae0bfdf95207
--- /dev/null
+++ b/compilerplugins/clang/noexcept.cxx
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "plugin.hxx"
+
+namespace
+{
+class Noexcept : public loplugin::FilteringRewritePlugin
+{
+public:
+explicit Noexcept(loplugin::InstantiationData const& data)
+: FilteringRewritePlugin(data)
+{
+}
+
+void run() override
+{
+// Don't execute for < C++11, so we don't accidentally rewrite the 
legacy definitions of
+// SAL_THROW_EXTERN_C and SAL_NOEXCEPT in include/sal/types.h e.g. 
when building
+// CppunitTest_odk_checkapi which explicitly uses gb_CXX03FLAGS:
+if (compiler.getLangOpts().CPlusPlus11)
+{
+TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+}
+}
+
+bool VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc tloc)
+{
+if (ignoreLocation(tloc))
+{
+return true;
+}
+if (tloc.getTypePtr()->getExceptionSpecType() != EST_DynamicNone)
+{
+return true;
+}
+auto const r = tloc.getExceptionSpecRange();
+auto const repl = isInUnoIncludeFile(r.getBegin()) ? "SAL_NOEXCEPT" : 
"noexcept";
+if (rewriter != nullptr)
+{
+auto r2 = r;
+auto l1 = r.getBegin();
+while (compiler.getSourceManager().isMacroArgExpansion(l1))
+{
+l1 = 
compiler.getSourceManager().getImmediateMacroCallerLoc(l1);
+}
+if (compiler.getSourceManager().isMacroBodyExpansion(l1))
+{
+auto l2 = r.getEnd();
+while (compiler.getSourceManager().isMacroArgExpansion(l2))
+{
+l2 = 
compiler.getSourceManager().getImmediateMacroCallerLoc(l2);
+}
+if (compiler.getSourceManager().isMacroBodyExpansion(l2))
+{
+//TODO: check l1, l2 are in same macro body expansion
+r2 = { compiler.getSourceManager().getSpellingLoc(l1),
+   compiler.getSourceManager().getSpellingLoc(l2) };
+}
+}
+if (replaceText(r2, repl))
+{
+return true;
+}
+}
+report(DiagnosticsEngine::Warning,
+   "Replace legacy dynamic 'throw ()' exception specification with 
'%0'", r.getBegin())
+<< repl << r;
+return true;
+}
+};
+
+loplugin::Plugin::Registration X("noexcept", true);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/compilerplugins/clang/test/noexcept.cxx 
b/compilerplugins/clang/test/noexcept.cxx
new file mode 100644
index ..f46a3d87f2b7
--- /dev/null
+++ b/compilerplugins/clang/test/noexcept.cxx
@@ -0,0 +1,16 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+// expected-error@+1 {{Replace legacy dynamic 'throw ()' exception 
specification with 'noexcept' [loplugin:noexcept]}}
+void f() throw();
+
+// expected-error@+1 {{Replace legacy dynamic 'throw ()' exception 
specification with 'noexcept' [loplugin:noexcept]}}
+using F = void() throw();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 6ac27d98d4cf..3a05e8fb2bb3 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2020-11-06 Thread Noel (via logerrit)
 solenv/CompilerTest_compilerplugins_clang.mk |1 -
 1 file changed, 1 deletion(-)

New commits:
commit 78dac9f19460b92da3e56214cd5833c7407ab0f2
Author: Noel 
AuthorDate: Fri Nov 6 12:24:37 2020 +0200
Commit: Noel Grandin 
CommitDate: Fri Nov 6 14:35:36 2020 +0100

retire the stringbuffer loplugin

the best code is now the opposite of what this plugin recommends

Change-Id: I88c04200c73a9bae07ef8fcf6ba5f1d9e4927709
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105394
Tested-by: Jenkins
Reviewed-by: Noel Grandin 

diff --git a/compilerplugins/clang/stringbuffer.cxx 
b/compilerplugins/clang/store/stringbuffer.cxx
similarity index 100%
rename from compilerplugins/clang/stringbuffer.cxx
rename to compilerplugins/clang/store/stringbuffer.cxx
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 46d090781d58..a8cc4ad731af 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -82,7 +82,6 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/staticvar \
 compilerplugins/clang/test/stdfunction \
 compilerplugins/clang/test/stringadd \
-compilerplugins/clang/test/stringbuffer \
 compilerplugins/clang/test/stringconcatauto \
 compilerplugins/clang/test/stringconcatliterals \
 compilerplugins/clang/test/stringconstant \
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2020-06-26 Thread Stephan Bergmann (via logerrit)
 compilerplugins/clang/elidestringvar.cxx  |   18 +++-
 compilerplugins/clang/test/elidestringvar.cxx |   39 ++
 solenv/CompilerTest_compilerplugins_clang.mk  |1 
 3 files changed, 57 insertions(+), 1 deletion(-)

New commits:
commit 311fe58df8cbdc6550f9b6ed89bd7f14d61c50a9
Author: Stephan Bergmann 
AuthorDate: Fri Jun 26 14:53:24 2020 +0200
Commit: Stephan Bergmann 
CommitDate: Fri Jun 26 17:31:53 2020 +0200

Improve loplugin:elidestringvar

...by addressing the follow-up TODO mentioned in the commit message of
7a3736f908c0ae207567603c61ce0f617339bac0 "New loplugin:elidestringvar"
(extending it not only to uses with a constant sal_Unicode, but also to uses
with OUStringLiteral).

(All necessary changes have been made in preceding "Upcoming improved
loplugin:elidestringvar" commits.)

Change-Id: Ibef9c4a1dad52124dfd039dd936cf7e3ba3f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97226
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/elidestringvar.cxx 
b/compilerplugins/clang/elidestringvar.cxx
index 4ca28d0d881d..d091f8175783 100644
--- a/compilerplugins/clang/elidestringvar.cxx
+++ b/compilerplugins/clang/elidestringvar.cxx
@@ -67,7 +67,7 @@ public:
 continue;
 }
 report(DiagnosticsEngine::Warning,
-   "replace single use of literal OUString variable with the 
literal",
+   "replace single use of literal OUString variable with a 
literal",
(*var.second.singleUse)->getExprLoc())
 << (*var.second.singleUse)->getSourceRange();
 report(DiagnosticsEngine::Note, "literal OUString variable defined 
here",
@@ -121,6 +121,22 @@ public:
 {
 case 0:
 break;
+case 1:
+{
+auto const e2 = e1->getArg(0);
+if (loplugin::TypeCheck(e2->getType())
+.Struct("OUStringLiteral")
+.Namespace("rtl")
+.GlobalNamespace())
+{
+break;
+}
+if (e2->isIntegerConstantExpr(compiler.getASTContext()))
+{
+break;
+}
+return true;
+}
 case 2:
 {
 auto const e2 = e1->getArg(1);
diff --git a/compilerplugins/clang/test/elidestringvar.cxx 
b/compilerplugins/clang/test/elidestringvar.cxx
new file mode 100644
index ..e7a5f40a8eae
--- /dev/null
+++ b/compilerplugins/clang/test/elidestringvar.cxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "sal/config.h"
+
+#include "rtl/ustring.hxx"
+
+OUString f(sal_Unicode c, int n)
+{
+OUString s1(c);
+// expected-note@+1 {{literal OUString variable defined here 
[loplugin:elidestringvar]}}
+OUString s2('a');
+// expected-note@+1 {{literal OUString variable defined here 
[loplugin:elidestringvar]}}
+OUString s3(u'a');
+// expected-note@+1 {{literal OUString variable defined here 
[loplugin:elidestringvar]}}
+OUString s4 = OUStringLiteral("a");
+switch (n)
+{
+case 1:
+return s1;
+case 2:
+// expected-error@+1 {{replace single use of literal OUString 
variable with a literal [loplugin:elidestringvar]}}
+return s2;
+case 3:
+// expected-error@+1 {{replace single use of literal OUString 
variable with a literal [loplugin:elidestringvar]}}
+return s3;
+default:
+// expected-error@+1 {{replace single use of literal OUString 
variable with a literal [loplugin:elidestringvar]}}
+return s4;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 59a00d31038d..3d457af768df 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -31,6 +31,7 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/dbgunhandledexception \
 compilerplugins/clang/test/dodgyswitch \
 compilerplugins/clang/test/doubleconvert \
+compilerplugins/clang/test/elidestringvar \
 compilerplugins/clang/test/emptyif \
 compilerplugins/clang/test/expressionalwayszero \
 compilerplugins/clang/test/external \

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2019-12-05 Thread Stephan Bergmann (via logerrit)
 compilerplugins/clang/fakebool.cxx   |  114 ---
 compilerplugins/clang/plugin.hxx |9 
 compilerplugins/clang/pluginhandler.cxx  |  106 ++
 compilerplugins/clang/pluginhandler.hxx  |   11 
 compilerplugins/clang/test/unusedmember.cxx  |  158 ++
 compilerplugins/clang/unusedmember.cxx   |  416 +++
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 7 files changed, 704 insertions(+), 111 deletions(-)

New commits:
commit 6a10149c5fef13721e3f83727a828556f8e1ec9a
Author: Stephan Bergmann 
AuthorDate: Wed Dec 4 14:32:15 2019 +0100
Commit: Stephan Bergmann 
CommitDate: Thu Dec 5 13:30:36 2019 +0100

New loplugin:unusedmember

* See comment at head of compilerplugins/clang/unusedmember.cxx for 
description.

* Moved isAllRelevantCodeDefined from loplugin:fakebool to PluginHandler for
  reuse.  (Made it a member function so that it can reuse its two
  RecordCompleteMap instances across different loplugins.  Probably safer
  lifecycle-wise to have them as PluginHandler members than to have them as
  static local variables in function isAllRelevantCodeDefined.)

* Need Plugin::ignoreLocation overload for TypeLoc now, thanks to
  UnusedMember::VisitElaboratedTypeLoc.

* UETT_PreferredAlignOf was split off UETT_AlignOf with  
"PR26547:
  alignof should return ABI alignment, not preferred alignment".

* RecursiveASTVisitor::TraverseAlignedAttr traverses into the attribute's
  argument only since  "Do not look through pack
  expansions when looking for unexpanded parameter packs".

Change-Id: Ic2702b03d4567fa253766de7920f3c524a69
Reviewed-on: https://gerrit.libreoffice.org/84416
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/fakebool.cxx 
b/compilerplugins/clang/fakebool.cxx
index 62fbc936e897..f50116b8ee88 100644
--- a/compilerplugins/clang/fakebool.cxx
+++ b/compilerplugins/clang/fakebool.cxx
@@ -23,114 +23,6 @@
 
 namespace {
 
-// BEGIN code copied from LLVM's clang/lib/Sema/Sema.cpp
-
-typedef llvm::DenseMap RecordCompleteMap;
-
-/// Returns true, if all methods and nested classes of the given
-/// CXXRecordDecl are defined in this translation unit.
-///
-/// Should only be called from ActOnEndOfTranslationUnit so that all
-/// definitions are actually read.
-static bool MethodsAndNestedClassesComplete(const CXXRecordDecl *RD,
-RecordCompleteMap ) {
-  RecordCompleteMap::iterator Cache = MNCComplete.find(RD);
-  if (Cache != MNCComplete.end())
-return Cache->second;
-  if (!RD->isCompleteDefinition())
-return false;
-  bool Complete = true;
-  for (DeclContext::decl_iterator I = RD->decls_begin(),
-  E = RD->decls_end();
-   I != E && Complete; ++I) {
-if (const CXXMethodDecl *M = dyn_cast(*I))
-  Complete = M->isDefined() || M->isDefaulted() ||
- (M->isPure() && !isa(M));
-else if (const FunctionTemplateDecl *F = 
dyn_cast(*I))
-  // If the template function is marked as late template parsed at this
-  // point, it has not been instantiated and therefore we have not
-  // performed semantic analysis on it yet, so we cannot know if the type
-  // can be considered complete.
-  Complete = !F->getTemplatedDecl()->isLateTemplateParsed() &&
-  F->getTemplatedDecl()->isDefined();
-else if (const CXXRecordDecl *R = dyn_cast(*I)) {
-  if (R->isInjectedClassName())
-continue;
-  if (R->hasDefinition())
-Complete = MethodsAndNestedClassesComplete(R->getDefinition(),
-   MNCComplete);
-  else
-Complete = false;
-}
-  }
-  MNCComplete[RD] = Complete;
-  return Complete;
-}
-
-/// Returns true, if the given CXXRecordDecl is fully defined in this
-/// translation unit, i.e. all methods are defined or pure virtual and all
-/// friends, friend functions and nested classes are fully defined in this
-/// translation unit.
-///
-/// Should only be called from ActOnEndOfTranslationUnit so that all
-/// definitions are actually read.
-static bool IsRecordFullyDefined(const CXXRecordDecl *RD,
- RecordCompleteMap ,
- RecordCompleteMap ) {
-  RecordCompleteMap::iterator Cache = RecordsComplete.find(RD);
-  if (Cache != RecordsComplete.end())
-return Cache->second;
-  bool Complete = MethodsAndNestedClassesComplete(RD, MNCComplete);
-  for (CXXRecordDecl::friend_iterator I = RD->friend_begin(),
-  E = RD->friend_end();
-   I != E && Complete; ++I) {
-// Check if friend classes and 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2019-11-25 Thread Stephan Bergmann (via logerrit)
 compilerplugins/clang/implicitboolconversion.cxx  |   13 
 compilerplugins/clang/test/implicitboolconversion.cxx |   28 ++
 solenv/CompilerTest_compilerplugins_clang.mk  |1 
 3 files changed, 42 insertions(+)

New commits:
commit 28f8a26fa12c2f78696864189356db46c1cae30c
Author: Stephan Bergmann 
AuthorDate: Mon Nov 25 11:17:19 2019 +0100
Commit: Stephan Bergmann 
CommitDate: Tue Nov 26 07:12:15 2019 +0100

loplugin:implicitboolconversion: Filter out bool -> std::atomic

...as used since patch set 8 of 
"WIP: tdf#120006 New Document converter"

Change-Id: I79c2237a2e5839162272c0d49bdb4d87c9e35102
Reviewed-on: https://gerrit.libreoffice.org/83655
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/implicitboolconversion.cxx 
b/compilerplugins/clang/implicitboolconversion.cxx
index e16b15517bc9..3adbf7197f47 100644
--- a/compilerplugins/clang/implicitboolconversion.cxx
+++ b/compilerplugins/clang/implicitboolconversion.cxx
@@ -1020,6 +1020,19 @@ void ImplicitBoolConversion::checkCXXConstructExpr(
 
 void ImplicitBoolConversion::reportWarning(ImplicitCastExpr const * expr) {
 if (compiler.getLangOpts().CPlusPlus) {
+if (expr->getCastKind() == CK_ConstructorConversion) {
+auto const t1 = expr->getType();
+if (auto const t2 = t1->getAs()) {
+assert(t2->getNumArgs() >= 1);
+auto const a = t2->getArg(0);
+if (a.getKind() == TemplateArgument::Type && 
a.getAsType()->isBooleanType()
+&& (loplugin::TypeCheck(t1).TemplateSpecializationClass()
+.ClassOrStruct("atomic").StdNamespace()))
+{
+return;
+}
+}
+}
 report(
 DiagnosticsEngine::Warning,
 "implicit conversion (%0) from %1 to %2", 
compat::getBeginLoc(expr))
diff --git a/compilerplugins/clang/test/implicitboolconversion.cxx 
b/compilerplugins/clang/test/implicitboolconversion.cxx
new file mode 100644
index ..c438822d3b88
--- /dev/null
+++ b/compilerplugins/clang/test/implicitboolconversion.cxx
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+
+#include 
+
+void f()
+{
+// expected-error@+1 {{implicit conversion (IntegralCast) from 'bool' to 
'int' [loplugin:implicitboolconversion]}}
+int i = false;
+(void)i;
+std::atomic b = false;
+(void)b;
+//TODO: Emit only one diagnostic here:
+// expected-error@+2 {{implicit conversion (ConstructorConversion) from 
'bool' to 'std::atomic' [loplugin:implicitboolconversion]}}
+// expected-error-re@+1 {{implicit conversion (IntegralCast) from 'bool' 
to {{.+}} [loplugin:implicitboolconversion]}}
+std::atomic a = false;
+(void)a;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 318bf8c69d0a..3c9969bd628f 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -41,6 +41,7 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/flatten \
 compilerplugins/clang/test/fragiledestructor \
 compilerplugins/clang/test/getstr \
+compilerplugins/clang/test/implicitboolconversion \
 compilerplugins/clang/test/indentation \
 compilerplugins/clang/test/intvsfloat \
 compilerplugins/clang/test/logexceptionnicely \
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2019-11-16 Thread Stephan Bergmann (via logerrit)
 compilerplugins/clang/readability-redundant-pp.cxx   |8 
 compilerplugins/clang/test/redundantpreprocessor.cxx |   15 +++
 solenv/CompilerTest_compilerplugins_clang.mk |1 +
 3 files changed, 20 insertions(+), 4 deletions(-)

New commits:
commit 24b69e95c699ca595775f657244498a0cebe1faf
Author: Stephan Bergmann 
AuthorDate: Sat Nov 16 15:42:32 2019 +0100
Commit: Stephan Bergmann 
CommitDate: Sat Nov 16 16:55:36 2019 +0100

Improve loplugin:redundantpreprocessor performance a bit

...and add a minimal test for it

Change-Id: Ia6c61e41a7e60fd01c639e893c34bd9d215c1513
Reviewed-on: https://gerrit.libreoffice.org/82983
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/readability-redundant-pp.cxx 
b/compilerplugins/clang/readability-redundant-pp.cxx
index e1c284b99c63..dcfd70247ff8 100644
--- a/compilerplugins/clang/readability-redundant-pp.cxx
+++ b/compilerplugins/clang/readability-redundant-pp.cxx
@@ -69,9 +69,9 @@ void RedundantPreprocessor::Ifdef(clang::SourceLocation aLoc, 
const clang::Token
 if (ignoreLocation(aLoc))
 return;
 
+std::string aMacroName = m_rPP.getSpelling(rMacroNameTok);
 if (m_rPP.getSourceManager().isInMainFile(aLoc))
 {
-std::string aMacroName = m_rPP.getSpelling(rMacroNameTok);
 for (const auto& rEntry : m_aDefStack)
 {
 if (rEntry.m_aMacroName == aMacroName)
@@ -84,7 +84,7 @@ void RedundantPreprocessor::Ifdef(clang::SourceLocation aLoc, 
const clang::Token
 
 Entry aEntry;
 aEntry.m_aLoc = aLoc;
-aEntry.m_aMacroName = m_rPP.getSpelling(rMacroNameTok);
+aEntry.m_aMacroName = aMacroName;
 m_aDefStack.push_back(aEntry);
 }
 
@@ -94,9 +94,9 @@ void RedundantPreprocessor::Ifndef(clang::SourceLocation 
aLoc, const clang::Toke
 if (ignoreLocation(aLoc))
 return;
 
+std::string aMacroName = m_rPP.getSpelling(rMacroNameTok);
 if (m_rPP.getSourceManager().isInMainFile(aLoc))
 {
-std::string aMacroName = m_rPP.getSpelling(rMacroNameTok);
 for (const auto& rEntry : m_aNotDefStack)
 {
 if (rEntry.m_aMacroName == aMacroName)
@@ -109,7 +109,7 @@ void RedundantPreprocessor::Ifndef(clang::SourceLocation 
aLoc, const clang::Toke
 
 Entry aEntry;
 aEntry.m_aLoc = aLoc;
-aEntry.m_aMacroName = m_rPP.getSpelling(rMacroNameTok);
+aEntry.m_aMacroName = aMacroName;
 m_aNotDefStack.push_back(aEntry);
 }
 
diff --git a/compilerplugins/clang/test/redundantpreprocessor.cxx 
b/compilerplugins/clang/test/redundantpreprocessor.cxx
new file mode 100644
index ..18ab10559f67
--- /dev/null
+++ b/compilerplugins/clang/test/redundantpreprocessor.cxx
@@ -0,0 +1,15 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifdef __clang__ // expected-note {{previous ifdef 
[loplugin:redundantpreprocessor]}}
+#ifdef __clang__ // expected-error {{nested ifdef 
[loplugin:redundantpreprocessor]}}
+#endif
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 226d0686dd52..e429d1bc00fa 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -59,6 +59,7 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/redundantfcast \
 compilerplugins/clang/test/redundantinline \
 compilerplugins/clang/test/redundantpointerops \
+compilerplugins/clang/test/redundantpreprocessor \
 compilerplugins/clang/test/refcounting \
 compilerplugins/clang/test/referencecasting \
 compilerplugins/clang/test/returnconstval \
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2019-11-12 Thread Stephan Bergmann (via logerrit)
 compilerplugins/clang/test/external.cxx  |   23 +++
 solenv/CompilerTest_compilerplugins_clang.mk |1 +
 2 files changed, 24 insertions(+)

New commits:
commit bc6e282bc2a43093c7a7b4d517c9e809c008298e
Author: Stephan Bergmann 
AuthorDate: Tue Nov 12 11:03:36 2019 +0100
Commit: Stephan Bergmann 
CommitDate: Tue Nov 12 13:04:28 2019 +0100

Clarify loplugin:external behavior for const(expr) vars

Change-Id: I4a649f9c9ed2015ed9b32a153060df9770b20403
Reviewed-on: https://gerrit.libreoffice.org/82493
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/test/external.cxx 
b/compilerplugins/clang/test/external.cxx
new file mode 100644
index ..f4f3d770f09d
--- /dev/null
+++ b/compilerplugins/clang/test/external.cxx
@@ -0,0 +1,23 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+// expected-error@+1 {{externally available entity 'n1' is not previously 
declared in an included file (if it is only used in this translation unit, make 
it static or put it in an unnamed namespace; otherwise, provide a declaration 
of it in an included file) [loplugin:external]}}
+int n1 = 0;
+
+int const n2 = 0; // no warning, internal linkage
+
+constexpr int n3 = 0; // no warning, internal linkage
+
+int main()
+{
+(void)n2;
+(void)n3;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 9f3c7310657e..1014d3f8c909 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -31,6 +31,7 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/dodgyswitch \
 compilerplugins/clang/test/doubleconvert \
 compilerplugins/clang/test/emptyif \
+compilerplugins/clang/test/external \
 compilerplugins/clang/test/externvar \
 compilerplugins/clang/test/expressionalwayszero \
 compilerplugins/clang/test/intvsfloat \
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk vbahelper/source

2019-10-02 Thread Noel Grandin (via logerrit)
 compilerplugins/clang/stringadd.cxx|  273 +
 compilerplugins/clang/test/stringadd.cxx   |  150 +++
 solenv/CompilerTest_compilerplugins_clang.mk   |1 
 vbahelper/source/vbahelper/vbacommandbarhelper.cxx |4 
 4 files changed, 425 insertions(+), 3 deletions(-)

New commits:
commit b3b8288f7f6c3cbb36edac2eddf0fff974c6d04a
Author: Noel Grandin 
AuthorDate: Fri Sep 27 21:41:42 2019 +0200
Commit: Noel Grandin 
CommitDate: Wed Oct 2 11:22:27 2019 +0200

new loplugin:stringadd

look for places where we can replace sequential additions to
OUString/OString with one concatentation (i.e. +) expression, which is
more efficient

Change-Id: I64d91328bf64828d8328b1cad9e90953c0a75663
Reviewed-on: https://gerrit.libreoffice.org/79406
Tested-by: Jenkins
Reviewed-by: Noel Grandin 

diff --git a/compilerplugins/clang/stringadd.cxx 
b/compilerplugins/clang/stringadd.cxx
new file mode 100644
index ..641000e28ecf
--- /dev/null
+++ b/compilerplugins/clang/stringadd.cxx
@@ -0,0 +1,273 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#ifndef LO_CLANG_SHARED_PLUGINS
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "plugin.hxx"
+#include "check.hxx"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/StmtVisitor.h"
+
+/**
+Look for repeated addition to OUString/OString.
+
+Eg.
+  OUString x = "xxx";
+  x += b;
+
+which can be simplified to
+x = "xxx" + b
+
+which is more efficient, because of the OUStringConcat magic.
+*/
+
+namespace
+{
+class StringAdd : public loplugin::FilteringPlugin
+{
+public:
+explicit StringAdd(loplugin::InstantiationData const& data)
+: FilteringPlugin(data)
+{
+}
+
+bool preRun() override
+{
+std::string fn(handler.getMainFileName());
+loplugin::normalizeDotDotInFilePath(fn);
+if (fn == SRCDIR "/sal/qa/rtl/oustring/rtl_OUString2.cxx"
+|| fn == SRCDIR "/sal/qa/rtl/strings/test_oustring_concat.cxx"
+|| fn == SRCDIR "/sal/qa/rtl/strings/test_ostring_concat.cxx"
+|| fn == SRCDIR "/sal/qa/OStringBuffer/rtl_OStringBuffer.cxx")
+return false;
+// there is an ifdef here, but my check is not working, not sure why
+if (fn == SRCDIR "/pyuno/source/module/pyuno_runtime.cxx")
+return false;
+// TODO the += depends on the result of the preceding assign, so can't 
merge
+if (fn == SRCDIR "/editeng/source/misc/svxacorr.cxx")
+return false;
+return true;
+}
+
+virtual void run() override
+{
+if (!preRun())
+return;
+TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+}
+
+bool VisitCompoundStmt(CompoundStmt const*);
+
+private:
+const VarDecl* findAssignOrAdd(Stmt const*);
+Expr const* ignore(Expr const*);
+void checkForCompoundAssign(Stmt const* stmt1, Stmt const* stmt2, VarDecl 
const* varDecl);
+std::string getSourceAsString(SourceLocation startLoc, SourceLocation 
endLoc);
+bool isSideEffectFree(Expr const*);
+};
+
+bool StringAdd::VisitCompoundStmt(CompoundStmt const* compoundStmt)
+{
+if (ignoreLocation(compoundStmt))
+return true;
+
+auto it = compoundStmt->body_begin();
+while (true)
+{
+if (it == compoundStmt->body_end())
+break;
+const VarDecl* foundVar = findAssignOrAdd(*it);
+// reference types have slightly weird behaviour
+if (foundVar && !foundVar->getType()->isReferenceType())
+{
+auto stmt1 = *it;
+++it;
+if (it == compoundStmt->body_end())
+break;
+checkForCompoundAssign(stmt1, *it, foundVar);
+continue;
+}
+else
+++it;
+}
+
+return true;
+}
+
+const VarDecl* StringAdd::findAssignOrAdd(Stmt const* stmt)
+{
+if (auto exprCleanup = dyn_cast(stmt))
+stmt = exprCleanup->getSubExpr();
+if (auto switchCase = dyn_cast(stmt))
+stmt = switchCase->getSubStmt();
+
+if (auto declStmt = dyn_cast(stmt))
+if (declStmt->isSingleDecl())
+if (auto varDeclLHS = 
dyn_cast_or_null(declStmt->getSingleDecl()))
+{
+auto tc = loplugin::TypeCheck(varDeclLHS->getType());
+if (!tc.Class("OUString").Namespace("rtl").GlobalNamespace()
+&& !tc.Class("OString").Namespace("rtl").GlobalNamespace())
+return nullptr;
+if (varDeclLHS->getStorageDuration() == SD_Static)
+

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2019-08-28 Thread Stephan Bergmann (via logerrit)
 compilerplugins/clang/check.cxx  |   37 +++--
 compilerplugins/clang/check.hxx  |   13 ++
 compilerplugins/clang/stdfunction.cxx|   48 +++
 compilerplugins/clang/test/stdfunction.cxx   |   56 +++
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 5 files changed, 142 insertions(+), 13 deletions(-)

New commits:
commit 5f3c2204eb7dbe82cc64bf0ade34ecfb4b9ffc05
Author: Stephan Bergmann 
AuthorDate: Wed Aug 28 11:17:20 2019 +0200
Commit: Stephan Bergmann 
CommitDate: Wed Aug 28 12:47:21 2019 +0200

New loplugin:stdfunction

...finding dubious additions to namespace std (concentrating on functions 
for
now).  C++17 [namespace.std]/1: "The behavior of a C ++ program is 
undefined if
it adds declarations or definitions to namespace std or to a namespace 
within
namespace std unless otherwise specified."

This found

ad4c7b97752b4da73808402604d6f96b39d920f5 "Avoid declaring function 
templates in
 namespace std"
042e30a3dc057aef4a02d95960e4dd4fb8d083ae "Avoid adding a function template
 declaration to namespace std"
cae9240a76cdb0eeed92421930d3b4cbef0ac201 "Avoid adding a function 
declaration to
 namespace std"

Change-Id: Ic2ba54e2a8bf931d5c58cedf499c0d1229eb2166
Reviewed-on: https://gerrit.libreoffice.org/78220
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/check.cxx b/compilerplugins/clang/check.cxx
index f2443e44a1f2..d53bfabbe9cf 100644
--- a/compilerplugins/clang/check.cxx
+++ b/compilerplugins/clang/check.cxx
@@ -151,12 +151,17 @@ ContextCheck DeclCheck::MemberFunction() const {
 return ContextCheck(m == nullptr ? nullptr : m->getParent());
 }
 
+namespace {
+
+bool isGlobalNamespace(clang::DeclContext const * context) {
+assert(context != nullptr);
+return (context->isLookupContext() ? context : 
context->getLookupParent())->isTranslationUnit();
+}
+
+}
+
 TerminalCheck ContextCheck::GlobalNamespace() const {
-return TerminalCheck(
-context_ != nullptr
-&& ((context_->isLookupContext()
- ? context_ : context_->getLookupParent())
-->isTranslationUnit()));
+return TerminalCheck(context_ != nullptr && isGlobalNamespace(context_));
 }
 
 TerminalCheck ContextCheck::StdNamespace() const {
@@ -164,6 +169,28 @@ TerminalCheck ContextCheck::StdNamespace() const {
 context_ != nullptr && context_->isStdNamespace());
 }
 
+namespace {
+
+bool isStdOrNestedNamespace(clang::DeclContext const * context) {
+assert(context != nullptr);
+if (!context->isNamespace()) {
+return false;
+}
+if (isGlobalNamespace(context)) {
+return false;
+}
+if (context->isStdNamespace()) {
+return true;
+}
+return isStdOrNestedNamespace(context->getParent());
+}
+
+}
+
+TerminalCheck ContextCheck::StdOrNestedNamespace() const {
+return TerminalCheck(context_ != nullptr && 
isStdOrNestedNamespace(context_));
+}
+
 ContextCheck ContextCheck::AnonymousNamespace() const {
 auto n = llvm::dyn_cast_or_null(context_);
 return ContextCheck(
diff --git a/compilerplugins/clang/check.hxx b/compilerplugins/clang/check.hxx
index 0904e5f2f1a1..4ac4f8e99cb6 100644
--- a/compilerplugins/clang/check.hxx
+++ b/compilerplugins/clang/check.hxx
@@ -103,6 +103,9 @@ private:
 
 class ContextCheck {
 public:
+explicit ContextCheck(clang::DeclContext const * context = nullptr):
+context_(context) {}
+
 explicit operator bool() const { return context_ != nullptr; }
 
 TerminalCheck GlobalNamespace() const;
@@ -111,6 +114,8 @@ public:
 
 TerminalCheck StdNamespace() const;
 
+TerminalCheck StdOrNestedNamespace() const;
+
 ContextCheck AnonymousNamespace() const;
 
 inline ContextCheck Class(llvm::StringRef id) const;
@@ -120,14 +125,6 @@ public:
 explicit ContextCheck(const clang::NamespaceDecl * decl ) : context_( decl 
) {}
 
 private:
-friend DeclCheck;
-friend TypeCheck;
-friend ContextCheck detail::checkRecordDecl(
-clang::Decl const * decl, clang::TagTypeKind tag, llvm::StringRef id);
-
-explicit ContextCheck(clang::DeclContext const * context = nullptr):
-context_(context) {}
-
 clang::DeclContext const * const context_;
 };
 
diff --git a/compilerplugins/clang/stdfunction.cxx 
b/compilerplugins/clang/stdfunction.cxx
new file mode 100644
index ..89935558d8a2
--- /dev/null
+++ b/compilerplugins/clang/stdfunction.cxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "check.hxx"

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2019-08-16 Thread Stephan Bergmann (via logerrit)
 compilerplugins/clang/nullptr.cxx|8 
 compilerplugins/clang/test/nullptr.cxx   |   23 +++
 solenv/CompilerTest_compilerplugins_clang.mk |1 +
 3 files changed, 32 insertions(+)

New commits:
commit e380e353485c3479abe645d3b6da9e007057a079
Author: Stephan Bergmann 
AuthorDate: Fri Aug 16 16:25:48 2019 +0200
Commit: Stephan Bergmann 
CommitDate: Fri Aug 16 19:54:25 2019 +0200

Adapt loplugin:nullptr to RecursiveASTVisitior::TraverseInitListExpr change

... "[AST] Treat semantic form of
InitListExpr as implicit code in traversals"

Change-Id: Ifd17009fcc6933abf0e9178dbe47fb9c14b274b7
Reviewed-on: https://gerrit.libreoffice.org/77595
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/nullptr.cxx 
b/compilerplugins/clang/nullptr.cxx
index bcdf606c13e3..30458d7f7f5a 100644
--- a/compilerplugins/clang/nullptr.cxx
+++ b/compilerplugins/clang/nullptr.cxx
@@ -75,6 +75,8 @@ public:
 
 bool TraverseLinkageSpecDecl(LinkageSpecDecl * decl);
 
+bool TraverseInitListExpr(InitListExpr * expr, DataRecursionQueue * queue 
= nullptr);
+
 // bool shouldVisitTemplateInstantiations() const { return true; }
 
 private:
@@ -231,6 +233,12 @@ bool Nullptr::TraverseLinkageSpecDecl(LinkageSpecDecl * 
decl) {
 return ret;
 }
 
+bool Nullptr::TraverseInitListExpr(InitListExpr * expr, DataRecursionQueue * 
queue) {
+return WalkUpFromInitListExpr(expr)
+&& TraverseSynOrSemInitListExpr(
+expr->isSemanticForm() ? expr : expr->getSemanticForm(), queue);
+}
+
 bool Nullptr::isInLokIncludeFile(SourceLocation spellingLocation) const {
 return loplugin::hasPathnamePrefix(
 getFileNameOfSpellingLoc(spellingLocation),
diff --git a/compilerplugins/clang/test/nullptr.cxx 
b/compilerplugins/clang/test/nullptr.cxx
new file mode 100644
index ..bf7376cb6562
--- /dev/null
+++ b/compilerplugins/clang/test/nullptr.cxx
@@ -0,0 +1,23 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+struct S
+{
+void* p;
+};
+
+int main()
+{
+S s{
+0 // expected-error {{NullToPointer ValueDependentIsNotNull 
ZeroLiteral -> nullptr [loplugin:nullptr]}}
+};
+(void)s;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 711137705ba3..caeee4333e78 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -36,6 +36,7 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/indentation \
 compilerplugins/clang/test/logexceptionnicely \
 compilerplugins/clang/test/loopvartoosmall \
+compilerplugins/clang/test/nullptr \
 compilerplugins/clang/test/mapindex \
 compilerplugins/clang/test/oncevar \
 compilerplugins/clang/test/oslendian-1 \
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk sw/qa

2019-07-23 Thread Noel Grandin (via logerrit)
 compilerplugins/clang/referencecasting.cxx |  385 +
 compilerplugins/clang/store/referencecasting.cxx   |  195 
 compilerplugins/clang/store/referencecasting.hxx   |   33 -
 compilerplugins/clang/test/referencecasting.cxx|  150 ++
 solenv/CompilerTest_compilerplugins_clang.mk   |1 
 sw/qa/extras/accessibility/accessible_relation_set.cxx |2 
 sw/qa/extras/globalfilter/globalfilter.cxx |8 
 sw/qa/extras/mailmerge/mailmerge.cxx   |8 
 sw/qa/extras/odfexport/odfexport.cxx   |   22 
 sw/qa/extras/ooxmlexport/ooxmlexport10.cxx |   45 -
 sw/qa/extras/ooxmlexport/ooxmlexport11.cxx |6 
 sw/qa/extras/ooxmlexport/ooxmlexport12.cxx |   40 -
 sw/qa/extras/ooxmlexport/ooxmlexport9.cxx  |   14 
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx   |   18 
 sw/qa/extras/ooxmlimport/ooxmlimport2.cxx  |5 
 sw/qa/extras/rtfimport/rtfimport.cxx   |   61 +-
 sw/qa/extras/uiwriter/uiwriter.cxx |   51 +-
 sw/qa/extras/uiwriter/uiwriter2.cxx|8 
 sw/qa/extras/unowriter/unowriter.cxx   |   14 
 sw/qa/extras/ww8export/ww8export.cxx   |   48 +-
 sw/qa/extras/ww8export/ww8export2.cxx  |   88 +--
 sw/qa/extras/ww8export/ww8export3.cxx  |2 
 22 files changed, 744 insertions(+), 460 deletions(-)

New commits:
commit c4bce5dafdfcb97586fab4bc3834daa6a27fec4c
Author: Noel Grandin 
AuthorDate: Thu Jul 18 14:57:37 2019 +0200
Commit: Noel Grandin 
CommitDate: Tue Jul 23 13:51:18 2019 +0200

resurrect and improve loplugin:referencecasting

Improve the plugin to avoid generating false+ with the special case of
querying XInterface (what the code calls normalisation).

Also ignore places where the querying is dealing with ambiguous base
classes.

Change-Id: I23b2b2fa6618328fafc4707b94c26582a462ea87
Reviewed-on: https://gerrit.libreoffice.org/74993
Tested-by: Jenkins
Reviewed-by: Noel Grandin 

diff --git a/compilerplugins/clang/referencecasting.cxx 
b/compilerplugins/clang/referencecasting.cxx
new file mode 100644
index ..e60177f4effb
--- /dev/null
+++ b/compilerplugins/clang/referencecasting.cxx
@@ -0,0 +1,385 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * Based on LLVM/Clang.
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ */
+
+#include "plugin.hxx"
+#include "check.hxx"
+#include 
+
+/*
+This is a compile-time checker.
+
+Check for cases where we have
+ - two IDL interfaces A and B,
+ - B extends A
+ - we are converting a Reference to a Reference using UNO_QUERY
+
+This makes the code simpler and cheaper, because UNO_QUERY can be surprisingly 
expensive if used a lot.
+
+*/
+
+class ReferenceCasting : public loplugin::FilteringPlugin
+{
+public:
+explicit ReferenceCasting(loplugin::InstantiationData const& data)
+: FilteringPlugin(data)
+{
+}
+void run() override
+{
+std::string fn(handler.getMainFileName());
+loplugin::normalizeDotDotInFilePath(fn);
+// macros
+if (fn == SRCDIR "/dbaccess/source/ui/browser/formadapter.cxx")
+return;
+TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+}
+bool VisitCXXConstructExpr(const CXXConstructExpr* cce);
+bool VisitCXXMemberCallExpr(const CXXMemberCallExpr* mce);
+
+private:
+bool CheckForUnnecessaryGet(const Expr*);
+};
+
+static const RecordType* extractTemplateType(const clang::Type*);
+static bool isDerivedFrom(const CXXRecordDecl* subtypeRecord, const 
CXXRecordDecl* baseRecord);
+
+bool ReferenceCasting::VisitCXXConstructExpr(const CXXConstructExpr* cce)
+{
+// don't bother processing anything in the Reference.h file. Makes my life 
easier when debugging this.
+StringRef aFileName = getFileNameOfSpellingLoc(
+compiler.getSourceManager().getSpellingLoc(compat::getBeginLoc(cce)));
+if (loplugin::isSamePathname(aFileName, SRCDIR 
"/include/com/sun/star/uno/Reference.h"))
+return true;
+if (loplugin::isSamePathname(aFileName, SRCDIR 
"/include/com/sun/star/uno/Reference.hxx"))
+return true;
+
+// look for calls to the Reference(x, UNO_something) constructor
+auto constructorClass = cce->getConstructor()->getParent();
+if (!constructorClass->getIdentifier() || constructorClass->getName() != 
"Reference")
+return true;
+
+if (cce->getNumArgs() != 2)
+return true;
+
+if (CheckForUnnecessaryGet(cce->getArg(0)))
+report(DiagnosticsEngine::Warning, "unnecessary get() call", 
compat::getBeginLoc(cce))
+<< cce->getSourceRange();
+
+// ignore the 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2019-06-13 Thread Noel Grandin (via logerrit)
 compilerplugins/clang/logexceptionnicely.cxx  |  136 ++
 compilerplugins/clang/stringconcat.cxx|   11 +
 compilerplugins/clang/test/logexceptionnicely.cxx |   52 
 solenv/CompilerTest_compilerplugins_clang.mk  |1 
 4 files changed, 200 insertions(+)

New commits:
commit b6086804af2b112f529952852ac55a2ffe7bd931
Author: Noel Grandin 
AuthorDate: Thu Jun 13 11:58:52 2019 +0200
Commit: Noel Grandin 
CommitDate: Thu Jun 13 13:39:08 2019 +0200

new loplugin logexceptionnicely

to be used to find places to use new TOOLS_WARN_EXCEPTION,etc macros

Change-Id: I213ab47efa82075435bb800736ee0937aea0486c
Reviewed-on: https://gerrit.libreoffice.org/73950
Tested-by: Jenkins
Reviewed-by: Noel Grandin 

diff --git a/compilerplugins/clang/logexceptionnicely.cxx 
b/compilerplugins/clang/logexceptionnicely.cxx
new file mode 100644
index ..efcf7060bf70
--- /dev/null
+++ b/compilerplugins/clang/logexceptionnicely.cxx
@@ -0,0 +1,136 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * Based on LLVM/Clang.
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ */
+
+#include "plugin.hxx"
+#include "check.hxx"
+#include "compat.hxx"
+#include 
+#include 
+
+namespace loplugin
+{
+/*
+Check that we are using exceptionToString when printing exceptions inside 
SAL_WARN, so that we
+get nicely formatted exception details in our logs.
+*/
+
+class LogExceptionNicely : public loplugin::FilteringPlugin
+{
+std::unordered_set m_visited;
+
+public:
+LogExceptionNicely(const InstantiationData& data)
+: FilteringPlugin(data)
+{
+}
+
+void run()
+{
+std::string fn(handler.getMainFileName());
+loplugin::normalizeDotDotInFilePath(fn);
+// these are below tools in the module hierarchy, so we can't use the 
pretty printing
+if (loplugin::hasPathnamePrefix(fn, SRCDIR "/cppuhelper/"))
+return;
+if (loplugin::hasPathnamePrefix(fn, SRCDIR "/ucbhelper/"))
+return;
+if (loplugin::hasPathnamePrefix(fn, SRCDIR "/binaryurp/"))
+return;
+if (loplugin::hasPathnamePrefix(fn, SRCDIR "/comphelper/"))
+return;
+// can't do that here, don't have an Any
+if (loplugin::hasPathnamePrefix(fn, SRCDIR
+
"/connectivity/source/drivers/hsqldb/HStorageMap.cxx"))
+return;
+TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+}
+
+static bool BaseCheckNotExceptionSubclass(const CXXRecordDecl* 
BaseDefinition)
+{
+if (!BaseDefinition)
+return true;
+auto tc = loplugin::TypeCheck(BaseDefinition);
+if (tc.Class("Exception")
+.Namespace("uno")
+.Namespace("star")
+.Namespace("sun")
+.Namespace("com")
+.GlobalNamespace())
+return false;
+return true;
+}
+
+bool isDerivedFromException(const CXXRecordDecl* decl)
+{
+if (!decl || !decl->hasDefinition())
+return false;
+auto tc = loplugin::TypeCheck(decl);
+if (tc.Class("Exception")
+.Namespace("uno")
+.Namespace("star")
+.Namespace("sun")
+.Namespace("com")
+.GlobalNamespace())
+return true;
+if ( // not sure what hasAnyDependentBases() does,
+// but it avoids classes we don't want, e.g. 
WeakAggComponentImplHelper1
+!decl->hasAnyDependentBases()
+&& !decl->forallBases(BaseCheckNotExceptionSubclass, true))
+{
+return true;
+}
+return false;
+}
+
+bool VisitCXXOperatorCallExpr(const CXXOperatorCallExpr* operatorCallExpr)
+{
+if (ignoreLocation(operatorCallExpr))
+return true;
+
+StringRef fn = getFileNameOfSpellingLoc(
+
compiler.getSourceManager().getExpansionLoc(compat::getBeginLoc(operatorCallExpr)));
+// these are below tools in the module hierarchy, so we can't use the 
pretty printing
+if (loplugin::hasPathnamePrefix(fn, SRCDIR "/include/comphelper/"))
+return true;
+
+if (operatorCallExpr->getOperator() != OO_LessLess)
+return true;
+auto expr = operatorCallExpr->getArg(1)->IgnoreImplicit();
+if (auto declRefExpr = dyn_cast(expr))
+if (auto varDecl = dyn_cast(declRefExpr->getDecl()))
+{
+const clang::Type* type = 
varDecl->getType()->getUnqualifiedDesugaredType();
+const CXXRecordDecl* cxxRecordDecl = 
type->getAsCXXRecordDecl();
+if (!cxxRecordDecl)
+cxxRecordDecl = 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2019-04-17 Thread Stephan Bergmann (via logerrit)
 compilerplugins/clang/selfinit.cxx   |   88 +++
 compilerplugins/clang/test/selfinit.cxx  |   33 ++
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 3 files changed, 122 insertions(+)

New commits:
commit 05a0c51ced86460b273a24f5884c99f46d8aae0d
Author: Stephan Bergmann 
AuthorDate: Wed Apr 17 19:08:16 2019 +0200
Commit: Stephan Bergmann 
CommitDate: Wed Apr 17 21:59:53 2019 +0200

New loplugin:selfinit

...to find more bugs like the one addressed in
6340daac7b99c65249363a4bb61c492de31ef5d6 "Revert broken
loplugin:sequentialassign change".  What it does is:  "Warn when a variable 
is
referenced from its own initializer.  This is not invalid in general (see 
C++17
[basic.life]), but is at least suspicious."  It found one false positive
(addressed with 884ad0d1af88f9985d30ef0dfe92d89e82f8e576 "Split
localProcessFactory function into class with setter and getter") and five 
true
positives (addressed with e0ccbe72ed6eb0d309ed272a78fd67a512acff5d "Fix use 
of
variable before its lifetime begins" and
0e335af4d3f044511551fa2ede20911beaee9b41 "Fix uses of variables before their
lifetimes begin").

Change-Id: I4c45cceaa042e93b37ad24a54784c027f6ca1f87
Reviewed-on: https://gerrit.libreoffice.org/70897
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/selfinit.cxx 
b/compilerplugins/clang/selfinit.cxx
new file mode 100644
index ..35ce37278f2a
--- /dev/null
+++ b/compilerplugins/clang/selfinit.cxx
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+
+#include "plugin.hxx"
+
+// Warn when a variable is referenced from its own initializer.  This is not 
invalid in general (see
+// C++17 [basic.life]), but is at least suspicious.
+
+namespace
+{
+class SelfInit : public loplugin::FilteringPlugin
+{
+public:
+explicit SelfInit(loplugin::InstantiationData const& data)
+: FilteringPlugin(data)
+{
+}
+
+bool TraverseVarDecl(VarDecl* decl)
+{
+decls_.push_back({ decl, decl->getCanonicalDecl() });
+auto const ret = FilteringPlugin::TraverseVarDecl(decl);
+decls_.pop_back();
+return ret;
+}
+
+bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr* expr)
+{
+if (expr->getKind() == UETT_SizeOf)
+{
+return true;
+}
+return FilteringPlugin::TraverseUnaryExprOrTypeTraitExpr(expr);
+}
+
+bool TraverseCXXTypeidExpr(CXXTypeidExpr const*) { return true; }
+
+bool TraverseCXXNoexceptExpr(CXXNoexceptExpr const*) { return true; }
+
+bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) { return true; }
+
+bool VisitDeclRefExpr(DeclRefExpr const* expr)
+{
+if (ignoreLocation(expr))
+{
+return true;
+}
+for (auto const& i : decls_)
+{
+if (expr->getDecl()->getCanonicalDecl() == i.canonical)
+{
+report(
+DiagnosticsEngine::Warning,
+("referencing a variable during its own initialization is 
error-prone and thus"
+ " suspicious"),
+expr->getLocation())
+<< expr->getSourceRange();
+report(DiagnosticsEngine::Note, "variable declared here", 
i.current->getLocation())
+<< i.current->getSourceRange();
+}
+}
+return true;
+}
+
+private:
+void run() override { 
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }
+
+struct Decl
+{
+VarDecl const* current;
+VarDecl const* canonical;
+};
+
+std::vector decls_;
+};
+
+loplugin::Plugin::Registration X("selfinit");
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/compilerplugins/clang/test/selfinit.cxx 
b/compilerplugins/clang/test/selfinit.cxx
new file mode 100644
index ..412a65b7060f
--- /dev/null
+++ b/compilerplugins/clang/test/selfinit.cxx
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+
+extern int i;
+int i = i;
+// expected-error@-1 {{referencing a variable during its own initialization is 
error-prone and thus suspicious 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2019-04-11 Thread Noel Grandin (via logerrit)
 compilerplugins/clang/sequentialassign.cxx  |  331 
 compilerplugins/clang/test/sequentialassign.cxx |   95 ++
 solenv/CompilerTest_compilerplugins_clang.mk|1 
 3 files changed, 427 insertions(+)

New commits:
commit b65f3fbb2beea99273371179703fcbc1d0ff326e
Author: Noel Grandin 
AuthorDate: Wed Apr 10 18:38:10 2019 +0200
Commit: Noel Grandin 
CommitDate: Thu Apr 11 08:52:49 2019 +0200

new loplugin sequentialassign

Look for places we are assigning to the same variable twice
in succession, which means we can simplify that to a single assign

Change-Id: I499d20e28f5595e81e927bef8e1bf364eea8ba91
Reviewed-on: https://gerrit.libreoffice.org/70531
Tested-by: Jenkins
Reviewed-by: Noel Grandin 

diff --git a/compilerplugins/clang/sequentialassign.cxx 
b/compilerplugins/clang/sequentialassign.cxx
new file mode 100644
index ..bc674694f8f1
--- /dev/null
+++ b/compilerplugins/clang/sequentialassign.cxx
@@ -0,0 +1,331 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "plugin.hxx"
+#include "check.hxx"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/StmtVisitor.h"
+
+/**
+This is a kind of simplified dead-store analysis.
+
+We are looking for patterns like:
+  Foo x = a;
+  x = b;
+which can be simplified to
+x = b
+
+or
+Foo x = a;
+x = f(x)
+which can be simplified to
+Foo x = f(a)
+
+   TODO Improve this plugin to make it safer. We should really be checking the 
following
+   conditions inside the RHS of the second statement:
+ If the variable is having it's address taken, or a non-const method 
called on it,
+ on passed by non-const-ref.
+*/
+
+namespace
+{
+//static bool startswith(const std::string& rStr, const char* pSubStr) {
+//return rStr.compare(0, strlen(pSubStr), pSubStr) == 0;
+//}
+class SequentialAssign : public loplugin::FilteringPlugin
+{
+public:
+explicit SequentialAssign(loplugin::InstantiationData const& data)
+: FilteringPlugin(data)
+{
+}
+
+virtual void run() override
+{
+std::string fn(handler.getMainFileName());
+loplugin::normalizeDotDotInFilePath(fn);
+// places where the existing code style just looks better
+// TODO lots of these would be unnecessary if I taught the plugin
+// to ignore vars which are assigned to repeatedly
+if (fn == SRCDIR "/vcl/source/helper/commandinfoprovider.cxx"
+|| fn == SRCDIR "/basegfx/source/polygon/b2dpolygonclipper.cxx"
+|| fn == SRCDIR "/i18nlangtag/source/isolang/insys.cxx"
+|| fn == SRCDIR "/vcl/unx/generic/fontmanager/fontconfig.cxx"
+|| fn == SRCDIR "/svtools/source/filter/exportdialog.cxx"
+|| fn == SRCDIR "/svtools/source/control/ruler.cxx"
+|| fn == SRCDIR "/basic/qa/cppunit/test_scanner.cxx"
+|| fn == SRCDIR "/basic/source/uno/namecont.cxx"
+|| fn == SRCDIR "/test/source/sheet/xnamedrange.cxx"
+|| fn == SRCDIR "/i18npool/qa/cppunit/test_breakiterator.cxx"
+|| fn == SRCDIR "/i18npool/source/localedata/LocaleNode.cxx"
+|| fn == SRCDIR 
"/i18npool/source/transliteration/transliteration_Ignore.cxx"
+|| fn == SRCDIR "/i18npool/qa/cppunit/test_textsearch.cxx"
+|| fn == SRCDIR "/framework/source/jobs/jobdata.cxx"
+|| fn == SRCDIR "/framework/source/services/pathsettings.cxx"
+|| fn == SRCDIR "/xmloff/source/chart/SchXMLTools.cxx"
+|| fn == SRCDIR "/svx/source/tbxctrls/Palette.cxx"
+|| fn == SRCDIR 
"/svx/source/sdr/contact/objectcontactofpageview.cxx"
+|| fn == SRCDIR "/svx/source/form/fmservs.cxx"
+|| fn == SRCDIR "/svx/source/svdraw/svdograf.cxx"
+|| fn == SRCDIR "/svx/source/accessibility/AccessibleShape.cxx"
+|| fn == SRCDIR "/svx/source/fmcomp/fmgridcl.cxx"
+|| fn == SRCDIR "/chart2/source/tools/CharacterProperties.cxx"
+|| fn == SRCDIR "/svx/source/dialog/dialcontrol.cxx"
+|| fn == SRCDIR "/connectivity/source/commontools/TTableHelper.cxx"
+|| fn == SRCDIR "/svx/source/dialog/_bmpmask.cxx"
+|| fn == SRCDIR 
"/media/noel/disk2/libo4/cui/source/dialogs/SignSignatureLineDialog.cxx"
+|| fn == SRCDIR "/filter/source/msfilter/msdffimp.cxx"
+|| fn == SRCDIR "/filter/source/flash/swffilter.cxx"
+|| fn == SRCDIR "/cui/source/dialogs/SignSignatureLineDialog.cxx"
+|| fn == SRCDIR 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2019-02-13 Thread Libreoffice Gerrit user
 compilerplugins/clang/stringconcat.cxx   |   30 +++-
 compilerplugins/clang/test/stringconcat.cxx  |   65 +++
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 3 files changed, 84 insertions(+), 12 deletions(-)

New commits:
commit bf1a511f9c7b3ca8131601ab3b267b8e24891f9a
Author: Stephan Bergmann 
AuthorDate: Wed Feb 13 11:17:10 2019 +0100
Commit: Stephan Bergmann 
CommitDate: Wed Feb 13 13:56:12 2019 +0100

Make loplugin:stringconcat more robust

Change-Id: Ib8adefd90141007c0422b4c15ba9c2cc5f707f3f
Reviewed-on: https://gerrit.libreoffice.org/67762
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/stringconcat.cxx 
b/compilerplugins/clang/stringconcat.cxx
index caa8e61ddedb..9cef9866db61 100644
--- a/compilerplugins/clang/stringconcat.cxx
+++ b/compilerplugins/clang/stringconcat.cxx
@@ -13,32 +13,36 @@
 namespace {
 
 Expr const * stripCtor(Expr const * expr) {
-auto e0 = expr;
-auto const e1 = dyn_cast(e0);
-if (e1 != nullptr) {
-e0 = e1->getSubExpr()->IgnoreParenImpCasts();
+auto e1 = expr;
+if (auto const e = dyn_cast(e1)) {
+e1 = e->getSubExpr()->IgnoreParenImpCasts();
 }
-auto const e2 = dyn_cast(e0);
+if (auto const e = dyn_cast(e1)) {
+e1 = e->getSubExpr()->IgnoreParenImpCasts();
+}
+auto const e2 = dyn_cast(e1);
 if (e2 == nullptr) {
 return expr;
 }
-auto const e3 = dyn_cast(
-e2->getSubExpr()->IgnoreParenImpCasts());
-if (e3 == nullptr) {
+auto qt = loplugin::DeclCheck(e2->getConstructor());
+if 
(qt.MemberFunction().Struct("OStringLiteral").Namespace("rtl").GlobalNamespace())
 {
+if (e2->getNumArgs() == 1) {
+return e2->getArg(0)->IgnoreParenImpCasts();
+}
 return expr;
 }
-auto qt = loplugin::DeclCheck(e3->getConstructor());
 if (!((qt.MemberFunction().Class("OString").Namespace("rtl")
.GlobalNamespace())
   || (qt.MemberFunction().Class("OUString").Namespace("rtl")
-  .GlobalNamespace(
+  .GlobalNamespace())
+  || 
qt.MemberFunction().Struct("OUStringLiteral").Namespace("rtl").GlobalNamespace()))
 {
 return expr;
 }
-if (e3->getNumArgs() != 2) {
+if (e2->getNumArgs() != 2) {
 return expr;
 }
-return e3->getArg(0)->IgnoreParenImpCasts();
+return e2->getArg(0)->IgnoreParenImpCasts();
 }
 
 class StringConcat:
@@ -100,6 +104,8 @@ bool StringConcat::VisitCallExpr(CallExpr const * expr) {
 getFileNameOfSpellingLoc(
 
compiler.getSourceManager().getSpellingLoc(compat::getBeginLoc(expr))) };
 if (loplugin::isSamePathname(
+name, SRCDIR 
"/sal/qa/rtl/oustringbuffer/test_oustringbuffer_assign.cxx")
+|| loplugin::isSamePathname(
 name, SRCDIR "/sal/qa/rtl/strings/test_ostring_concat.cxx")
 || loplugin::isSamePathname(
 name, SRCDIR "/sal/qa/rtl/strings/test_oustring_concat.cxx"))
diff --git a/compilerplugins/clang/test/stringconcat.cxx 
b/compilerplugins/clang/test/stringconcat.cxx
new file mode 100644
index ..e2d5a8ce20e3
--- /dev/null
+++ b/compilerplugins/clang/test/stringconcat.cxx
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+
+#include 
+
+#include 
+#include 
+
+#define FOO "foo"
+
+void f(std::ostream& s1)
+{
+static char const foo[] = "foo";
+s1 << "foo"
+   << "foo";
+// expected-error@-1 {{replace '<<' between string literals with 
juxtaposition}}
+s1 << "foo" << FOO;
+// expected-error@-1 {{replace '<<' between string literals with 
juxtaposition}}
+s1 << "foo" << foo;
+s1 << "foo" << OString("foo");
+// expected-error@-1 {{replace '<<' between string literals with 
juxtaposition}}
+s1 << "foo" << OString(FOO);
+// expected-error@-1 {{replace '<<' between string literals with 
juxtaposition}}
+s1 << "foo" << OString(foo);
+s1 << "foo" << OUString("foo");
+// expected-error@-1 {{replace '<<' between string literals with 
juxtaposition}}
+s1 << "foo" << OUString(FOO);
+// expected-error@-1 {{replace '<<' between string literals with 
juxtaposition}}
+s1 << "foo" << OUString(foo);
+s1 << "foo" << OUStringLiteral("foo"); //TODO: warn too, OUStringLiteral 
wrapped in OUString
+s1 << "foo" << OUStringLiteral(FOO); //TODO: warn too, OUStringLiteral 
wrapped in OUString
+s1 << "foo" << OUStringLiteral(foo);
+OString s2;
+s2 = "foo" + OString("foo");
+// expected-error@-1 {{replace '+' between string literals with 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2018-12-12 Thread Libreoffice Gerrit user
 compilerplugins/clang/test/unusedfields.cxx |   20 -
 compilerplugins/clang/unusedfields.cxx  |   10 
 compilerplugins/clang/unusedfields.only-used-in-constructor.results |   24 -
 compilerplugins/clang/unusedfields.readonly.results |   68 +--
 compilerplugins/clang/unusedfields.untouched.results|   12 
 compilerplugins/clang/unusedfields.writeonly.results|  182 
+-
 solenv/CompilerTest_compilerplugins_clang.mk|5 
 7 files changed, 239 insertions(+), 82 deletions(-)

New commits:
commit 61dfcdda8854498633cd874604bce2558bb976ec
Author: Noel Grandin 
AuthorDate: Wed Dec 12 09:40:09 2018 +0200
Commit: Noel Grandin 
CommitDate: Thu Dec 13 08:37:58 2018 +0100

loplugin:unusedfields improve write-only logic

when dealing with modifications to container classes (e.g. std::vector)

Change-Id: Ic30043631007355ee9a3d9e3f9b6488b435182d6
Reviewed-on: https://gerrit.libreoffice.org/65050
Tested-by: Jenkins
Reviewed-by: Noel Grandin 

diff --git a/compilerplugins/clang/test/unusedfields.cxx 
b/compilerplugins/clang/test/unusedfields.cxx
index a6b1ec625ec3..37cd9ac89b91 100644
--- a/compilerplugins/clang/test/unusedfields.cxx
+++ b/compilerplugins/clang/test/unusedfields.cxx
@@ -114,14 +114,13 @@ struct ReadOnly1 { ReadOnly1(int&); };
 struct ReadOnlyAnalysis
 // expected-error@-1 {{read m_f2 [loplugin:unusedfields]}}
 // expected-error@-2 {{read m_f3 [loplugin:unusedfields]}}
-// expected-error@-3 {{read m_f4 [loplugin:unusedfields]}}
-// expected-error@-4 {{read m_f5 [loplugin:unusedfields]}}
-// expected-error@-5 {{read m_f6 [loplugin:unusedfields]}}
-// expected-error@-6 {{write m_f2 [loplugin:unusedfields]}}
-// expected-error@-7 {{write m_f3 [loplugin:unusedfields]}}
-// expected-error@-8 {{write m_f4 [loplugin:unusedfields]}}
-// expected-error@-9 {{write m_f5 [loplugin:unusedfields]}}
-// expected-error@-10 {{write m_f6 [loplugin:unusedfields]}}
+// expected-error@-3 {{read m_f5 [loplugin:unusedfields]}}
+// expected-error@-4 {{read m_f6 [loplugin:unusedfields]}}
+// expected-error@-5 {{write m_f2 [loplugin:unusedfields]}}
+// expected-error@-6 {{write m_f3 [loplugin:unusedfields]}}
+// expected-error@-7 {{write m_f4 [loplugin:unusedfields]}}
+// expected-error@-8 {{write m_f5 [loplugin:unusedfields]}}
+// expected-error@-9 {{write m_f6 [loplugin:unusedfields]}}
 {
 int m_f1;
 int m_f2;
@@ -177,9 +176,8 @@ struct ReadOnlyAnalysis3
 // add elements.
 struct ReadOnlyAnalysis4
 // expected-error@-1 {{read m_readonly [loplugin:unusedfields]}}
-// expected-error@-2 {{read m_readwrite [loplugin:unusedfields]}}
-// expected-error@-3 {{write m_readwrite [loplugin:unusedfields]}}
-// expected-error@-4 {{read m_readonlyCss [loplugin:unusedfields]}}
+// expected-error@-2 {{write m_readwrite [loplugin:unusedfields]}}
+// expected-error@-3 {{read m_readonlyCss [loplugin:unusedfields]}}
 {
 std::vector m_readonly;
 std::vector m_readwrite;
diff --git a/compilerplugins/clang/unusedfields.cxx 
b/compilerplugins/clang/unusedfields.cxx
index 393c37450b74..43f3991f6dbc 100644
--- a/compilerplugins/clang/unusedfields.cxx
+++ b/compilerplugins/clang/unusedfields.cxx
@@ -586,10 +586,18 @@ void UnusedFields::checkIfReadFrom(const FieldDecl* 
fieldDecl, const Expr* membe
 if (startswith(name, "read"))
 // this is a write-only call
 ;
+else if (startswith(name, "emplace") || name == "insert"
+|| name == "erase" || name == "remove" || name == 
"remove_if" || name == "sort"
+|| name == "push_back" || name == "pop_back"
+|| name == "push_front" || name == "pop_front"
+|| name == "reserve"  || name == "resize"
+|| name == "clear" || name == "fill")
+// write-only modifications to collections
+;
 else if (name.find(">>=") != std::string::npos && 
callExpr->getArg(1) == child)
 // this is a write-only call
 ;
-else if (name == "clear" || name == "dispose" || name == 
"disposeAndClear" || name == "swap")
+else if (name == "dispose" || name == "disposeAndClear" || 
name == "swap")
 // we're abusing the write-only analysis here to look for 
fields which don't have anything useful
 // being done to them, so we're ignoring things like 
std::vector::clear, std::vector::swap,
 // and VclPtr::disposeAndClear
diff --git 
a/compilerplugins/clang/unusedfields.only-used-in-constructor.results 
b/compilerplugins/clang/unusedfields.only-used-in-constructor.results
index 0e242983d41a..e838acef69e9 100644
--- a/compilerplugins/clang/unusedfields.only-used-in-constructor.results
+++ 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2018-11-20 Thread Libreoffice Gerrit user
 compilerplugins/clang/test/unusedenumconstants.cxx  |   92 
 compilerplugins/clang/unusedenumconstants.cxx   |  133 
 compilerplugins/clang/unusedenumconstants.readonly.results  | 1494 -
 compilerplugins/clang/unusedenumconstants.untouched.results |  246 
 compilerplugins/clang/unusedenumconstants.writeonly.results |16716 
 solenv/CompilerTest_compilerplugins_clang.mk|1 
 6 files changed, 8183 insertions(+), 10499 deletions(-)

New commits:
commit 5e2322ec84840df9e268a5d2855073912413d463
Author: Noel Grandin 
AuthorDate: Tue Nov 20 13:22:50 2018 +0200
Commit: Noel Grandin 
CommitDate: Tue Nov 20 14:48:27 2018 +0100

loplugin:unusedenumconstants improvements

add some unit tests, and improve the heuristics

Change-Id: I95aa97a87e178ce8d506bd245710d0ae66ad08a4
Reviewed-on: https://gerrit.libreoffice.org/63647
Reviewed-by: Noel Grandin 
Tested-by: Noel Grandin 

diff --git a/compilerplugins/clang/test/unusedenumconstants.cxx 
b/compilerplugins/clang/test/unusedenumconstants.cxx
new file mode 100644
index ..3de1a65537e0
--- /dev/null
+++ b/compilerplugins/clang/test/unusedenumconstants.cxx
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+
+namespace test1
+{
+void test1()
+{
+enum NameClashMode
+{
+NONE,
+NO_CLASH // expected-error {{write NO_CLASH 
[loplugin:unusedenumconstants]}}
+};
+NameClashMode eNameClashMode = NO_CLASH;
+(void)eNameClashMode;
+}
+};
+
+enum class BrowseMode
+{
+Modules = 0x01, // expected-error {{read Modules 
[loplugin:unusedenumconstants]}}
+Top = 0x02, // expected-error {{write Top [loplugin:unusedenumconstants]}}
+};
+namespace o3tl
+{
+template <> struct typed_flags : is_typed_flags
+{
+};
+}
+BrowseMode g_flags;
+int test2(BrowseMode nMode)
+{
+if (nMode & BrowseMode::Modules)
+return 1;
+g_flags |= BrowseMode::Top;
+return 0;
+}
+
+enum class Enum3
+{
+One = 0x01, // expected-error {{write One [loplugin:unusedenumconstants]}}
+Two = 0x02 // expected-error {{write Two [loplugin:unusedenumconstants]}}
+};
+namespace o3tl
+{
+template <> struct typed_flags : is_typed_flags
+{
+};
+}
+void test3_foo(Enum3);
+void test3() { test3_foo(Enum3::One | Enum3::Two); }
+
+namespace test4
+{
+enum Enum4
+{
+ONE, // expected-error {{write ONE [loplugin:unusedenumconstants]}}
+TWO
+};
+struct Test4Base
+{
+Test4Base(Enum4) {}
+};
+struct Test4 : public Test4Base
+{
+Test4()
+: Test4Base(Enum4::ONE)
+{
+}
+};
+};
+
+// check that conditional operator walks up the tree
+namespace test5
+{
+enum Enum
+{
+ONE, // expected-error {{write ONE [loplugin:unusedenumconstants]}}
+TWO // expected-error {{write TWO [loplugin:unusedenumconstants]}}
+};
+
+Enum foo(int x) { return x == 1 ? Enum::ONE : Enum::TWO; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/compilerplugins/clang/unusedenumconstants.cxx 
b/compilerplugins/clang/unusedenumconstants.cxx
index b106d308fdb5..74e9eb216da7 100644
--- a/compilerplugins/clang/unusedenumconstants.cxx
+++ b/compilerplugins/clang/unusedenumconstants.cxx
@@ -44,6 +44,7 @@ struct MyFieldInfo
 std::string parentClass;
 std::string fieldName;
 std::string sourceLocation;
+SourceLocation loc;
 };
 bool operator < (const MyFieldInfo , const MyFieldInfo )
 {
@@ -68,19 +69,31 @@ public:
 {
 TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
 
-// dump all our output in one write call - this is to try and limit IO 
"crosstalk" between multiple processes
-// writing to the same logfile
-std::string output;
-for (const MyFieldInfo & s : definitionSet)
-output += "definition:\t" + s.parentClass + "\t" + s.fieldName + 
"\t" + s.sourceLocation + "\n";
-for (const MyFieldInfo & s : writeSet)
-output += "write:\t" + s.parentClass + "\t" + s.fieldName + "\n";
-for (const MyFieldInfo & s : readSet)
-output += "read:\t" + s.parentClass + "\t" + s.fieldName + "\n";
-std::ofstream myfile;
-myfile.open( WORKDIR "/loplugin.unusedenumconstants.log", 
std::ios::app | std::ios::out);
-myfile << output;
-myfile.close();
+if (!isUnitTestMode())
+{
+// dump all our output in one write call - this is to try and 
limit IO "crosstalk" between multiple processes
+// writing to the same logfile
+std::string output;
+for (const MyFieldInfo & s : definitionSet)
+ 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2018-11-20 Thread Libreoffice Gerrit user
 compilerplugins/clang/staticconstfield.cxx   |   11 ++-
 solenv/CompilerTest_compilerplugins_clang.mk |1 +
 2 files changed, 7 insertions(+), 5 deletions(-)

New commits:
commit b0e819bbc0b3ff20de04f31b593f7d5213659045
Author: Stephan Bergmann 
AuthorDate: Tue Nov 20 08:58:39 2018 +0100
Commit: Stephan Bergmann 
CommitDate: Tue Nov 20 11:18:45 2018 +0100

Fix loplugin:staticconstfield

...(ExprWithCleanups around the CXXConstructExpr in initializers for 
members of
O[U]String type, with older Clang, as used in
compilerplugins/clang/test/staticconstfield.cxx), and thus revert
e3e8d52625c2dc7a277a955d4ae2ad10c60c5f1b "Temporarily disable
compilerplugins/clang/test/staticconstfield" again.

Change-Id: Ic5fcdd1a26e4a6810369e4f9d909200d25feb12e
Reviewed-on: https://gerrit.libreoffice.org/63628
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/staticconstfield.cxx 
b/compilerplugins/clang/staticconstfield.cxx
index b10953a75617..eadbd26bef78 100644
--- a/compilerplugins/clang/staticconstfield.cxx
+++ b/compilerplugins/clang/staticconstfield.cxx
@@ -95,10 +95,11 @@ bool 
StaticConstField::TraverseConstructorInitializer(CXXCtorInitializer* init)
 
 bool found = false;
 std::string value;
+auto const initexpr = compat::IgnoreImplicit(init->getInit());
 if (tc.Const().Class("OUString").Namespace("rtl").GlobalNamespace()
 || tc.Const().Class("OString").Namespace("rtl").GlobalNamespace())
 {
-if (auto constructExpr = dyn_cast(init->getInit()))
+if (auto constructExpr = dyn_cast(initexpr))
 {
 if (constructExpr->getNumArgs() >= 1
 && isa(constructExpr->getArg(0)))
@@ -112,7 +113,7 @@ bool 
StaticConstField::TraverseConstructorInitializer(CXXCtorInitializer* init)
 else if (type->isFloatingType())
 {
 APFloat x1(0.0f);
-if (init->getInit()->EvaluateAsFloat(x1, compiler.getASTContext()))
+if (initexpr->EvaluateAsFloat(x1, compiler.getASTContext()))
 {
 std::string s;
 llvm::raw_string_ostream os(s);
@@ -123,15 +124,15 @@ bool 
StaticConstField::TraverseConstructorInitializer(CXXCtorInitializer* init)
 }
 #endif
 // ignore this, it seems to trigger an infinite recursion
-else if (isa(init->getInit()))
+else if (isa(initexpr))
 ;
 // ignore this, calling EvaluateAsInt on it will crash clang
-else if (init->getInit()->isValueDependent())
+else if (initexpr->isValueDependent())
 ;
 else
 {
 APSInt x1;
-if (init->getInit()->EvaluateAsInt(x1, compiler.getASTContext()))
+if (initexpr->EvaluateAsInt(x1, compiler.getASTContext()))
 {
 value = x1.toString(10);
 found = true;
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 96f71a5beda2..5b07568c1f75 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -53,6 +53,7 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/simplifyconstruct \
 compilerplugins/clang/test/simplifydynamiccast \
 compilerplugins/clang/test/singlevalfields \
+compilerplugins/clang/test/staticconstfield \
 compilerplugins/clang/test/staticvar \
 compilerplugins/clang/test/stringbuffer \
 compilerplugins/clang/test/stringconstant \
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2018-11-16 Thread Libreoffice Gerrit user
 compilerplugins/clang/buriedassign.cxx   |  226 +++
 compilerplugins/clang/test/buriedassign.cxx  |   80 +
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 3 files changed, 307 insertions(+)

New commits:
commit faa63cd14c1d360d0e4eedb64cd879aa1229fa60
Author: Noel Grandin 
AuthorDate: Fri Nov 16 14:01:48 2018 +0200
Commit: Noel Grandin 
CommitDate: Fri Nov 16 14:20:04 2018 +0100

new loplugin buriedassign

Change-Id: If6dd8033daf2103a81c3a7c3a44cf1e38d0a3744
Reviewed-on: https://gerrit.libreoffice.org/63466
Tested-by: Jenkins
Reviewed-by: Noel Grandin 

diff --git a/compilerplugins/clang/buriedassign.cxx 
b/compilerplugins/clang/buriedassign.cxx
new file mode 100644
index ..8d0e6cc79e59
--- /dev/null
+++ b/compilerplugins/clang/buriedassign.cxx
@@ -0,0 +1,226 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "plugin.hxx"
+#include "check.hxx"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/StmtVisitor.h"
+
+/**
+  TODO deal with C++ operator overload assign
+*/
+
+namespace
+{
+//static bool startswith(const std::string& rStr, const char* pSubStr) {
+//return rStr.compare(0, strlen(pSubStr), pSubStr) == 0;
+//}
+class BuriedAssign : public loplugin::FilteringPlugin
+{
+public:
+explicit BuriedAssign(loplugin::InstantiationData const& data)
+: FilteringPlugin(data)
+{
+}
+
+virtual void run() override
+{
+std::string fn(handler.getMainFileName());
+loplugin::normalizeDotDotInFilePath(fn);
+// getParentStmt appears not to be working very well here
+if (fn == SRCDIR "/stoc/source/inspect/introspection.cxx"
+|| fn == SRCDIR "/stoc/source/corereflection/criface.cxx")
+return;
+// calling an acquire via function pointer
+if (fn == SRCDIR "/cppu/source/uno/lbenv.cxx"
+|| fn == SRCDIR "cppu/source/typelib/static_types.cxx")
+return;
+// false+, not sure why
+if (fn == SRCDIR "/vcl/source/window/menu.cxx")
+return;
+TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+}
+
+bool VisitBinaryOperator(BinaryOperator const*);
+bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr const*);
+
+private:
+void checkExpr(Expr const*);
+};
+
+static bool isAssignmentOp(clang::BinaryOperatorKind op)
+{
+// We ignore BO_ShrAssign i.e. >>= because we use that everywhere for
+// extracting data from css::uno::Any
+return op == BO_Assign || op == BO_MulAssign || op == BO_DivAssign || op 
== BO_RemAssign
+   || op == BO_AddAssign || op == BO_SubAssign || op == BO_ShlAssign 
|| op == BO_AndAssign
+   || op == BO_XorAssign || op == BO_OrAssign;
+}
+
+static bool isAssignmentOp(clang::OverloadedOperatorKind Opc)
+{
+// Same logic as CXXOperatorCallExpr::isAssignmentOp(), which our 
supported clang
+// doesn't have yet.
+// Except that we ignore OO_GreaterGreaterEqual i.e. >>= because we use 
that everywhere for
+// extracting data from css::uno::Any
+return Opc == OO_Equal || Opc == OO_StarEqual || Opc == OO_SlashEqual || 
Opc == OO_PercentEqual
+   || Opc == OO_PlusEqual || Opc == OO_MinusEqual || Opc == 
OO_LessLessEqual
+   || Opc == OO_AmpEqual || Opc == OO_CaretEqual || Opc == 
OO_PipeEqual;
+}
+
+bool BuriedAssign::VisitBinaryOperator(BinaryOperator const* binaryOp)
+{
+if (ignoreLocation(binaryOp))
+return true;
+
+if (!isAssignmentOp(binaryOp->getOpcode()))
+return true;
+
+checkExpr(binaryOp);
+return true;
+}
+
+bool BuriedAssign::VisitCXXOperatorCallExpr(CXXOperatorCallExpr const* cxxOper)
+{
+if (ignoreLocation(cxxOper))
+return true;
+if (!isAssignmentOp(cxxOper->getOperator()))
+return true;
+checkExpr(cxxOper);
+return true;
+}
+
+void BuriedAssign::checkExpr(Expr const* binaryOp)
+{
+if 
(compiler.getSourceManager().isMacroBodyExpansion(compat::getBeginLoc(binaryOp)))
+return;
+if 
(compiler.getSourceManager().isMacroArgExpansion(compat::getBeginLoc(binaryOp)))
+return;
+
+/**
+Note: I tried writing this plugin without getParentStmt, but in order to 
make that work, I had to
+hack things like TraverseWhileStmt to call TraverseStmt on the child nodes 
myself, so I could know whether I was inside the body or the condition.
+But I could not get that to work, so switched to this approach.
+*/
+
+// look up past the temporary nodes
+Stmt const* child = binaryOp;
+Stmt const* parent = 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2018-09-16 Thread Libreoffice Gerrit user
 compilerplugins/clang/staticconstfield.cxx  |   10 +-
 compilerplugins/clang/test/staticconstfield.cxx |8 
 solenv/CompilerTest_compilerplugins_clang.mk|2 +-
 3 files changed, 10 insertions(+), 10 deletions(-)

New commits:
commit 7168fe32c9e79cf9cbbcf1e0b6a35d85781b1332
Author: Noel Grandin 
AuthorDate: Thu Sep 13 15:07:13 2018 +0200
Commit: Noel Grandin 
CommitDate: Sun Sep 16 12:01:59 2018 +0200

rename conststringfield loplugin to staticconstfield

in preparation for making it more general

Change-Id: I2fc8d0f99140dc7ef72341f8cbf28d6536ebd61f
Reviewed-on: https://gerrit.libreoffice.org/60525
Tested-by: Jenkins
Reviewed-by: Noel Grandin 

diff --git a/compilerplugins/clang/conststringfield.cxx 
b/compilerplugins/clang/staticconstfield.cxx
similarity index 83%
rename from compilerplugins/clang/conststringfield.cxx
rename to compilerplugins/clang/staticconstfield.cxx
index 23a7db9ebea2..7276d7e05c49 100644
--- a/compilerplugins/clang/conststringfield.cxx
+++ b/compilerplugins/clang/staticconstfield.cxx
@@ -14,11 +14,11 @@
 
 namespace
 {
-class ConstStringField : public loplugin::FilteringPlugin
+class StaticConstField : public loplugin::FilteringPlugin
 {
 public:
-explicit ConstStringField(loplugin::InstantiationData const& data)
-: loplugin::FilteringPlugin(data)
+explicit StaticConstField(loplugin::InstantiationData const& data)
+: loplugin::FilteringPlugin(data)
 {
 }
 
@@ -27,7 +27,7 @@ public:
 bool TraverseConstructorInitializer(CXXCtorInitializer* init);
 };
 
-bool ConstStringField::TraverseConstructorInitializer(CXXCtorInitializer* init)
+bool StaticConstField::TraverseConstructorInitializer(CXXCtorInitializer* init)
 {
 if (!init->getSourceLocation().isValid() || 
ignoreLocation(init->getSourceLocation()))
 return true;
@@ -51,7 +51,7 @@ bool 
ConstStringField::TraverseConstructorInitializer(CXXCtorInitializer* init)
 return RecursiveASTVisitor::TraverseConstructorInitializer(init);
 }
 
-loplugin::Plugin::Registration X("conststringfield", true);
+loplugin::Plugin::Registration X("staticconstfield", true);
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/compilerplugins/clang/test/conststringfield.cxx 
b/compilerplugins/clang/test/staticconstfield.cxx
similarity index 91%
rename from compilerplugins/clang/test/conststringfield.cxx
rename to compilerplugins/clang/test/staticconstfield.cxx
index 1f34ee2530e2..49b326f7d76e 100644
--- a/compilerplugins/clang/test/conststringfield.cxx
+++ b/compilerplugins/clang/test/staticconstfield.cxx
@@ -12,10 +12,10 @@
 
 class Class1
 {
-OUString const m_field1; // expected-note {{field here 
[loplugin:conststringfield]}}
+OUString const m_field1; // expected-note {{field here 
[loplugin:staticconstfield]}}
 Class1()
 : m_field1("")
-// expected-error@-1 {{string field can be static const 
[loplugin:conststringfield]}}
+// expected-error@-1 {{string field can be static const 
[loplugin:staticconstfield]}}
 {
 (void)m_field1;
 }
@@ -23,10 +23,10 @@ class Class1
 
 class Class2
 {
-OString const m_field1; // expected-note {{field here 
[loplugin:conststringfield]}}
+OString const m_field1; // expected-note {{field here 
[loplugin:staticconstfield]}}
 Class2()
 : m_field1("")
-// expected-error@-1 {{string field can be static const 
[loplugin:conststringfield]}}
+// expected-error@-1 {{string field can be static const 
[loplugin:staticconstfield]}}
 {
 (void)m_field1;
 }
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index f56fd772e806..89085c5e4a8f 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -16,7 +16,6 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/commaoperator \
 compilerplugins/clang/test/constfields \
 compilerplugins/clang/test/constparams \
-compilerplugins/clang/test/conststringfield \
 compilerplugins/clang/test/convertlong \
 compilerplugins/clang/test/cppunitassertequals \
 compilerplugins/clang/test/cstylecast \
@@ -51,6 +50,7 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/simplifybool \
 compilerplugins/clang/test/simplifyconstruct \
 compilerplugins/clang/test/simplifydynamiccast \
+compilerplugins/clang/test/staticconstfield \
 compilerplugins/clang/test/stringbuffer \
 compilerplugins/clang/test/stringconstant \
 compilerplugins/clang/test/stringloop \
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2018-06-01 Thread Stephan Bergmann
 compilerplugins/clang/test/unreffun.cxx  |   25 +
 compilerplugins/clang/test/unreffun.hxx  |   17 +
 compilerplugins/clang/unreffun.cxx   |   18 ++
 solenv/CompilerTest_compilerplugins_clang.mk |1 +
 4 files changed, 61 insertions(+)

New commits:
commit e1ab04440195092aa0bfbf445e97530082843569
Author: Stephan Bergmann 
Date:   Fri Jun 1 16:22:53 2018 +0200

Improve loplugin:unreffun

...to avoid a false positive in --enable-qt5

> [build CXX] vcl/qt5/Qt5Widget.cxx
> /home/sbergman/lo/core/vcl/qt5/Qt5Widget.cxx:466:21: error: Unreferenced 
function declaration [loplugin:unreffun]
> friend QWidget* createQt5Widget(Qt5Frame& rFrame, QWidget* parent, 
Qt::WindowFlags f);
> 
^
> 1 error generated.

Change-Id: I01e47bc5f5147916737d62fe18ce5312a0221a3f
Reviewed-on: https://gerrit.libreoffice.org/55189
Tested-by: Jenkins 
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/test/unreffun.cxx 
b/compilerplugins/clang/test/unreffun.cxx
new file mode 100644
index ..d9d56afe3c35
--- /dev/null
+++ b/compilerplugins/clang/test/unreffun.cxx
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "unreffun.hxx"
+
+template  struct S
+{
+friend void f();
+};
+
+void f() {}
+
+void g(); // expected-error {{Unreferenced function declaration 
[loplugin:unreffun]}}
+
+void h() // expected-error {{Unreferenced externally visible function 
definition [loplugin:unreffun]}}
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/compilerplugins/clang/test/unreffun.hxx 
b/compilerplugins/clang/test/unreffun.hxx
new file mode 100644
index ..20d0e50056be
--- /dev/null
+++ b/compilerplugins/clang/test/unreffun.hxx
@@ -0,0 +1,17 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_COMPILERPLUGINS_CLANG_TEST_UNREFFUN_HXX
+#define INCLUDED_COMPILERPLUGINS_CLANG_TEST_UNREFFUN_HXX
+
+void f();
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/compilerplugins/clang/unreffun.cxx 
b/compilerplugins/clang/unreffun.cxx
index d825423bfeaa..bfd48b328300 100644
--- a/compilerplugins/clang/unreffun.cxx
+++ b/compilerplugins/clang/unreffun.cxx
@@ -58,7 +58,18 @@ public:
 void run() override
 { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }
 
+bool TraverseFriendDecl(FriendDecl * decl) {
+auto const old = friendFunction_;
+friendFunction_ = 
dyn_cast_or_null(decl->getFriendDecl());
+auto const ret = RecursiveASTVisitor::TraverseFriendDecl(decl);
+friendFunction_ = old;
+return ret;
+}
+
 bool VisitFunctionDecl(FunctionDecl const * decl);
+
+private:
+FunctionDecl const * friendFunction_ = nullptr;
 };
 
 bool UnrefFun::VisitFunctionDecl(FunctionDecl const * decl) {
@@ -74,6 +85,13 @@ bool UnrefFun::VisitFunctionDecl(FunctionDecl const * decl) {
 {
 return true;
 }
+if (decl == friendFunction_) {
+if (auto const lex = 
dyn_cast(decl->getLexicalDeclContext())) {
+if (lex->isDependentContext()) {
+return true;
+}
+}
+}
 
 if (!(decl->isThisDeclarationADefinition() || isFriendDecl(decl)
   || decl->isFunctionTemplateSpecialization()))
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 9e809e484450..f97fb9c31f75 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -53,6 +53,7 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/unnecessaryoverride-dtor \
 compilerplugins/clang/test/unnecessaryparen \
 compilerplugins/clang/test/unoany \
+compilerplugins/clang/test/unreffun \
 compilerplugins/clang/test/unusedindex \
 compilerplugins/clang/test/unusedvariablecheck \
 compilerplugins/clang/test/unusedvariablemore \
___
Libreoffice-commits mailing list

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2018-02-21 Thread Noel Grandin
 compilerplugins/clang/redundantfcast.cxx  |   39 ++---
 compilerplugins/clang/test/redundantcopy.cxx  |   40 -
 compilerplugins/clang/test/redundantfcast.cxx |   48 ++
 solenv/CompilerTest_compilerplugins_clang.mk  |2 -
 4 files changed, 69 insertions(+), 60 deletions(-)

New commits:
commit 50d0ec571f302fe54ac7ddac827b571c94554bec
Author: Noel Grandin 
Date:   Thu Feb 22 08:55:08 2018 +0200

rename redundantcopy loplugin to redundantfcast

Change-Id: I34e28a30a4f1fd264c18c901cd94094531543271

diff --git a/compilerplugins/clang/redundantcopy.cxx 
b/compilerplugins/clang/redundantfcast.cxx
similarity index 57%
rename from compilerplugins/clang/redundantcopy.cxx
rename to compilerplugins/clang/redundantfcast.cxx
index bffe89014eeb..87d656c6d237 100644
--- a/compilerplugins/clang/redundantcopy.cxx
+++ b/compilerplugins/clang/redundantfcast.cxx
@@ -11,50 +11,51 @@
 #include "compat.hxx"
 #include "plugin.hxx"
 
-namespace {
-
-class RedundantCopy final:
-public RecursiveASTVisitor, public loplugin::Plugin
+namespace
+{
+class RedundantFCast final : public RecursiveASTVisitor, 
public loplugin::Plugin
 {
 public:
-explicit RedundantCopy(loplugin::InstantiationData const & data):
-Plugin(data) {}
+explicit RedundantFCast(loplugin::InstantiationData const& data)
+: Plugin(data)
+{
+}
 
-bool VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr const * expr) {
-if (ignoreLocation(expr)) {
+bool VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr const* expr)
+{
+if (ignoreLocation(expr))
+{
 return true;
 }
 auto const t1 = expr->getTypeAsWritten();
 auto const t2 = compat::getSubExprAsWritten(expr)->getType();
-if (t1.getCanonicalType().getTypePtr()
-!= t2.getCanonicalType().getTypePtr())
+if (t1.getCanonicalType().getTypePtr() != 
t2.getCanonicalType().getTypePtr())
 {
 return true;
 }
 auto tc = loplugin::TypeCheck(t1);
 if (!(tc.Class("OUString").Namespace("rtl").GlobalNamespace()
-  || tc.Class("Color").GlobalNamespace()
-  || tc.Class("unique_ptr").StdNamespace()))
+  || tc.Class("Color").GlobalNamespace() || 
tc.Class("unique_ptr").StdNamespace()))
 {
 return true;
 }
-report(
-DiagnosticsEngine::Warning,
-"redundant copy construction from %0 to %1", expr->getExprLoc())
+report(DiagnosticsEngine::Warning, "redundant functional cast from %0 
to %1",
+   expr->getExprLoc())
 << t2 << t1 << expr->getSourceRange();
 return true;
 }
 
 private:
-void run() override {
-if (compiler.getLangOpts().CPlusPlus) {
+void run() override
+{
+if (compiler.getLangOpts().CPlusPlus)
+{
 TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
 }
 }
 };
 
-static loplugin::Plugin::Registration reg("redundantcopy");
-
+static loplugin::Plugin::Registration reg("redundantfcast");
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/compilerplugins/clang/test/redundantcopy.cxx 
b/compilerplugins/clang/test/redundantcopy.cxx
deleted file mode 100644
index 0e3e7f0377c2..
--- a/compilerplugins/clang/test/redundantcopy.cxx
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#include "sal/config.h"
-
-#include 
-
-#include "rtl/ustring.hxx"
-#include "tools/color.hxx"
-
-void method1(OUString const &);
-
-int main() {
-OUString s;
-(void) OUString(s); // expected-error {{redundant copy construction from 
'rtl::OUString' to 'rtl::OUString' [loplugin:redundantcopy]}}
-using T1 = OUString;
-(void) T1(s); // expected-error {{redundant copy construction from 
'rtl::OUString' to 'T1' (aka 'rtl::OUString') [loplugin:redundantcopy]}}
-using T2 = OUString const;
-(void) T2(s); // expected-error {{redundant copy construction from 
'rtl::OUString' to 'T2' (aka 'const rtl::OUString') [loplugin:redundantcopy]}}
-
-(void) std::unique_ptr(std::unique_ptr(new int{})); // 
expected-error {{redundant copy construction from 'std::unique_ptr' to 
'std::unique_ptr' [loplugin:redundantcopy]}}
-
-OUString s1;
-method1( OUString(s1) ); // expected-error {{redundant copy construction 
from 'rtl::OUString' to 'rtl::OUString' [loplugin:redundantcopy]}}
-
-OUString s2;
-s2 = OUString(s1); // expected-error {{redundant copy 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2018-01-12 Thread Stephan Bergmann
 compilerplugins/clang/cstylecast.cxx |  440 ++-
 compilerplugins/clang/test/cstylecast.cxx|   63 +++
 compilerplugins/clang/unnecessaryparen.cxx   |  104 ++
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 4 files changed, 595 insertions(+), 13 deletions(-)

New commits:
commit cab0427cadddb3aaf1349c66f2fa13a4234ba4b2
Author: Stephan Bergmann 
Date:   Wed Jan 10 15:55:22 2018 +0100

Enable loplugin:cstylecast for some more cases

...mostly of C-style casts among arithmetic types, and automatically rewrite
those into either static_cast or a functional cast (which should have 
identical
semantics, but where the latter probably looks better for simple cases like
casting a literal to a specific type, as in "sal_Int32(0)" vs.
"static_cast(0)").

The main benefit of reducing the amount of C-style casts across the code 
base
further is so that other plugins (that have not been taught about the 
complex
semantics of C-style cast) can pick those up (cf. the various recent
"loplugin:redundantcast" commits, which address those findings after this
improved loplugin:cstylecast has been run).  Also, I found some places where
a C-style cast has probably been applied only to the first part of a larger
expression in error (because it's easy to forget parentheses in cases like
"(sal_uInt16)VOPT_CLIPMARKS+1"); I'll follow up on those individually.

The improved loplugin:cstylecast is careful to output either "(performs:
static_cast)" or "(performs: functional cast)", so that
compilerplugins/clang/test/cstylecast.cxx can check that the plugin would
automatically rewrite to one or the other form.

To allow fully-automatic rewriting, this also required 
loplugin:unnecessaryparen
to become a rewriting plugin, at least for the parens-around-cast case 
(where
"((foo)bar)" first gets rewritten to "(static_cast(bar))", then to
"static_cast(bar)".  Rewriting could probably be added to other cases 
of
loplugin:unnecessaryparen in the future, too.

(The final version of this patch would even have been able to cope with
361dd2576a09fbda83f3ce9a26ecb590c38f74e3 "Replace some C-style casts in ugly
macros with static_cast", so that manual change would not have been 
necessary
after all.)

Change-Id: Icd7e319cc38eb58262fcbf7643d177ac9ea0220a
Reviewed-on: https://gerrit.libreoffice.org/47798
Tested-by: Jenkins 
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/cstylecast.cxx 
b/compilerplugins/clang/cstylecast.cxx
index bf8e2fb00809..f09ce81a2987 100644
--- a/compilerplugins/clang/cstylecast.cxx
+++ b/compilerplugins/clang/cstylecast.cxx
@@ -7,8 +7,10 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
+#include 
 #include 
 #include 
+#include 
 #include 
 #include "plugin.hxx"
 
@@ -82,11 +84,89 @@ QualType resolvePointers(QualType type) {
 return type;
 }
 
+bool isLiteralLike(Expr const * expr) {
+expr = expr->IgnoreParenImpCasts();
+if (isa(expr) || isa(expr) || 
isa(expr)
+|| isa(expr) || isa(expr)
+|| isa(expr) || isa(expr))
+{
+return true;
+}
+if (auto const e = dyn_cast(expr)) {
+auto const d = e->getDecl();
+if (isa(d)) {
+return true;
+}
+if (auto const v = dyn_cast(d)) {
+if (d->getType().isConstQualified()) {
+if (auto const init = v->getAnyInitializer()) {
+return isLiteralLike(init);
+}
+}
+}
+return false;
+}
+if (auto const e = dyn_cast(expr)) {
+auto const k = e->getKind();
+return k == UETT_SizeOf || k == UETT_AlignOf;
+}
+if (auto const e = dyn_cast(expr)) {
+auto const k = e->getOpcode();
+if (k == UO_Plus || k == UO_Minus || k == UO_Not || k == UO_LNot) {
+return isLiteralLike(e->getSubExpr());
+}
+return false;
+}
+if (auto const e = dyn_cast(expr)) {
+auto const k = e->getOpcode();
+if (k == BO_Mul || k == BO_Div || k == BO_Rem || k == BO_Add || k == 
BO_Sub || k == BO_Shl
+|| k == BO_Shr || k == BO_And || k == BO_Xor || k == BO_Or)
+{
+return isLiteralLike(e->getLHS()) && isLiteralLike(e->getRHS());
+}
+return false;
+}
+if (auto const e = dyn_cast(expr)) {
+auto const t = e->getTypeAsWritten();
+return (t->isArithmeticType() || t->isEnumeralType())
+&& isLiteralLike(e->getSubExprAsWritten());
+}
+return false;
+}
+
+bool canBeUsedForFunctionalCast(TypeSourceInfo const * info) {
+// Must be  or , lets 
approximate that here:
+assert(info != nullptr);
+auto const type = info->getType();
+if (type.hasLocalQualifiers()) {
+return false;

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2017-12-14 Thread Noel Grandin
 compilerplugins/clang/test/unusedindex.cxx   |   23 +++
 compilerplugins/clang/unusedindex.cxx|   86 +++
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 3 files changed, 110 insertions(+)

New commits:
commit 5f4b126f74b1fa85f99a0ee3dfdf45368b6a1bb7
Author: Noel Grandin 
Date:   Fri Dec 15 08:23:01 2017 +0200

once off loplugin: unusedindex

Change-Id: Ifdf5da1f014c4f130eafed475c6781c029d54f1d

diff --git a/compilerplugins/clang/test/unusedindex.cxx 
b/compilerplugins/clang/test/unusedindex.cxx
new file mode 100644
index ..69ad7000b38c
--- /dev/null
+++ b/compilerplugins/clang/test/unusedindex.cxx
@@ -0,0 +1,23 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+
+void func1()
+{
+std::vector v1;
+int n = 0;
+
+for (int i = 0; i < 10; ++i) // expected-error {{loop variable not used 
[loplugin:unusedindex]}}
+n += 1;
+for (int i = 0; i < 10; ++i)
+n += i;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/compilerplugins/clang/unusedindex.cxx 
b/compilerplugins/clang/unusedindex.cxx
new file mode 100644
index ..96c343820a6b
--- /dev/null
+++ b/compilerplugins/clang/unusedindex.cxx
@@ -0,0 +1,86 @@
+
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+#include 
+#include 
+
+#include "plugin.hxx"
+#include "check.hxx"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/StmtVisitor.h"
+
+/*
+ Mike Kaganski found a bug where the code was looping over a block and
+ not using the index var, and the loop was unnecessary.
+ So he wanted to have a look for other places like that.
+*/
+namespace
+{
+class UnusedIndex : public RecursiveASTVisitor, public 
loplugin::Plugin
+{
+public:
+explicit UnusedIndex(loplugin::InstantiationData const& data)
+: Plugin(data)
+{
+}
+
+virtual void run() override { 
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }
+
+bool TraverseForStmt(ForStmt* stmt);
+bool VisitDeclRefExpr(DeclRefExpr const* stmt);
+
+private:
+VarDecl const* mLoopVarDecl = nullptr;
+std::unordered_set mFoundSet;
+};
+
+bool UnusedIndex::TraverseForStmt(ForStmt* stmt)
+{
+if (ignoreLocation(stmt))
+return true;
+auto savedCopy = mLoopVarDecl;
+
+mLoopVarDecl = nullptr;
+if (stmt->getInit())
+{
+auto declStmt = dyn_cast(stmt->getInit());
+if (declStmt && declStmt->isSingleDecl())
+{
+auto varDecl = dyn_cast(declStmt->getSingleDecl());
+if (varDecl)
+mLoopVarDecl = varDecl;
+}
+}
+
+// deliberately ignore the other parts of the for stmt, except for the body
+auto ret = RecursiveASTVisitor::TraverseStmt(stmt->getBody());
+
+if (mLoopVarDecl && mFoundSet.erase(mLoopVarDecl) == 0)
+report(DiagnosticsEngine::Warning, "loop variable not used", 
mLoopVarDecl->getLocStart())
+<< mLoopVarDecl->getSourceRange();
+mLoopVarDecl = savedCopy;
+return ret;
+}
+
+bool UnusedIndex::VisitDeclRefExpr(DeclRefExpr const* stmt)
+{
+auto varDecl = dyn_cast(stmt->getDecl());
+if (!varDecl)
+return true;
+if (mLoopVarDecl && mLoopVarDecl == varDecl)
+mFoundSet.insert(varDecl);
+return true;
+}
+
+loplugin::Plugin::Registration X("unusedindex", false);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 4a98ef996091..41990fab90f4 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -48,6 +48,7 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/unnecessaryoverride-dtor \
 compilerplugins/clang/test/unnecessaryparen \
 compilerplugins/clang/test/unoany \
+compilerplugins/clang/test/unusedindex \
 compilerplugins/clang/test/unusedvariablecheck \
 compilerplugins/clang/test/useuniqueptr \
 compilerplugins/clang/test/vclwidgets \
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2017-10-20 Thread Stephan Bergmann
 compilerplugins/clang/faileddyncast.cxx  |6 ++
 compilerplugins/clang/test/faileddyncast.cxx |   21 +
 solenv/CompilerTest_compilerplugins_clang.mk |1 +
 3 files changed, 28 insertions(+)

New commits:
commit 1c680d763e770250b8e1b0e63e62a4f5ecda3b74
Author: Stephan Bergmann 
Date:   Fri Oct 20 14:48:16 2017 +0200

Avoid loplugin:faileddyncast for "unnecessary", up-casting dynamic_cast

Change-Id: Iecb943db0aff7ffc21cc2f6adb625be369255b32
Reviewed-on: https://gerrit.libreoffice.org/43606
Tested-by: Jenkins 
Reviewed-by: Noel Grandin 

diff --git a/compilerplugins/clang/faileddyncast.cxx 
b/compilerplugins/clang/faileddyncast.cxx
index bdc9ce6e5fad..9a257d7d8a23 100644
--- a/compilerplugins/clang/faileddyncast.cxx
+++ b/compilerplugins/clang/faileddyncast.cxx
@@ -80,7 +80,13 @@ bool isAlwaysNull(CXXDynamicCastExpr const * expr) {
 return false;
 #endif
 
+#if 0
   return !DestRD->isDerivedFrom(SrcRD);
+#else
+  return !(DestRD->isDerivedFrom(SrcRD)
+   || SrcRD->isDerivedFrom(DestRD)
+   || SrcRD == DestRD);
+#endif
 }
 
 class FailedDynCast:
diff --git a/compilerplugins/clang/test/faileddyncast.cxx 
b/compilerplugins/clang/test/faileddyncast.cxx
new file mode 100644
index ..7d835e041f7a
--- /dev/null
+++ b/compilerplugins/clang/test/faileddyncast.cxx
@@ -0,0 +1,21 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+struct S1 { virtual ~S1(); };
+struct S2 final: S1 {};
+struct S3: S1 {};
+
+void f(S1 * s1, S2 * s2) {
+(void) dynamic_cast(s1);
+(void) dynamic_cast(s2);
+(void) dynamic_cast(s2);
+(void) dynamic_cast(s2); // expected-error {{dynamic_cast from 'S2 
*' to 'S3 *' always fails [loplugin:faileddyncast]}}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 26306dccc983..97a870d9c296 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -21,6 +21,7 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/droplong \
 compilerplugins/clang/test/externvar \
 compilerplugins/clang/test/expressionalwayszero \
+compilerplugins/clang/test/faileddyncast \
 compilerplugins/clang/test/finalprotected \
 compilerplugins/clang/test/flatten \
 compilerplugins/clang/test/loopvartoosmall \
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk sw/source vcl/source

2017-10-06 Thread Stephan Bergmann
 compilerplugins/clang/commaoperator.cxx  |   71 +--
 compilerplugins/clang/test/commaoperator.cxx |   27 ++
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 sw/source/core/doc/number.cxx|   20 ++-
 vcl/source/gdi/svmconverter.cxx  |5 +
 5 files changed, 95 insertions(+), 29 deletions(-)

New commits:
commit 4fc52078f6afa4368b2f4de3cd700e474b7a417f
Author: Stephan Bergmann 
Date:   Fri Oct 6 08:55:26 2017 +0200

Improve performance of loplugin:commaoperator

...by avoiding calls to parentStmt, thereby also improving the precision of
exactly which comma operators to ignore (which turned up a handful more 
finds).
Also added tests.

Change-Id: Ie74f824fd7f54131aab09b59086452fb4f3ff827
Reviewed-on: https://gerrit.libreoffice.org/43181
Tested-by: Jenkins 
Reviewed-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/commaoperator.cxx 
b/compilerplugins/clang/commaoperator.cxx
index c4a61e772281..c9efc09092de 100644
--- a/compilerplugins/clang/commaoperator.cxx
+++ b/compilerplugins/clang/commaoperator.cxx
@@ -20,6 +20,13 @@ the comma operator is best used sparingly
 
 namespace {
 
+Stmt const * lookThroughExprWithCleanups(Stmt const * stmt) {
+if (auto const e = dyn_cast_or_null(stmt)) {
+return e->getSubExpr();
+}
+return stmt;
+}
+
 class CommaOperator:
 public RecursiveASTVisitor, public loplugin::Plugin
 {
@@ -31,11 +38,49 @@ public:
 TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
 }
 
-bool VisitBinaryOperator(const BinaryOperator* );
+bool TraverseForStmt(ForStmt * stmt) {
+auto const saved1 = ignore1_;
+ignore1_ = lookThroughExprWithCleanups(stmt->getInit());
+auto const saved2 = ignore2_;
+ignore2_ = lookThroughExprWithCleanups(stmt->getInc());
+auto const ret = RecursiveASTVisitor::TraverseForStmt(stmt);
+ignore1_ = saved1;
+ignore2_ = saved2;
+return ret;
+}
+
+bool TraverseParenExpr(ParenExpr * expr) {
+auto const saved1 = ignore1_;
+ignore1_ = expr->getSubExpr();
+auto const ret = RecursiveASTVisitor::TraverseParenExpr(expr);
+ignore1_ = saved1;
+return ret;
+}
+
+bool TraverseBinComma(BinaryOperator * expr) {
+if (!WalkUpFromBinComma(expr)) {
+return false;
+}
+auto const saved1 = ignore1_;
+ignore1_ = expr->getLHS();
+auto const ret = TraverseStmt(expr->getLHS())
+&& TraverseStmt(expr->getRHS());
+ignore1_ = saved1;
+return ret;
+}
+
+bool VisitBinComma(const BinaryOperator* );
+
+private:
+Stmt const * ignore1_ = nullptr;
+Stmt const * ignore2_ = nullptr;
 };
 
-bool CommaOperator::VisitBinaryOperator(const BinaryOperator* binaryOp)
+bool CommaOperator::VisitBinComma(const BinaryOperator* binaryOp)
 {
+if (binaryOp == ignore1_ || binaryOp == ignore2_) {
+return true;
+}
 if (ignoreLocation(binaryOp)) {
 return true;
 }
@@ -54,28 +99,6 @@ bool CommaOperator::VisitBinaryOperator(const 
BinaryOperator* binaryOp)
 {
 return true;
 }
-if (binaryOp->getOpcode() != BO_Comma) {
-return true;
-}
-const Stmt* parent = parentStmt(binaryOp);
-if (parent != nullptr) {
-if (isa(parent)) {
-return true;
-}
-if (isa(parent)) {
-return true;
-}
-if (isa(parent)) {
-return true;
-}
-if (isa(parent)) {
-const Stmt* parent2 = parentStmt(parent);
-if (isa(parent2)) {
-return true;
-}
-}
-}
-//parent->dump();
 report(
 DiagnosticsEngine::Warning, "comma operator hides code",
 binaryOp->getOperatorLoc())
diff --git a/compilerplugins/clang/test/commaoperator.cxx 
b/compilerplugins/clang/test/commaoperator.cxx
new file mode 100644
index ..199dcf41c243
--- /dev/null
+++ b/compilerplugins/clang/test/commaoperator.cxx
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+bool f();
+
+struct S { ~S(); };
+
+int main() {
+f(), f(), f(); // expected-error {{comma operator hides code 
[loplugin:commaoperator]}}
+(f(), f());
+for (
+f(), f();
+f(), f(); // expected-error {{comma operator hides code 
[loplugin:commaoperator]}}
+f(), f())
+f(), f(); // expected-error {{comma operator hides code 
[loplugin:commaoperator]}}
+S s;
+(s = 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2017-09-22 Thread Michael Stahl
 compilerplugins/clang/badstatics.cxx |   13 +++---
 compilerplugins/clang/test/badstatics.cxx|   58 +++
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 3 files changed, 67 insertions(+), 5 deletions(-)

New commits:
commit 0fbfdce3eab680eb845af0d9cdb1d2352a5cbd28
Author: Michael Stahl 
Date:   Thu Sep 21 16:37:40 2017 +0200

compilerplugins: add test for badstatics

Change-Id: Ibdb3144c0510ed723a01ca28d7cdcd6b21caec54
Reviewed-on: https://gerrit.libreoffice.org/42596
Tested-by: Jenkins 
Reviewed-by: Michael Stahl 

diff --git a/compilerplugins/clang/badstatics.cxx 
b/compilerplugins/clang/badstatics.cxx
index 56f2b7be9f91..9ada7b60459c 100644
--- a/compilerplugins/clang/badstatics.cxx
+++ b/compilerplugins/clang/badstatics.cxx
@@ -225,11 +225,14 @@ public:
 "bad static variable causes crash on shutdown",
 pVarDecl->getLocation())
 << pVarDecl->getSourceRange();
-for (auto i: ret.second) {
-report(DiagnosticsEngine::Note,
-"... due to this member of %0",
-i->getLocation())
-<< i->getParent() << i->getSourceRange();
+if (!isUnitTestMode())
+{
+for (auto i: ret.second) {
+report(DiagnosticsEngine::Note,
+"... due to this member of %0",
+i->getLocation())
+<< i->getParent() << i->getSourceRange();
+}
 }
 }
 }
diff --git a/compilerplugins/clang/test/badstatics.cxx 
b/compilerplugins/clang/test/badstatics.cxx
new file mode 100644
index ..db9a023d95a6
--- /dev/null
+++ b/compilerplugins/clang/test/badstatics.cxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+class Image { public: ~Image() { ::std::abort(); } };
+class Bitmap { public: ~Bitmap() { ::std::abort(); } };
+
+struct WithImage
+{
+Image image;
+};
+
+struct WithBitmap
+{
+Bitmap bitmap;
+};
+
+WithImage g_bug1; // expected-error {{bad static variable causes crash on 
shutdown [loplugin:badstatics]}}
+WithBitmap g_bug2; // expected-error {{bad static variable causes crash on 
shutdown [loplugin:badstatics]}}
+
+static WithImage g_bug3; // expected-error {{bad static variable causes crash 
on shutdown [loplugin:badstatics]}}
+
+void foo() {
+static Image s_bug1; // expected-error {{bad static variable causes crash 
on shutdown [loplugin:badstatics]}}
+Image nobug;
+}
+
+::std::unique_ptr g_bug4; // expected-error {{bad static variable 
causes crash on shutdown [loplugin:badstatics]}}
+
+::std::shared_ptr g_bug5; // expected-error {{bad static variable 
causes crash on shutdown [loplugin:badstatics]}}
+
+::std::weak_ptr g_nobug;
+
+struct DerivedWithImage : WithImage
+{
+};
+
+DerivedWithImage g_bug6; // expected-error {{bad static variable causes crash 
on shutdown [loplugin:badstatics]}}
+
+::std::vector g_bug7; // expected-error {{bad static variable causes 
crash on shutdown [loplugin:badstatics]}}
+
+::std::vector<::std::unique_ptr> g_bug8; // expected-error {{bad static 
variable causes crash on shutdown [loplugin:badstatics]}}
+
+::std::map g_bug9; // expected-error {{bad static variable causes 
crash on shutdown [loplugin:badstatics]}}
+
+::std::map g_bug10; // expected-error {{bad static variable causes 
crash on shutdown [loplugin:badstatics]}}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index f0c53ed3095a..4a6928a72348 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -10,6 +10,7 @@
 $(eval $(call gb_CompilerTest_CompilerTest,compilerplugins_clang))
 
 $(eval $(call gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
+compilerplugins/clang/test/badstatics \
 compilerplugins/clang/test/casttovoid \
 compilerplugins/clang/test/constparams \
 $(if $(filter-out INTEL,$(CPU)),compilerplugins/clang/test/convertuintptr) 
\
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2017-09-21 Thread Noel Grandin
 compilerplugins/clang/test/unusedfields.cxx  |   18 ++
 compilerplugins/clang/unusedfields.cxx   |   13 +
 solenv/CompilerTest_compilerplugins_clang.mk |4 +---
 3 files changed, 28 insertions(+), 7 deletions(-)

New commits:
commit e8b5ec6590bbde63f3bbe50d049a3307d9d5682c
Author: Noel Grandin 
Date:   Wed Sep 20 16:22:27 2017 +0200

loplugin:unusedfields, fix var taking ref

Change-Id: I0ea1f0c7488c140fca9f64de326c6ac588ece925

diff --git a/compilerplugins/clang/test/unusedfields.cxx 
b/compilerplugins/clang/test/unusedfields.cxx
index 71489b018843..21e59fcbbdd1 100644
--- a/compilerplugins/clang/test/unusedfields.cxx
+++ b/compilerplugins/clang/test/unusedfields.cxx
@@ -116,16 +116,19 @@ struct ReadOnlyAnalysis
 // expected-error@-2 {{read m_f3 [loplugin:unusedfields]}}
 // expected-error@-3 {{read m_f4 [loplugin:unusedfields]}}
 // expected-error@-4 {{read m_f5 [loplugin:unusedfields]}}
-// expected-error@-5 {{write m_f2 [loplugin:unusedfields]}}
-// expected-error@-6 {{write m_f3 [loplugin:unusedfields]}}
-// expected-error@-7 {{write m_f4 [loplugin:unusedfields]}}
-// expected-error@-8 {{write m_f5 [loplugin:unusedfields]}}
+// expected-error@-5 {{read m_f6 [loplugin:unusedfields]}}
+// expected-error@-6 {{write m_f2 [loplugin:unusedfields]}}
+// expected-error@-7 {{write m_f3 [loplugin:unusedfields]}}
+// expected-error@-8 {{write m_f4 [loplugin:unusedfields]}}
+// expected-error@-9 {{write m_f5 [loplugin:unusedfields]}}
+// expected-error@-10 {{write m_f6 [loplugin:unusedfields]}}
 {
 int m_f1;
 int m_f2;
 int m_f3;
 std::vector m_f4;
 int m_f5;
+int m_f6;
 
 // check that we dont see a write of m_f1
 ReadOnlyAnalysis() : m_f1(0) {}
@@ -141,6 +144,13 @@ struct ReadOnlyAnalysis
 
 // check that we see a write when we pass by non-const ref
 void method5() { ReadOnly1 a(m_f5); }
+
+// check that we see a write when we pass by non-const ref
+void method6()
+{
+int& r = m_f6;
+r = 1;
+}
 };
 
 struct ReadOnlyAnalysis2
diff --git a/compilerplugins/clang/unusedfields.cxx 
b/compilerplugins/clang/unusedfields.cxx
index 69ea4be9c8b2..af2be7ba6076 100644
--- a/compilerplugins/clang/unusedfields.cxx
+++ b/compilerplugins/clang/unusedfields.cxx
@@ -611,6 +611,19 @@ void UnusedFields::checkReadOnly(const FieldDecl* 
fieldDecl, const Expr* memberE
 {
 if (!parent)
 {
+// check if we have an expression like
+//int& r = m_field;
+auto parentsRange = compiler.getASTContext().getParents(*child);
+if (parentsRange.begin() != parentsRange.end())
+{
+auto varDecl = 
dyn_cast_or_null(parentsRange.begin()->get());
+// The isImplicit() call is to avoid triggering when we see 
the vardecl which is part of a for-range statement,
+// which is of type 'T&&' and also an l-value-ref ?
+if (varDecl && !varDecl->isImplicit() && 
loplugin::TypeCheck(varDecl->getType()).LvalueReference().NonConst())
+{
+bPotentiallyWrittenTo = true;
+}
+}
 break;
 }
 if (isa(parent))
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 8df1c2b495f7..10fa577d908a 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -38,13 +38,11 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/unnecessaryoverride-dtor \
 compilerplugins/clang/test/unnecessaryparen \
 compilerplugins/clang/test/unoany \
+compilerplugins/clang/test/unusedfields \
 compilerplugins/clang/test/useuniqueptr \
 compilerplugins/clang/test/vclwidgets \
 ))
 
-# FIXME Fails with clang-3.8.
-#compilerplugins/clang/test/unusedfields \
-
 $(eval $(call gb_CompilerTest_use_externals,compilerplugins_clang, \
 boost_headers \
 cppunit \
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2017-09-20 Thread Noel Grandin
 compilerplugins/clang/flatten.cxx|  262 +++
 compilerplugins/clang/test/flatten.cxx   |   29 ++
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 3 files changed, 292 insertions(+)

New commits:
commit dc97ede7cffbb5ce704602456ba0f560caee22a2
Author: Noel Grandin 
Date:   Wed Sep 20 12:18:04 2017 +0200

new loplugin flatten

look for places where we can flatten the control flow in a method by
exiting early with a throw, ie. instead of

   if (cond)
   stuff();
   else
   throw ex;

we  change it to:

   if (!cond)
  throw ex;
   stuff();

Change-Id: I8b6bdf883b325807c7e3a3ef698e4f4606e7d38b

diff --git a/compilerplugins/clang/flatten.cxx 
b/compilerplugins/clang/flatten.cxx
new file mode 100644
index ..f3c49591c1a7
--- /dev/null
+++ b/compilerplugins/clang/flatten.cxx
@@ -0,0 +1,262 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "plugin.hxx"
+
+/**
+  Look for places where we can flatten the control flow in a method.
+
+ */
+
+namespace {
+
+class Flatten:
+public RecursiveASTVisitor, public loplugin::RewritePlugin
+{
+public:
+explicit Flatten(InstantiationData const & data): RewritePlugin(data) {}
+
+virtual void run() override
+{
+TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+}
+
+bool TraverseCXXCatchStmt(CXXCatchStmt * );
+bool VisitIfStmt(const IfStmt * );
+private:
+bool rewrite(const IfStmt * );
+SourceRange ignoreMacroExpansions(SourceRange range);
+std::string getSourceAsString(SourceRange range);
+};
+
+static const Stmt * containsSingleThrowExpr(const Stmt * stmt)
+{
+if (auto compoundStmt = dyn_cast(stmt)) {
+if (compoundStmt->size() != 1)
+return nullptr;
+stmt = *compoundStmt->body_begin();
+}
+if (auto exprWithCleanups = dyn_cast(stmt)) {
+stmt = exprWithCleanups->getSubExpr();
+}
+return dyn_cast(stmt);
+}
+
+bool Flatten::TraverseCXXCatchStmt(CXXCatchStmt* )
+{
+// ignore stuff inside catch statements, where doing a "if...else..throw" 
is more natural
+return true;
+}
+
+bool Flatten::VisitIfStmt(const IfStmt* ifStmt)
+{
+if (ignoreLocation(ifStmt))
+return true;
+
+if (!ifStmt->getElse())
+return true;
+
+// ignore if/then/else/if chains for now
+if (isa(ifStmt->getElse()))
+return true;
+
+// ignore if we are part of an if/then/else/if chain
+auto parentIfStmt = dyn_cast(parentStmt(ifStmt));
+if (parentIfStmt && parentIfStmt->getElse() == ifStmt)
+return true;
+
+auto throwExpr = containsSingleThrowExpr(ifStmt->getElse());
+if (!throwExpr)
+return true;
+
+// if both the "if" and the "else" contain throws, no improvement
+if (containsSingleThrowExpr(ifStmt->getThen()))
+return true;
+
+if (!rewrite(ifStmt))
+{
+report(
+DiagnosticsEngine::Warning,
+"unconditional throw in else branch, rather invert the condition, 
throw early, and flatten the normal case",
+throwExpr->getLocStart())
+<< throwExpr->getSourceRange();
+report(
+DiagnosticsEngine::Note,
+"if condition here",
+ifStmt->getLocStart())
+<< ifStmt->getSourceRange();
+}
+return true;
+}
+
+static std::string stripOpenAndCloseBrace(std::string s);
+static std::string deindentThenStmt(std::string const & s);
+static std::vector split(std::string const & s);
+
+bool Flatten::rewrite(const IfStmt* ifStmt)
+{
+if (!rewriter)
+return false;
+
+auto conditionRange = 
ignoreMacroExpansions(ifStmt->getCond()->getSourceRange());
+if (!conditionRange.isValid()) {
+return false;
+}
+auto thenRange = 
ignoreMacroExpansions(ifStmt->getThen()->getSourceRange());
+if (!thenRange.isValid()) {
+return false;
+}
+auto elseRange = 
ignoreMacroExpansions(ifStmt->getElse()->getSourceRange());
+if (!elseRange.isValid()) {
+return false;
+}
+auto elseKeywordRange = ifStmt->getElseLoc();
+
+// in adjusting the formatting I assume that "{" starts on a new line
+
+std::string conditionString = getSourceAsString(conditionRange);
+conditionString = "(!" + conditionString + ")";
+
+std::string thenString = getSourceAsString(thenRange);
+bool thenIsCompound = false;
+if (auto compoundStmt = dyn_cast(ifStmt->getThen())) {
+if (compoundStmt->getLBracLoc().isValid()) {
+

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2017-08-16 Thread Noel Grandin
 solenv/CompilerTest_compilerplugins_clang.mk |1 -
 1 file changed, 1 deletion(-)

New commits:
commit 9fb742489b2101c5e7cd8015d053695ce3066291
Author: Noel Grandin 
Date:   Wed Aug 16 11:19:02 2017 +0200

move deadclass plugin to store

 noelgrandin, and is loplugin:deadclass even sound?

struct B { B(B const &) {} }; struct D: B { D(): B(*this) {} };

Change-Id: Idadd379b925aa6f9de6c625bffa8560ec4192ac7

diff --git a/compilerplugins/clang/deadclass.cxx 
b/compilerplugins/clang/store/deadclass.cxx
similarity index 100%
rename from compilerplugins/clang/deadclass.cxx
rename to compilerplugins/clang/store/deadclass.cxx
diff --git a/compilerplugins/clang/test/deadclass.cxx 
b/compilerplugins/clang/store/test/deadclass.cxx
similarity index 100%
rename from compilerplugins/clang/test/deadclass.cxx
rename to compilerplugins/clang/store/test/deadclass.cxx
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index a5ec62024a0e..4f1b41149536 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -13,7 +13,6 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/casttovoid \
 compilerplugins/clang/test/constparams \
 compilerplugins/clang/test/cppunitassertequals \
-compilerplugins/clang/test/deadclass \
 compilerplugins/clang/test/datamembershadow \
 compilerplugins/clang/test/droplong \
 compilerplugins/clang/test/externvar \
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2017-07-03 Thread Stephan Bergmann
 compilerplugins/clang/casttovoid.cxx  |  494 ++
 compilerplugins/clang/check.cxx   |   73 +++
 compilerplugins/clang/check.hxx   |2 
 compilerplugins/clang/compat.hxx  |   34 +
 compilerplugins/clang/test/casttovoid.cxx |  110 +
 compilerplugins/clang/unusedvariablecheck.cxx |   74 ---
 solenv/CompilerTest_compilerplugins_clang.mk  |1 
 7 files changed, 715 insertions(+), 73 deletions(-)

New commits:
commit 65d6c642590bd5f51c04228d941608322a85f1ac
Author: Stephan Bergmann 
Date:   Mon Jul 3 12:34:38 2017 +0200

loplugin:casttovoid

Change-Id: I427b15b35ef6e7c803cb8a00c961d35175ae8cb2

diff --git a/compilerplugins/clang/casttovoid.cxx 
b/compilerplugins/clang/casttovoid.cxx
new file mode 100644
index ..997f7ed83e7c
--- /dev/null
+++ b/compilerplugins/clang/casttovoid.cxx
@@ -0,0 +1,494 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "clang/AST/Attr.h"
+
+#include "check.hxx"
+#include "compat.hxx"
+#include "plugin.hxx"
+
+namespace {
+
+bool isWarnUnusedType(QualType type) {
+if (auto const t = type->getAs()) {
+if (t->getDecl()->hasAttr()) {
+return true;
+}
+}
+if (auto const t = type->getAs()) {
+if (t->getDecl()->hasAttr()) {
+return true;
+}
+}
+return loplugin::isExtraWarnUnusedType(type);
+}
+
+Expr const * lookThroughInitListExpr(Expr const * expr) {
+if (auto const ile = dyn_cast(expr->IgnoreParenImpCasts())) {
+if (ile->getNumInits() == 1) {
+return ile->getInit(0);
+}
+}
+return expr;
+}
+
+class Visitor final:
+public RecursiveASTVisitor, public loplugin::Plugin
+{
+public:
+explicit Visitor(InstantiationData const & data): Plugin(data) {}
+
+bool TraverseCStyleCastExpr(CStyleCastExpr * expr) {
+auto const dre = checkCast(expr);
+if (dre != nullptr) {
+castToVoid_.push({expr, dre});
+}
+auto const ret = RecursiveASTVisitor::TraverseCStyleCastExpr(expr);
+if (dre != nullptr) {
+assert(!castToVoid_.empty());
+assert(castToVoid_.top().cast == expr);
+assert(castToVoid_.top().sub == dre);
+castToVoid_.pop();
+}
+return ret;
+}
+
+bool TraverseCXXStaticCastExpr(CXXStaticCastExpr * expr) {
+auto const dre = checkCast(expr);
+if (dre != nullptr) {
+castToVoid_.push({expr, dre});
+}
+auto const ret = RecursiveASTVisitor::TraverseCXXStaticCastExpr(expr);
+if (dre != nullptr) {
+assert(!castToVoid_.empty());
+assert(castToVoid_.top().cast == expr);
+assert(castToVoid_.top().sub == dre);
+castToVoid_.pop();
+}
+return ret;
+}
+
+bool TraverseCXXFunctionalCastExpr(CXXFunctionalCastExpr * expr) {
+auto const dre = checkCast(expr);
+if (dre != nullptr) {
+castToVoid_.push({expr, dre});
+}
+auto const ret = RecursiveASTVisitor::TraverseCXXFunctionalCastExpr(
+expr);
+if (dre != nullptr) {
+assert(!castToVoid_.empty());
+assert(castToVoid_.top().cast == expr);
+assert(castToVoid_.top().sub == dre);
+castToVoid_.pop();
+}
+return ret;
+}
+
+bool TraverseFunctionDecl(FunctionDecl * decl) {
+returnTypes_.push(decl->getReturnType());
+auto const ret = RecursiveASTVisitor::TraverseFunctionDecl(decl);
+assert(!returnTypes_.empty());
+assert(returnTypes_.top() == decl->getReturnType());
+returnTypes_.pop();
+return ret;
+}
+
+#if CLANG_VERSION >= 5
+bool TraverseCXXDeductionGuideDecl(CXXDeductionGuideDecl * decl) {
+returnTypes_.push(decl->getReturnType());
+auto const ret = RecursiveASTVisitor::TraverseCXXDeductionGuideDecl(
+decl);
+assert(!returnTypes_.empty());
+assert(returnTypes_.top() == decl->getReturnType());
+returnTypes_.pop();
+return ret;
+}
+#endif
+
+bool TraverseCXXMethodDecl(CXXMethodDecl * decl) {
+returnTypes_.push(decl->getReturnType());
+auto const ret = RecursiveASTVisitor::TraverseCXXMethodDecl(decl);
+assert(!returnTypes_.empty());
+assert(returnTypes_.top() == decl->getReturnType());
+returnTypes_.pop();
+return ret;
+}
+
+bool TraverseCXXConstructorDecl(CXXConstructorDecl * decl) {
+

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2017-06-19 Thread Noel Grandin
 compilerplugins/clang/plugin.cxx |5 +
 compilerplugins/clang/plugin.hxx |2 
 compilerplugins/clang/pluginhandler.cxx  |   16 --
 compilerplugins/clang/pluginhandler.hxx  |2 
 compilerplugins/clang/test/unusedfields.cxx  |   28 ++
 compilerplugins/clang/unusedfields.cxx   |   70 ---
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 7 files changed, 102 insertions(+), 22 deletions(-)

New commits:
commit 3b60f59bc55824e247f6e751a9c8f5d253665f0b
Author: Noel Grandin 
Date:   Mon Jun 19 13:44:14 2017 +0200

loplugin:unusedfields fix false positive

When the field in question is read from inside a constructor
initializer.

In the process, create some needed infrastructure in the plugin classes.

Change-Id: I2f440efa6912801a236727c9fe3180404616958c
Reviewed-on: https://gerrit.libreoffice.org/38960
Tested-by: Jenkins 
Reviewed-by: Noel Grandin 

diff --git a/compilerplugins/clang/plugin.cxx b/compilerplugins/clang/plugin.cxx
index 3ec612ef..ea646d29da89 100644
--- a/compilerplugins/clang/plugin.cxx
+++ b/compilerplugins/clang/plugin.cxx
@@ -265,6 +265,11 @@ SourceLocation Plugin::locationAfterToken( SourceLocation 
location )
 return Lexer::getLocForEndOfToken( location, 0, 
compiler.getSourceManager(), compiler.getLangOpts());
 }
 
+bool Plugin::isUnitTestMode()
+{
+return PluginHandler::isUnitTestMode();
+}
+
 RewritePlugin::RewritePlugin( const InstantiationData& data )
 : Plugin( data )
 , rewriter( data.rewriter )
diff --git a/compilerplugins/clang/plugin.hxx b/compilerplugins/clang/plugin.hxx
index 413b2ab7cefb..5651b2ff02ca 100644
--- a/compilerplugins/clang/plugin.hxx
+++ b/compilerplugins/clang/plugin.hxx
@@ -78,6 +78,8 @@ class Plugin
 bool isInUnoIncludeFile(const FunctionDecl*) const;
 
 static void normalizeDotDotInFilePath(std::string&);
+
+static bool isUnitTestMode();
 private:
 static void registerPlugin( Plugin* (*create)( const 
InstantiationData& ), const char* optionName, bool isPPCallback, bool byDefault 
);
 template< typename T > static Plugin* createHelper( const 
InstantiationData& data );
diff --git a/compilerplugins/clang/pluginhandler.cxx 
b/compilerplugins/clang/pluginhandler.cxx
index ad043e87e58d..7c42d14f3056 100644
--- a/compilerplugins/clang/pluginhandler.cxx
+++ b/compilerplugins/clang/pluginhandler.cxx
@@ -56,13 +56,13 @@ const int MAX_PLUGINS = 100;
 static PluginData plugins[ MAX_PLUGINS ];
 static int pluginCount = 0;
 static bool bPluginObjectsCreated = false;
+static bool unitTestMode = false;
 
 PluginHandler::PluginHandler( CompilerInstance& compiler, const vector< string 
>& args )
 : compiler( compiler )
 , rewriter( compiler.getSourceManager(), compiler.getLangOpts())
 , scope( "mainfile" )
 , warningsAsErrors( false )
-, unitTestMode( false )
 {
 set< string > rewriters;
 for( string const & arg : args )
@@ -89,6 +89,11 @@ PluginHandler::~PluginHandler()
 }
 }
 
+bool PluginHandler::isUnitTestMode()
+{
+return unitTestMode;
+}
+
 void PluginHandler::handleOption( const string& option )
 {
 if( option.substr( 0, 6 ) == "scope=" )
@@ -121,10 +126,13 @@ void PluginHandler::createPlugins( set< string > 
rewriters )
  i < pluginCount;
  ++i )
 {
-if( rewriters.erase( plugins[i].optionName ) != 0 )
-plugins[ i ].object = plugins[ i ].create( 
Plugin::InstantiationData { plugins[ i ].optionName, *this, compiler,  
} );
+const char* name = plugins[i].optionName;
+if( rewriters.erase( name ) != 0 )
+plugins[ i ].object = plugins[ i ].create( 
Plugin::InstantiationData { name, *this, compiler,  } );
 else if( plugins[ i ].byDefault )
-plugins[ i ].object = plugins[ i ].create( 
Plugin::InstantiationData { plugins[ i ].optionName, *this, compiler, NULL } );
+plugins[ i ].object = plugins[ i ].create( 
Plugin::InstantiationData { name, *this, compiler, NULL } );
+else if( unitTestMode && strcmp(name, "unusedmethodsremove") != 0 && 
strcmp(name, "unusedfieldsremove") != 0)
+plugins[ i ].object = plugins[ i ].create( 
Plugin::InstantiationData { name, *this, compiler, NULL } );
 }
 for( auto r: rewriters )
 report( DiagnosticsEngine::Fatal, "unknown plugin tool %0" ) << r;
diff --git a/compilerplugins/clang/pluginhandler.hxx 
b/compilerplugins/clang/pluginhandler.hxx
index a2cc136f5751..222cb258e80f 100644
--- a/compilerplugins/clang/pluginhandler.hxx
+++ b/compilerplugins/clang/pluginhandler.hxx
@@ -37,6 +37,7 @@ class PluginHandler
 DiagnosticBuilder report( DiagnosticsEngine::Level level, const char * 
plugin, StringRef message,
 CompilerInstance& compiler, 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2017-06-13 Thread Stephan Bergmann
 compilerplugins/clang/redundantcopy.cxx  |   14 +-
 compilerplugins/clang/test/redundantcopy.cxx |   10 +++---
 solenv/CompilerTest_compilerplugins_clang.mk |2 +-
 3 files changed, 17 insertions(+), 9 deletions(-)

New commits:
commit 423dacde87cbb3cba466c9701ed10dadc2b8b4e0
Author: Stephan Bergmann 
Date:   Tue Jun 13 17:00:30 2017 +0200

Generalize loplugin:stringcopy to loplugin:redundantcopy

(such redundant std::unique_ptr copies could happen when changing parts of 
the
code base to make use of std::unique_ptr individually)

Change-Id: Ib48a45a212f9426a775c7f379bc5d3c92230218a

diff --git a/compilerplugins/clang/stringcopy.cxx 
b/compilerplugins/clang/redundantcopy.cxx
similarity index 78%
rename from compilerplugins/clang/stringcopy.cxx
rename to compilerplugins/clang/redundantcopy.cxx
index b1d8e22216ec..18190f1eb0e4 100644
--- a/compilerplugins/clang/stringcopy.cxx
+++ b/compilerplugins/clang/redundantcopy.cxx
@@ -25,10 +25,14 @@ public:
 }
 auto const t1 = expr->getTypeAsWritten();
 auto const t2 = compat::getSubExprAsWritten(expr)->getType();
-if ((t1.getCanonicalType().getTypePtr()
- != t2.getCanonicalType().getTypePtr())
-|| !(loplugin::TypeCheck(t1).Class("OUString").Namespace("rtl")
- .GlobalNamespace()))
+if (t1.getCanonicalType().getTypePtr()
+!= t2.getCanonicalType().getTypePtr())
+{
+return true;
+}
+auto tc = loplugin::TypeCheck(t1);
+if (!(tc.Class("OUString").Namespace("rtl").GlobalNamespace()
+  || tc.Class("unique_ptr").StdNamespace()))
 {
 return true;
 }
@@ -47,7 +51,7 @@ private:
 }
 };
 
-static loplugin::Plugin::Registration reg("stringcopy");
+static loplugin::Plugin::Registration reg("redundantcopy");
 
 }
 
diff --git a/compilerplugins/clang/test/stringcopy.cxx 
b/compilerplugins/clang/test/redundantcopy.cxx
similarity index 68%
rename from compilerplugins/clang/test/stringcopy.cxx
rename to compilerplugins/clang/test/redundantcopy.cxx
index c801b7096f74..24207a60be69 100644
--- a/compilerplugins/clang/test/stringcopy.cxx
+++ b/compilerplugins/clang/test/redundantcopy.cxx
@@ -9,15 +9,19 @@
 
 #include "sal/config.h"
 
+#include 
+
 #include "rtl/ustring.hxx"
 
 int main() {
 OUString s;
-(void) OUString(s); // expected-error {{redundant copy construction from 
'rtl::OUString' to 'rtl::OUString' [loplugin:stringcopy]}}
+(void) OUString(s); // expected-error {{redundant copy construction from 
'rtl::OUString' to 'rtl::OUString' [loplugin:redundantcopy]}}
 using T1 = OUString;
-(void) T1(s); // expected-error {{redundant copy construction from 
'rtl::OUString' to 'T1' (aka 'rtl::OUString') [loplugin:stringcopy]}}
+(void) T1(s); // expected-error {{redundant copy construction from 
'rtl::OUString' to 'T1' (aka 'rtl::OUString') [loplugin:redundantcopy]}}
 using T2 = OUString const;
-(void) T2(s); // expected-error {{redundant copy construction from 
'rtl::OUString' to 'T2' (aka 'const rtl::OUString') [loplugin:stringcopy]}}
+(void) T2(s); // expected-error {{redundant copy construction from 
'rtl::OUString' to 'T2' (aka 'const rtl::OUString') [loplugin:redundantcopy]}}
+
+(void) std::unique_ptr(std::unique_ptr(new int{})); // 
expected-error {{redundant copy construction from 'std::unique_ptr' to 
'std::unique_ptr' [loplugin:redundantcopy]}}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index d85ba6d9f58e..4e65a684efd4 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -20,11 +20,11 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/oslendian-2 \
 compilerplugins/clang/test/oslendian-3 \
 compilerplugins/clang/test/redundantcast \
+compilerplugins/clang/test/redundantcopy \
 compilerplugins/clang/test/redundantinline \
 compilerplugins/clang/test/salbool \
 compilerplugins/clang/test/salunicodeliteral \
 compilerplugins/clang/test/stringconstant \
-compilerplugins/clang/test/stringcopy \
 compilerplugins/clang/test/unnecessaryoverride-dtor \
 compilerplugins/clang/test/unoany \
 compilerplugins/clang/test/useuniqueptr \
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk solenv/gbuild

2017-04-28 Thread Stephan Bergmann
 compilerplugins/clang/cppunitassertequals.cxx  |  142 ++---
 compilerplugins/clang/test/cppunitassertequals.cxx |   56 
 compilerplugins/clang/test/cppunitassertequals.hxx |   23 +++
 solenv/CompilerTest_compilerplugins_clang.mk   |5 
 solenv/gbuild/CompilerTest.mk  |1 
 5 files changed, 183 insertions(+), 44 deletions(-)

New commits:
commit a528392e71bc70136021be4e3d83732fccbb885e
Author: Stephan Bergmann 
Date:   Fri Apr 28 14:23:35 2017 +0200

Fixed/improved loplugin:cppunitassertequals

* 994e38e336beeacbd983faafac480afc94d3947e "loplugin: use TypeCheck instead 
of
  getQualifiedNameAsString" had effectively disabled this plugin (Asserter 
is a
  struct, not a namespace).  Fixed that.

* Also improved the checks, for one removing the---expensive---use of
  Plugin::parentStmt, for another making the plugin look into (...), !..., 
and
  ...&&... expressions.

* However, as the plugin had effectively already been disabled (see above) 
when
  it was switched on generally with 839e53b933322b739a7f534af58c63a2c69af7bd
  "compilerplugins: enable loplugin:cppunitassertequals by default", it now 
hit
  way more places than I had initially anticipated.  To keep the amount of 
work
  manageable, midway-through I disabled looking into ...&&... expressions 
for
  now.  That will be enabled (and resulting warnings fixed) in follow-up
  commits.

* Checks like

CPPUNIT_ASSERT(a == b)

  that actually want to check a specific overloaded operator == 
implementation,
  rather than using such an operator == to actually check that a and b are
  equal, can be rewritten as

CPPUNIT_ASSERT(operator ==(a, b))

  to avoid false warnings from this plugin.

Change-Id: If3501020e2d150ad0f2454a65a39081e31470c0f

diff --git a/compilerplugins/clang/cppunitassertequals.cxx 
b/compilerplugins/clang/cppunitassertequals.cxx
index 858ad9615cbe..37dff6acca97 100644
--- a/compilerplugins/clang/cppunitassertequals.cxx
+++ b/compilerplugins/clang/cppunitassertequals.cxx
@@ -7,11 +7,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-#include 
-#include 
-#include 
-#include 
-#include 
 #include "plugin.hxx"
 #include "check.hxx"
 
@@ -29,74 +24,133 @@ public:
 
 virtual void run() override
 {
-TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+if (compiler.getLangOpts().CPlusPlus) {
+TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+}
 }
 
 bool VisitCallExpr(const CallExpr*);
-bool VisitBinaryOperator(const BinaryOperator*);
+
 private:
-void checkExpr(const Stmt* stmt);
+void checkExpr(
+SourceRange range, StringRef name, Expr const * expr, bool negated);
+
+void reportEquals(SourceRange range, StringRef name, bool negative);
 };
 
 bool CppunitAssertEquals::VisitCallExpr(const CallExpr* callExpr)
 {
-if (ignoreLocation(callExpr)) {
+auto const decl = callExpr->getDirectCallee();
+if (decl == nullptr
+|| !(loplugin::DeclCheck(decl).Function("failIf").Struct("Asserter")
+ .Namespace("CppUnit").GlobalNamespace()))
+{
 return true;
 }
-if (callExpr->getDirectCallee() == nullptr) {
+// Don't use callExpr->getLocStart() or callExpr->getExprLoc(), as those
+// fall into a nested use of the CPPUNIT_NS macro; CallExpr::getRParenLoc
+// happens to be readily available and cause good results:
+auto loc = callExpr->getRParenLoc();
+while (compiler.getSourceManager().isMacroArgExpansion(loc)) {
+loc = compiler.getSourceManager().getImmediateMacroCallerLoc(loc);
+}
+if (!compiler.getSourceManager().isMacroBodyExpansion(loc)
+|| ignoreLocation(
+compiler.getSourceManager().getImmediateMacroCallerLoc(loc)))
+{
 return true;
 }
-const FunctionDecl* functionDecl = 
callExpr->getDirectCallee()->getCanonicalDecl();
-if (functionDecl->getOverloadedOperator() != OO_EqualEqual) {
+auto name = Lexer::getImmediateMacroName(
+loc, compiler.getSourceManager(), compiler.getLangOpts());
+if (name != "CPPUNIT_ASSERT" && name != "CPPUNIT_ASSERT_MESSAGE") {
 return true;
 }
-checkExpr(callExpr);
-return true;
-}
-
-bool CppunitAssertEquals::VisitBinaryOperator(const BinaryOperator* binaryOp)
-{
-if (ignoreLocation(binaryOp)) {
+if (decl->getNumParams() != 3) {
+report(
+DiagnosticsEngine::Warning,
+("TODO: suspicious CppUnit::Asserter::failIf call with %0"
+ " parameters"),
+callExpr->getExprLoc())
+<< decl->getNumParams() << callExpr->getSourceRange();
 return true;
 }
-if (binaryOp->getOpcode() != BO_EQ) {
+auto const e1 = callExpr->getArg(0)->IgnoreParenImpCasts();
+   

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk svtools/source svx/source sw/source

2017-03-25 Thread Stephan Bergmann
 compilerplugins/clang/loopvartoosmall.cxx  |  239 ++---
 compilerplugins/clang/test/loopvartoosmall.cxx |   24 ++
 solenv/CompilerTest_compilerplugins_clang.mk   |1 
 svtools/source/brwbox/brwbox2.cxx  |4 
 svx/source/fmcomp/gridctrl.cxx |2 
 sw/source/core/frmedt/fetab.cxx|2 
 sw/source/core/text/itrpaint.cxx   |2 
 sw/source/filter/ww8/ww8par6.cxx   |2 
 sw/source/filter/ww8/ww8scan.cxx   |2 
 9 files changed, 207 insertions(+), 71 deletions(-)

New commits:
commit 2258f33a5fd95a5e25f5bb232994ab147d09bfb9
Author: Stephan Bergmann 
Date:   Sat Mar 25 10:55:44 2017 +0100

Make loplugin:loopvartoosmall find more suspicious cases

...where the "controlling expression" of any sort of loop contains a sub-
expression of the form

  var < val

where the type of var is smaller than that of val.  Theoretically, this 
could
turn up lots of false positives, but practically it didn't run into any.  
Most
findings have been cleaned up over the last weeks.  There's just a handful
remaining places that are hard to clean up, so I flagged them here with
(deliberately awkward) sal::static_int_cast for later clean-up.

Change-Id: I0f735d46dda15b9b336150095df65cf247e9d6d3
Reviewed-on: https://gerrit.libreoffice.org/35682
Reviewed-by: Stephan Bergmann 
Tested-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/loopvartoosmall.cxx 
b/compilerplugins/clang/loopvartoosmall.cxx
index aaa664827298..eb4cb96d592d 100644
--- a/compilerplugins/clang/loopvartoosmall.cxx
+++ b/compilerplugins/clang/loopvartoosmall.cxx
@@ -7,11 +7,13 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-#include 
-#include 
+#include 
+#include 
+#include 
+#include 
 
 #include "plugin.hxx"
-#include "clang/AST/CXXInheritance.h"
+//#include "clang/AST/CXXInheritance.h"
 
 // Idea from bubli. Check that the index variable in a for loop is able to 
cover the range
 // revealed by the terminating condition.
@@ -30,86 +32,195 @@ public:
 TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
 }
 
-bool VisitForStmt( const ForStmt* stmt );
+bool VisitForStmt( const ForStmt* stmt ) {
+checkExpr(stmt->getCond());
+return true;
+}
+
+bool VisitWhileStmt(WhileStmt const * stmt) {
+checkExpr(stmt->getCond());
+return true;
+}
+
+bool VisitDoStmt(DoStmt const * stmt) {
+checkExpr(stmt->getCond());
+return true;
+}
 
 private:
-StringRef getFilename(SourceLocation loc);
+unsigned getIntValueWidth(QualType type) const;
+
+void checkSubExpr(Expr const * expr, bool positive);
+
+void checkExpr(Expr const * expr);
+
+struct Comparison {
+BinaryOperator const * op;
+unsigned rhsWidth;
+};
 
+struct Comparisons {
+std::list comparisons;
+unsigned lhsWidth;
+};
+
+std::map comparisons_;
 };
 
-StringRef LoopVarTooSmall::getFilename(SourceLocation loc)
-{
-SourceLocation spellingLocation = 
compiler.getSourceManager().getSpellingLoc(loc);
-StringRef name { compiler.getSourceManager().getFilename(spellingLocation) 
};
-return name;
+unsigned LoopVarTooSmall::getIntValueWidth(QualType type) const {
+if (auto const et = type->getAs()) {
+auto const ed = et->getDecl();
+if (!ed->isFixed()) {
+unsigned pos = ed->getNumPositiveBits();
+unsigned neg = ed->getNumNegativeBits();
+return neg == 0 ? std::max(pos, 1U) : std::max(pos + 1, neg);
+}
+}
+return compiler.getASTContext().getIntWidth(type);
 }
 
-bool LoopVarTooSmall::VisitForStmt( const ForStmt* stmt )
-{
-if (ignoreLocation( stmt ))
-return true;
-// ignore sal/ module for now
-StringRef aFileName = getFilename(stmt->getLocStart());
-if (aFileName.startswith(SRCDIR "/sal/")) {
-return true;
+void LoopVarTooSmall::checkSubExpr(Expr const * expr, bool positive) {
+auto const e = expr->IgnoreParenImpCasts();
+if (auto const uo = dyn_cast(e)) {
+if (uo->getOpcode() == UO_LNot) {
+checkSubExpr(uo->getSubExpr(), !positive);
+}
+return;
 }
-
-const Stmt* initStmt = stmt->getInit();
-if (!initStmt || !isa(initStmt))
-return true;
-const DeclStmt* declStmt = dyn_cast(initStmt);
-if (!declStmt->getDeclGroup().isSingleDecl())
-return true;
-const Decl* decl = declStmt->getSingleDecl();
-if (!decl || !isa(decl))
-return true;
-const VarDecl* varDecl = dyn_cast(decl);
-QualType qt = varDecl->getType();
-if (!qt->isIntegralType(compiler.getASTContext()))
-return true;
-uint64_t qt1BitWidth = compiler.getASTContext().getTypeSize(qt);
-
-if 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2017-03-25 Thread Stephan Bergmann
 compilerplugins/clang/redundantinline.cxx  |  127 +
 compilerplugins/clang/test/redundantinline.cxx |   14 ++
 compilerplugins/clang/test/redundantinline.hxx |   79 +++
 solenv/CompilerTest_compilerplugins_clang.mk   |1 
 4 files changed, 221 insertions(+)

New commits:
commit 5d8e6901ec14edd9da10d9dee63b2ef2ab058692
Author: Stephan Bergmann 
Date:   Sat Mar 25 10:47:34 2017 +0100

Add loplugin:redundantinline

...after it had recently been run with 
6cb9e6dad798ec59f055aebe84a9c4a21e4be40d
"Remove redundant 'inline' keyword"

Change-Id: I7f3ee2ff1c32988dcff7245c64b50fe20b0a5e79
Reviewed-on: https://gerrit.libreoffice.org/35681
Reviewed-by: Stephan Bergmann 
Tested-by: Stephan Bergmann 

diff --git a/compilerplugins/clang/redundantinline.cxx 
b/compilerplugins/clang/redundantinline.cxx
new file mode 100644
index ..88c870d75465
--- /dev/null
+++ b/compilerplugins/clang/redundantinline.cxx
@@ -0,0 +1,127 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+
+#include "plugin.hxx"
+
+namespace {
+
+class Visitor:
+public RecursiveASTVisitor, public loplugin::RewritePlugin
+{
+public:
+explicit Visitor(InstantiationData const & data): RewritePlugin(data) {}
+
+void run() override {
+if (compiler.getLangOpts().CPlusPlus) {
+TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+}
+}
+
+bool VisitFunctionDecl(FunctionDecl const * decl) {
+if (ignoreLocation(decl) || !decl->isInlineSpecified()
+|| !(decl->doesThisDeclarationHaveABody()
+ || decl->isExplicitlyDefaulted())
+|| !(decl->getLexicalDeclContext()->isRecord()
+ || decl->isConstexpr()))
+{
+return true;
+}
+auto l1 = unwindToQObject(decl->getLocStart());
+if (l1.isValid() && l1 == unwindToQObject(decl->getLocEnd())) {
+return true;
+}
+SourceLocation inlineLoc;
+unsigned n;
+auto end = Lexer::getLocForEndOfToken(
+compiler.getSourceManager().getExpansionLoc(decl->getLocEnd()), 0,
+compiler.getSourceManager(), compiler.getLangOpts());
+assert(end.isValid());
+for (auto loc = compiler.getSourceManager().getExpansionLoc(
+ decl->getLocStart());
+ loc != end; loc = loc.getLocWithOffset(std::max(n, 1)))
+{
+n = Lexer::MeasureTokenLength(
+loc, compiler.getSourceManager(), compiler.getLangOpts());
+StringRef s(compiler.getSourceManager().getCharacterData(loc), n);
+//TODO: see compilerplugins/clang/override.cxx:
+if (s.startswith("\\\n")) {
+s = s.drop_front(2);
+}
+if (s == "inline") {
+if (!compiler.getSourceManager().isMacroArgExpansion(loc)) {
+inlineLoc = loc;
+}
+break;
+} else if (s == "#") {
+// Hard to pick the right 'inline' in code like
+//
+//   #if 1
+// static
+//   #else
+// inline
+//   #endif
+//   inline void f() {}
+//
+// so just give up once a preprocessing directive is seen:
+break;
+}
+}
+if (rewriter != nullptr && inlineLoc.isValid()) {
+for (auto loc = inlineLoc.getLocWithOffset(
+ std::max(n, 1));;)
+{
+assert(loc != end);
+unsigned n2 = Lexer::MeasureTokenLength(
+loc, compiler.getSourceManager(), compiler.getLangOpts());
+StringRef s(
+compiler.getSourceManager().getCharacterData(loc), n2);
+//TODO: see compilerplugins/clang/override.cxx:
+if (s.startswith("\\\n")) {
+s = s.drop_front(2);
+}
+if (!s.empty()) {
+break;
+}
+n2 = std::max(n2, 1);
+n += n2;
+loc = loc.getLocWithOffset(n2);
+}
+if (removeText(inlineLoc, n, RewriteOptions(RemoveLineIfEmpty))) {
+return true;
+}
+}
+report(
+DiagnosticsEngine::Warning,
+"function definition redundantly declared 'inline'",
+inlineLoc.isValid() ? 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2017-02-16 Thread Stephan Bergmann
 compilerplugins/clang/test/redundantcast.cxx |   32 +++
 solenv/CompilerTest_compilerplugins_clang.mk |1 
 2 files changed, 33 insertions(+)

New commits:
commit 6d3db33328fb2fec3539c828d062cad6d16d3195
Author: Stephan Bergmann 
Date:   Thu Feb 16 17:36:21 2017 +0100

Capture loplugin:redundantcast status-quo wrt const_cast

...including some double-warnings that'll get cleaned up shortly

Change-Id: I14e9796f2846a6bb61e4c93dfb23cba6488ea2e6

diff --git a/compilerplugins/clang/test/redundantcast.cxx 
b/compilerplugins/clang/test/redundantcast.cxx
new file mode 100644
index 000..7af9716
--- /dev/null
+++ b/compilerplugins/clang/test/redundantcast.cxx
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+void f1(char *) {}
+void f2(char const *) {}
+
+int main() {
+char * p1;
+char const * p2;
+p1 = nullptr;
+p2 = "";
+f1(const_cast(p1)); // expected-error {{redundant const_cast from 
'char *' to 'char *' [loplugin:redundantcast]}}
+f1(const_cast(p1)); // expected-error {{redundant const_cast 
from 'char *' to 'char *const' [loplugin:redundantcast]}}
+f1(const_cast(p2));
+f1(const_cast(p2));
+f2(const_cast(p1)); // expected-error {{redundant const_cast from 
'char *' to 'char *', result is implictly cast to 'const char *' 
[loplugin:redundantcast]}} expected-error {{redundant const_cast from 'char *' 
to 'char *' [loplugin:redundantcast]}}
+f2(const_cast(p1)); // expected-error {{redundant const_cast 
from 'char *' to 'char *', result is implictly cast to 'const char *' 
[loplugin:redundantcast]}} expected-error {{redundant const_cast from 'char *' 
to 'char *const' [loplugin:redundantcast]}}
+f2(const_cast(p1));
+f2(const_cast(p1));
+f2(const_cast(p2)); // expected-error {{redundant const_cast from 
'const char *' to 'char *', result is implictly cast to 'const char *' 
[loplugin:redundantcast]}}
+f2(const_cast(p2)); // expected-error {{redundant const_cast 
from 'const char *' to 'char *', result is implictly cast to 'const char *' 
[loplugin:redundantcast]}}
+f2(const_cast(p2)); // expected-error {{redundant const_cast 
from 'const char *' to 'const char *' [loplugin:redundantcast]}}
+f2(const_cast(p2)); // expected-error {{redundant 
const_cast from 'const char *' to 'const char *const' [loplugin:redundantcast]}}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 7840b1e..85de035 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -17,6 +17,7 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
 compilerplugins/clang/test/oslendian-1 \
 compilerplugins/clang/test/oslendian-2 \
 compilerplugins/clang/test/oslendian-3 \
+compilerplugins/clang/test/redundantcast \
 compilerplugins/clang/test/salbool \
 compilerplugins/clang/test/stringconstant \
 compilerplugins/clang/test/unnecessaryoverride-dtor \
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2016-12-04 Thread Noel Grandin
 compilerplugins/clang/passstuffbyref.cxx  |   50 +++---
 compilerplugins/clang/test/passstuffbyref.cxx |   28 ++
 solenv/CompilerTest_compilerplugins_clang.mk  |1 
 3 files changed, 67 insertions(+), 12 deletions(-)

New commits:
commit 8cf59c674326d93de049ffe2c1d73d7f32e70d37
Author: Noel Grandin 
Date:   Fri Dec 2 17:03:37 2016 +0200

make passstuffbyref plugin ignore std::move'd params

request from vmiklos

Change-Id: If263beb0623d725e406003bb1660df10fe4b4e35
Reviewed-on: https://gerrit.libreoffice.org/31555
Tested-by: Jenkins 
Reviewed-by: Noel Grandin 

diff --git a/compilerplugins/clang/passstuffbyref.cxx 
b/compilerplugins/clang/passstuffbyref.cxx
index ad6c100..8695ae6 100644
--- a/compilerplugins/clang/passstuffbyref.cxx
+++ b/compilerplugins/clang/passstuffbyref.cxx
@@ -185,24 +185,50 @@ void PassStuffByRef::checkParams(const FunctionDecl * 
functionDecl) {
 if (!functionDecl->doesThisDeclarationHaveABody()) {
 return;
 }
+auto cxxConstructorDecl = dyn_cast(functionDecl);
 unsigned n = functionDecl->getNumParams();
 for (unsigned i = 0; i != n; ++i) {
 const ParmVarDecl * pvDecl = functionDecl->getParamDecl(i);
 auto const t = pvDecl->getType();
-if (isFat(t)) {
-report(
-DiagnosticsEngine::Warning,
-("passing %0 by value, rather pass by const lvalue reference"),
-pvDecl->getLocation())
-<< t << pvDecl->getSourceRange();
-auto can = functionDecl->getCanonicalDecl();
-if (can->getLocation() != functionDecl->getLocation()) {
-report(
-DiagnosticsEngine::Note, "function is declared here:",
-can->getLocation())
-<< can->getSourceRange();
+if (!isFat(t)) {
+continue;
+}
+// Ignore cases where the parameter is std::move'd.
+// This is a fairly simple check, might need some more complexity if 
the parameter is std::move'd
+// somewhere else in the constructor.
+bool bFoundMove = false;
+if (cxxConstructorDecl) {
+for (CXXCtorInitializer const * cxxCtorInitializer : 
cxxConstructorDecl->inits()) {
+if (cxxCtorInitializer->isMemberInitializer())
+{
+auto cxxConstructExpr = 
dyn_cast(cxxCtorInitializer->getInit());
+if (cxxConstructExpr && cxxConstructExpr->getNumArgs() == 
1)
+{
+if (auto callExpr = 
dyn_cast(cxxConstructExpr->getArg(0))) {
+if 
(loplugin::DeclCheck(callExpr->getCalleeDecl()).Function("move").StdNamespace())
 {
+bFoundMove = true;
+break;
+}
+}
+}
+}
 }
 }
+if (bFoundMove) {
+continue;
+}
+report(
+DiagnosticsEngine::Warning,
+("passing %0 by value, rather pass by const lvalue reference"),
+pvDecl->getLocation())
+<< t << pvDecl->getSourceRange();
+auto can = functionDecl->getCanonicalDecl();
+if (can->getLocation() != functionDecl->getLocation()) {
+report(
+DiagnosticsEngine::Note, "function is declared here:",
+can->getLocation())
+<< can->getSourceRange();
+}
 }
 // ignore stuff that forms part of the stable URE interface
 if (isInUnoIncludeFile(functionDecl)) {
diff --git a/compilerplugins/clang/test/passstuffbyref.cxx 
b/compilerplugins/clang/test/passstuffbyref.cxx
new file mode 100644
index 000..d19b139
--- /dev/null
+++ b/compilerplugins/clang/test/passstuffbyref.cxx
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+
+struct S {
+OUString mv;
+
+// request from vmiklos: make sure we ignore cases where the passed in 
parameter is std::move'd
+S(OUString v)
+  : mv(std::move(v)) {}
+};
+
+
+void f() // expected-error {{Unreferenced externally visible function 
definition [loplugin:unreffun]}}
+{
+S* s;
+OUString v;
+s = new S(v);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index 8bae924..dc3a67e 100644
--- 

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk

2016-11-22 Thread Stephan Bergmann
 compilerplugins/clang/oslendian.cxx  |  116 +++
 compilerplugins/clang/test/oslendian-1.cxx   |   47 ++
 compilerplugins/clang/test/oslendian-2.cxx   |   23 +
 compilerplugins/clang/test/oslendian-3.cxx   |   25 +
 solenv/CompilerTest_compilerplugins_clang.mk |3 
 5 files changed, 214 insertions(+)

New commits:
commit 0de1b34a89a5bafa87a031da7e53e902ec14312c
Author: Stephan Bergmann 
Date:   Tue Nov 22 10:54:25 2016 +0100

New loplugin:oslendian

...to catch new places where defined'ness of OSL_BIG/LITENDIAN would be 
checked
without osl/endian.h being included; cf.
e2f08f9def0869460ad38a1c2adb450778290f6e "connectivity, sc: add missing 
#include
" and 2b14fb3a4f92b928f0a5fc536c6a5f4a6e51a9b8 "cppcanvas, 
oox:
add missing #include ".

Change-Id: I167c8916a01391b7dacad7325153ccf35d3ba9dc

diff --git a/compilerplugins/clang/oslendian.cxx 
b/compilerplugins/clang/oslendian.cxx
new file mode 100644
index 000..99b2851
--- /dev/null
+++ b/compilerplugins/clang/oslendian.cxx
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+
+#include "compat.hxx"
+#include "plugin.hxx"
+
+namespace {
+
+class OslEndian: public loplugin::Plugin, public PPCallbacks {
+public:
+explicit OslEndian(InstantiationData const & data): Plugin(data) {
+compat::addPPCallbacks(compiler.getPreprocessor(), this);
+}
+
+enum { isPPCallback = true };
+
+private:
+void run() override {}
+
+void MacroDefined(Token const & MacroNameTok, MacroDirective const *)
+override
+{
+auto id = MacroNameTok.getIdentifierInfo()->getName();
+if (id == "OSL_BIGENDIAN") {
+if (definedLit_.isValid()) {
+report(
+DiagnosticsEngine::Warning,
+"macro %0 defined in addition to 'OSL_LITENDIAN'",
+MacroNameTok.getLocation())
+<< MacroNameTok.getIdentifierInfo();
+report(
+DiagnosticsEngine::Note,
+"conflicting macro definition is here", definedLit_);
+}
+definedBig_ = MacroNameTok.getLocation();
+assert(definedBig_.isValid());
+} else if (id == "OSL_LITENDIAN") {
+if (definedBig_.isValid()) {
+report(
+DiagnosticsEngine::Warning,
+"macro %0 defined in addition to 'OSL_BIGENDIAN'",
+MacroNameTok.getLocation())
+<< MacroNameTok.getIdentifierInfo();
+report(
+DiagnosticsEngine::Note,
+"conflicting macro definition is here", definedBig_);
+}
+definedLit_ = MacroNameTok.getLocation();
+assert(definedLit_.isValid());
+}
+}
+
+void MacroUndefined(Token const & MacroNameTok, MacroDefinition const &)
+override
+{
+auto id = MacroNameTok.getIdentifierInfo()->getName();
+if (id == "OSL_BIGENDIAN" || id == "OSL_LITENDIAN") {
+report(
+DiagnosticsEngine::Warning, "macro %0 undefinition",
+MacroNameTok.getLocation())
+<< MacroNameTok.getIdentifierInfo();
+}
+}
+
+void Defined(
+Token const & MacroNameTok, MacroDefinition const &, SourceRange)
+override
+{
+check(MacroNameTok);
+}
+
+void Ifdef(
+SourceLocation, Token const & MacroNameTok, MacroDefinition const &)
+override
+{
+check(MacroNameTok);
+}
+
+void Ifndef(
+SourceLocation, Token const & MacroNameTok, MacroDefinition const &)
+override
+{
+check(MacroNameTok);
+}
+
+void check(Token const & macro) const {
+auto id = macro.getIdentifierInfo()->getName();
+if ((id == "OSL_BIGENDIAN" || id == "OSL_LITENDIAN")
+&& definedBig_.isInvalid() && definedLit_.isInvalid())
+{
+report(
+DiagnosticsEngine::Warning,
+"definition of macro %0 checked but 'osl/endian.h' is not"
+" included",
+macro.getLocation())
+<< macro.getIdentifierInfo();
+}
+}
+
+SourceLocation definedBig_;
+SourceLocation definedLit_;
+};
+
+loplugin::Plugin::Registration X("oslendian");
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/compilerplugins/clang/test/oslendian-1.cxx 
b/compilerplugins/clang/test/oslendian-1.cxx

[Libreoffice-commits] core.git: compilerplugins/clang solenv/CompilerTest_compilerplugins_clang.mk solenv/gbuild solenv/Module_solenv.mk

2016-11-15 Thread Stephan Bergmann
 compilerplugins/clang/test/salbool.cxx   |   18 ++
 solenv/CompilerTest_compilerplugins_clang.mk |   16 +
 solenv/Module_solenv.mk  |6 +++
 solenv/gbuild/CompilerTest.mk|   46 +++
 solenv/gbuild/LinkTarget.mk  |9 ++---
 solenv/gbuild/TargetLocations.mk |   13 +++
 solenv/gbuild/gbuild.mk  |1 
 solenv/gbuild/platform/com_GCC_class.mk  |5 +-
 solenv/gbuild/platform/com_GCC_defs.mk   |2 -
 9 files changed, 109 insertions(+), 7 deletions(-)

New commits:
commit 645583dfd374c8b02f3c0eeba6233a0bb5884d68
Author: Stephan Bergmann 
Date:   Mon Nov 14 23:35:19 2016 +0100

New compilerplugins/clang unit tests

...to check that loplugin produces warnings/errors as expected:

* Clang has a -verify switch that makes it easy to write test input .cxx 
files
  that list in comments all the warnings/errors that are expected, and let 
Clang
  check those expectations instead of generating object code.  See
  include/clang/Frontend/VerifyDiagnosticConsumer.h in the Clang source 
tree for
  documentation.

* Introduce a CompilerTest gbuild class that uses the existing LinkTarget 
class
  as much as possible.  Checking the input files is implicitly phony, as the
  compilation step doesn't generate any object files, and the link step does
  nothing because there is no gb_LinkTarget_set_targettype for CompilerTest.
  The setup at least works for Clang on Linux (will need adaptions for 
Clang on
  Windows; compilers other than Clang are not relevant for now given this is
  used to check compilerplugins).

* Definition of gb_CFLAGS_WERROR in solenv/gbuild/platform/com_GCC_defs.mk 
needs
  to be lazy ('=' vs. ':=') so that CompilerTest can override it:  The Clang
  -verify mode wants the input files to specify whether the loplugin 
diagnostics
  are warnings or errros, so they consistently need to be errors 
independent of
  --enable-werror configuration.

* A first (example) test is in compilerplugins/clang/test/salbool.cxx.  The
  corresponding gbuild CompilerTest instance is in
  solenv/CompilerTest_compilerplugins_clang.mk for now.  The reason for 
that odd
  split across compilerplugins/ and solenv/ is that there is no
  compilerplugins/Modules_compilerplugins.mk file, so this setup is the 
easiest
  hack for now (to be cleaned up).  (Another area that could be improved is 
that
  all test files need to be listed explicitly in the CompilerTest_*.mk file,
  instead of, say, using all .c/.cxx/.m/.mm files in a specified directory.)

* The test is run somewhat late during a top-level 'make', after loplugin 
has
  already been used in compilation.  But it can be run manually (e.g., 'make
  solenv') when making changes to loplugin during development.

Change-Id: I01e12fb84887d264ac03ef2484807458c2075af4

diff --git a/compilerplugins/clang/test/salbool.cxx 
b/compilerplugins/clang/test/salbool.cxx
new file mode 100644
index 000..da861af
--- /dev/null
+++ b/compilerplugins/clang/test/salbool.cxx
@@ -0,0 +1,18 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include 
+
+#include 
+
+struct S {
+sal_Bool b; // expected-error {{FieldDecl, use "bool" instead of 
"sal_Bool" [loplugin:salbool]}}
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
new file mode 100644
index 000..29fb11a
--- /dev/null
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 
100 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_CompilerTest_CompilerTest,compilerplugins_clang))
+
+$(eval $(call gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
+compilerplugins/clang/test/salbool \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/Module_solenv.mk b/solenv/Module_solenv.mk
index 229ee58..127007e 100644
--- a/solenv/Module_solenv.mk
+++ b/solenv/Module_solenv.mk
@@ -33,4 +33,10 @@ endif
 endif
 endif
 
+ifneq ($(COMPILER_PLUGINS),)
+$(eval $(call gb_Module_add_check_targets,solenv, \
+