[Libreoffice-commits] core.git: basegfx/source basegfx/test chart2/source compilerplugins/clang desktop/source drawinglayer/source emfio/source filter/source i18nlangtag/source i18npool/source registry/source sal/osl sc/source sd/source sfx2/source solenv/CompilerTest_compilerplugins_clang.mk sot/source svgio/source svtools/source svx/source sw/source vcl/qa vcl/source vcl/unx

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Mar 8 06:20:58 UTC 2019


 basegfx/source/curve/b2dcubicbezier.cxx                     |    2 
 basegfx/source/raster/rasterconvert3d.cxx                   |    3 
 basegfx/test/B2DHomMatrixTest.cxx                           |    8 
 chart2/source/view/axes/VCartesianAxis.cxx                  |    2 
 compilerplugins/clang/constvars.cxx                         |  509 ++++++++++++
 compilerplugins/clang/test/constvars.cxx                    |   49 +
 desktop/source/app/app.cxx                                  |    2 
 drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx |    4 
 drawinglayer/source/primitive2d/polygonprimitive2d.cxx      |    5 
 drawinglayer/source/primitive2d/sceneprimitive2d.cxx        |    4 
 drawinglayer/source/processor2d/vclhelperbufferdevice.cxx   |    2 
 drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx  |    8 
 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx     |  199 +---
 drawinglayer/source/processor3d/defaultprocessor3d.cxx      |   17 
 drawinglayer/source/tools/converters.cxx                    |    2 
 emfio/source/reader/emfreader.cxx                           |    2 
 filter/source/config/cache/typedetection.cxx                |   15 
 filter/source/msfilter/msdffimp.cxx                         |    2 
 i18nlangtag/source/isolang/isolang.cxx                      |    2 
 i18npool/source/nativenumber/nativenumbersupplier.cxx       |    2 
 registry/source/reflwrit.cxx                                |    2 
 sal/osl/unx/thread.cxx                                      |    2 
 sc/source/core/tool/interpr5.cxx                            |    2 
 sc/source/core/tool/scmatrix.cxx                            |    2 
 sc/source/core/tool/token.cxx                               |    2 
 sd/source/ui/func/futext.cxx                                |    5 
 sfx2/source/appl/newhelp.cxx                                |    2 
 sfx2/source/appl/shutdownicon.cxx                           |    2 
 sfx2/source/sidebar/Paint.cxx                               |    2 
 solenv/CompilerTest_compilerplugins_clang.mk                |    1 
 sot/source/sdstor/stg.cxx                                   |    2 
 svgio/source/svgreader/svgdocumenthandler.cxx               |    2 
 svtools/source/contnr/imivctl1.cxx                          |    4 
 svx/source/sdr/contact/objectcontactofpageview.cxx          |   11 
 svx/source/sdr/contact/viewcontactofsdrpage.cxx             |    2 
 svx/source/sdr/overlay/overlaymanager.cxx                   |   13 
 svx/source/sdr/overlay/overlaymanagerbuffered.cxx           |   12 
 svx/source/sdr/primitive2d/sdrole2primitive2d.cxx           |   13 
 svx/source/svdraw/sdrpaintwindow.cxx                        |   17 
 svx/source/svdraw/svdedtv2.cxx                              |   10 
 svx/source/svdraw/svdotextdecomposition.cxx                 |    3 
 svx/source/svdraw/svdpntv.cxx                               |   31 
 sw/source/core/crsr/paminit.cxx                             |    4 
 sw/source/core/doc/docredln.cxx                             |    2 
 sw/source/core/layout/flylay.cxx                            |    2 
 sw/source/core/ole/ndole.cxx                                |    2 
 sw/source/core/text/txtpaint.cxx                            |    8 
 sw/source/ui/dbui/dbinsdlg.cxx                              |   30 
 vcl/qa/cppunit/svm/svmtest.cxx                              |    2 
 vcl/source/filter/png/pngread.cxx                           |    7 
 vcl/source/outdev/bitmap.cxx                                |   10 
 vcl/source/window/layout.cxx                                |    4 
 vcl/unx/generic/app/wmadaptor.cxx                           |   15 
 53 files changed, 703 insertions(+), 364 deletions(-)

New commits:
commit 5c23459245f566831383934dd64d19e002bfcfcb
Author:     Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Wed Mar 6 11:05:49 2019 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Fri Mar 8 07:20:29 2019 +0100

    new loplugin constvars
    
    detect static variables that can be made const.
    
    Thanks to mike kaganski for suggesting this.
    
    Here I introduce a new plugin feature - using markers
    in nearby comments to disable the plugin for specific
    vars.
    
    Some of this stuff was old debugging code. I removed the stuff
    that was older than 5 years.
    
    Change-Id: I6ec7742a7fdadf28fd128b592fcdf6da8257585c
    Reviewed-on: https://gerrit.libreoffice.org/68807
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/basegfx/source/curve/b2dcubicbezier.cxx b/basegfx/source/curve/b2dcubicbezier.cxx
index 9584eeded3c0..e1fad1e8a552 100644
--- a/basegfx/source/curve/b2dcubicbezier.cxx
+++ b/basegfx/source/curve/b2dcubicbezier.cxx
@@ -30,7 +30,7 @@
 // #i37443#
 #define FACTOR_FOR_UNSHARPEN    (1.6)
 #ifdef DBG_UTIL
-static double fMultFactUnsharpen = FACTOR_FOR_UNSHARPEN;
+static const double fMultFactUnsharpen = FACTOR_FOR_UNSHARPEN;
 #endif
 
 namespace basegfx
diff --git a/basegfx/source/raster/rasterconvert3d.cxx b/basegfx/source/raster/rasterconvert3d.cxx
index d6169b7ad9fe..2e654831c5f3 100644
--- a/basegfx/source/raster/rasterconvert3d.cxx
+++ b/basegfx/source/raster/rasterconvert3d.cxx
@@ -214,9 +214,8 @@ namespace basegfx
         B3DPoint aStart(rLine.getB3DPoint(nA));
         B3DPoint aEnd(rLine.getB3DPoint(nB));
         const double fZBufferLineAdd(0x00ff);
-        static bool bForceToPolygon(false);
 
-        if(nLineWidth > 1 || bForceToPolygon)
+        if(nLineWidth > 1)
         {
             // this is not a hairline anymore, in most cases since it's an oversampled
             // hairline to get e.g. AA for Z-Buffering. Create fill geometry.
diff --git a/basegfx/test/B2DHomMatrixTest.cxx b/basegfx/test/B2DHomMatrixTest.cxx
index bf46026beaba..52ab3e77ad5e 100644
--- a/basegfx/test/B2DHomMatrixTest.cxx
+++ b/basegfx/test/B2DHomMatrixTest.cxx
@@ -331,10 +331,10 @@ public:
         // using the decompose result should be the same as before. Test
         // with all ranges of values. Translations are not tested since these
         // are just the two rightmost values and uncritical
-        static double fSX(10.0);
-        static double fSY(12.0);
-        static double fR(F_PI4);
-        static double fS(deg2rad(15.0));
+        static const double fSX(10.0);
+        static const double fSY(12.0);
+        static const double fR(F_PI4);
+        static const double fS(deg2rad(15.0));
 
         // check all possible scaling combinations
         CPPUNIT_ASSERT_MESSAGE("decompose: error test A1",
diff --git a/chart2/source/view/axes/VCartesianAxis.cxx b/chart2/source/view/axes/VCartesianAxis.cxx
index 2a9b592b46cb..a83139719545 100644
--- a/chart2/source/view/axes/VCartesianAxis.cxx
+++ b/chart2/source/view/axes/VCartesianAxis.cxx
@@ -1802,7 +1802,7 @@ void VCartesianAxis::createShapes()
             hideIdenticalScreenValues( aComplexTickInfos );
 
             std::vector<TickmarkProperties> aTickmarkPropertiesList;
-            static bool bIncludeSpaceBetweenTickAndText = false;
+            static const bool bIncludeSpaceBetweenTickAndText = false;
             sal_Int32 nOffset = static_cast<sal_Int32>(pTickFactory2D->getDistanceAxisTickToText( m_aAxisProperties, false, bIncludeSpaceBetweenTickAndText ).getLength());
             sal_Int32 nTextLevelCount = getTextLevelCount();
             for( sal_Int32 nTextLevel=0; nTextLevel<nTextLevelCount; nTextLevel++ )
diff --git a/compilerplugins/clang/constvars.cxx b/compilerplugins/clang/constvars.cxx
new file mode 100644
index 000000000000..18a9a48fc2df
--- /dev/null
+++ b/compilerplugins/clang/constvars.cxx
@@ -0,0 +1,509 @@
+/* -*- 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/.
+ */
+
+#if !defined _WIN32 //TODO, #include <sys/file.h>
+
+#include <cassert>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <unordered_set>
+#include <vector>
+#include <algorithm>
+#include <sys/file.h>
+#include <unistd.h>
+#include "plugin.hxx"
+#include "compat.hxx"
+#include "check.hxx"
+
+/**
+Look for static vars that are only assigned to once, and never written to, they can be const.
+*/
+
+namespace
+{
+/**
+ * Wrap the different kinds of callable and callee objects in the clang AST so I can define methods that handle everything.
+ */
+class CallerWrapper
+{
+    const CallExpr* m_callExpr;
+    const CXXConstructExpr* m_cxxConstructExpr;
+
+public:
+    CallerWrapper(const CallExpr* callExpr)
+        : m_callExpr(callExpr)
+        , m_cxxConstructExpr(nullptr)
+    {
+    }
+    CallerWrapper(const CXXConstructExpr* cxxConstructExpr)
+        : m_callExpr(nullptr)
+        , m_cxxConstructExpr(cxxConstructExpr)
+    {
+    }
+    unsigned getNumArgs() const
+    {
+        return m_callExpr ? m_callExpr->getNumArgs() : m_cxxConstructExpr->getNumArgs();
+    }
+    const Expr* getArg(unsigned i) const
+    {
+        return m_callExpr ? m_callExpr->getArg(i) : m_cxxConstructExpr->getArg(i);
+    }
+};
+class CalleeWrapper
+{
+    const FunctionDecl* m_calleeFunctionDecl = nullptr;
+    const CXXConstructorDecl* m_cxxConstructorDecl = nullptr;
+    const FunctionProtoType* m_functionPrototype = nullptr;
+
+public:
+    explicit CalleeWrapper(const FunctionDecl* calleeFunctionDecl)
+        : m_calleeFunctionDecl(calleeFunctionDecl)
+    {
+    }
+    explicit CalleeWrapper(const CXXConstructExpr* cxxConstructExpr)
+        : m_cxxConstructorDecl(cxxConstructExpr->getConstructor())
+    {
+    }
+    explicit CalleeWrapper(const FunctionProtoType* functionPrototype)
+        : m_functionPrototype(functionPrototype)
+    {
+    }
+    unsigned getNumParams() const
+    {
+        if (m_calleeFunctionDecl)
+            return m_calleeFunctionDecl->getNumParams();
+        else if (m_cxxConstructorDecl)
+            return m_cxxConstructorDecl->getNumParams();
+        else if (m_functionPrototype->param_type_begin() == m_functionPrototype->param_type_end())
+            // FunctionProtoType will assert if we call getParamTypes() and it has no params
+            return 0;
+        else
+            return m_functionPrototype->getParamTypes().size();
+    }
+    const QualType getParamType(unsigned i) const
+    {
+        if (m_calleeFunctionDecl)
+            return m_calleeFunctionDecl->getParamDecl(i)->getType();
+        else if (m_cxxConstructorDecl)
+            return m_cxxConstructorDecl->getParamDecl(i)->getType();
+        else
+            return m_functionPrototype->getParamTypes()[i];
+    }
+    std::string getNameAsString() const
+    {
+        if (m_calleeFunctionDecl)
+            return m_calleeFunctionDecl->getNameAsString();
+        else if (m_cxxConstructorDecl)
+            return m_cxxConstructorDecl->getNameAsString();
+        else
+            return "";
+    }
+    CXXMethodDecl const* getAsCXXMethodDecl() const
+    {
+        if (m_calleeFunctionDecl)
+            return dyn_cast<CXXMethodDecl>(m_calleeFunctionDecl);
+        return nullptr;
+    }
+};
+
+class ConstVars : public RecursiveASTVisitor<ConstVars>, public loplugin::Plugin
+{
+public:
+    explicit ConstVars(loplugin::InstantiationData const& data)
+        : Plugin(data)
+    {
+    }
+
+    virtual void run() override;
+
+    bool shouldVisitTemplateInstantiations() const { return true; }
+    bool shouldVisitImplicitCode() const { return true; }
+
+    bool VisitVarDecl(const VarDecl*);
+    bool VisitDeclRefExpr(const DeclRefExpr*);
+    bool TraverseCXXConstructorDecl(CXXConstructorDecl*);
+    bool TraverseCXXMethodDecl(CXXMethodDecl*);
+    bool TraverseFunctionDecl(FunctionDecl*);
+    bool TraverseIfStmt(IfStmt*);
+
+private:
+    void check(const VarDecl* varDecl, const Expr* memberExpr);
+    bool isSomeKindOfZero(const Expr* arg);
+    bool IsPassedByNonConst(const VarDecl* varDecl, const Stmt* child, CallerWrapper callExpr,
+                            CalleeWrapper calleeFunctionDecl);
+    llvm::Optional<CalleeWrapper> getCallee(CallExpr const*);
+
+    RecordDecl* insideMoveOrCopyDeclParent = nullptr;
+    // For reasons I do not understand, parentFunctionDecl() is not reliable, so
+    // we store the parent function on the way down the AST.
+    FunctionDecl* insideFunctionDecl = nullptr;
+    std::vector<VarDecl const*> insideConditionalCheckOfVarSet;
+
+    std::set<VarDecl const*> cannotBeConstSet;
+    std::set<VarDecl const*> definitionSet;
+};
+
+void ConstVars::run()
+{
+    // clang::Expr::isCXX11ConstantExpr only works for C++
+    if (!compiler.getLangOpts().CPlusPlus)
+        return;
+
+    TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+
+    SourceManager& SM = compiler.getSourceManager();
+    for (VarDecl const* v : definitionSet)
+    {
+        if (cannotBeConstSet.find(v) != cannotBeConstSet.end())
+            continue;
+        llvm::StringRef sourceString(SM.getCharacterData(v->getSourceRange().getEnd()), 50);
+        // Implement a marker that disables this plugins warning at a specific site
+        if (sourceString.contains("loplugin:constvars:ignore"))
+            continue;
+        report(DiagnosticsEngine::Warning, "static var can be const", compat::getBeginLoc(v));
+        v->getType().dump();
+    }
+}
+
+bool ConstVars::VisitVarDecl(const VarDecl* varDecl)
+{
+    varDecl = varDecl->getCanonicalDecl();
+    if (varDecl->getLocation().isValid() && ignoreLocation(varDecl))
+        return true;
+    if (!varDecl->hasGlobalStorage())
+        return true;
+    if (varDecl->getLinkageAndVisibility().getLinkage() == ExternalLinkage)
+        return true;
+    if (varDecl->getType().isConstQualified())
+        return true;
+    if (isa<ConstantArrayType>(varDecl->getType()))
+        return true;
+    if (loplugin::TypeCheck(varDecl->getType()).Pointer().Const())
+        return true;
+    // ignore stuff that forms part of the stable URE interface
+    if (isInUnoIncludeFile(compiler.getSourceManager().getSpellingLoc(varDecl->getLocation())))
+        return true;
+
+    if (!varDecl->getInit())
+        return true;
+    if (!varDecl->getInit()->isCXX11ConstantExpr(compiler.getASTContext()))
+        return true;
+
+    definitionSet.insert(varDecl);
+    return true;
+}
+
+bool ConstVars::TraverseCXXConstructorDecl(CXXConstructorDecl* cxxConstructorDecl)
+{
+    auto copy = insideMoveOrCopyDeclParent;
+    if (!ignoreLocation(cxxConstructorDecl) && cxxConstructorDecl->isThisDeclarationADefinition())
+    {
+        if (cxxConstructorDecl->isCopyOrMoveConstructor())
+            insideMoveOrCopyDeclParent = cxxConstructorDecl->getParent();
+    }
+    bool ret = RecursiveASTVisitor::TraverseCXXConstructorDecl(cxxConstructorDecl);
+    insideMoveOrCopyDeclParent = copy;
+    return ret;
+}
+
+bool ConstVars::TraverseCXXMethodDecl(CXXMethodDecl* cxxMethodDecl)
+{
+    auto copy1 = insideMoveOrCopyDeclParent;
+    auto copy2 = insideFunctionDecl;
+    if (!ignoreLocation(cxxMethodDecl) && cxxMethodDecl->isThisDeclarationADefinition())
+    {
+        if (cxxMethodDecl->isCopyAssignmentOperator() || cxxMethodDecl->isMoveAssignmentOperator())
+            insideMoveOrCopyDeclParent = cxxMethodDecl->getParent();
+    }
+    insideFunctionDecl = cxxMethodDecl;
+    bool ret = RecursiveASTVisitor::TraverseCXXMethodDecl(cxxMethodDecl);
+    insideMoveOrCopyDeclParent = copy1;
+    insideFunctionDecl = copy2;
+    return ret;
+}
+
+bool ConstVars::TraverseFunctionDecl(FunctionDecl* functionDecl)
+{
+    auto copy2 = insideFunctionDecl;
+    insideFunctionDecl = functionDecl;
+    bool ret = RecursiveASTVisitor::TraverseFunctionDecl(functionDecl);
+    insideFunctionDecl = copy2;
+    return ret;
+}
+
+bool ConstVars::TraverseIfStmt(IfStmt* ifStmt)
+{
+    VarDecl const* varDecl = nullptr;
+    Expr const* cond = ifStmt->getCond()->IgnoreParenImpCasts();
+    if (auto declRefExpr = dyn_cast<DeclRefExpr>(cond))
+    {
+        if ((varDecl = dyn_cast<VarDecl>(declRefExpr->getDecl())))
+            insideConditionalCheckOfVarSet.push_back(varDecl);
+    }
+    bool ret = RecursiveASTVisitor::TraverseIfStmt(ifStmt);
+    if (varDecl)
+        insideConditionalCheckOfVarSet.pop_back();
+    return ret;
+}
+
+bool ConstVars::VisitDeclRefExpr(const DeclRefExpr* declRefExpr)
+{
+    const VarDecl* varDecl = dyn_cast<VarDecl>(declRefExpr->getDecl());
+    if (!varDecl)
+        return true;
+    varDecl = varDecl->getCanonicalDecl();
+    if (ignoreLocation(varDecl))
+        return true;
+    // ignore stuff that forms part of the stable URE interface
+    if (isInUnoIncludeFile(compiler.getSourceManager().getSpellingLoc(varDecl->getLocation())))
+        return true;
+
+    if (definitionSet.find(varDecl) != definitionSet.end())
+        check(varDecl, declRefExpr);
+
+    return true;
+}
+
+void ConstVars::check(const VarDecl* varDecl, const Expr* memberExpr)
+{
+    auto parentsRange = compiler.getASTContext().getParents(*memberExpr);
+    const Stmt* child = memberExpr;
+    const Stmt* parent
+        = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>();
+    // walk up the tree until we find something interesting
+    bool bCannotBeConst = false;
+    bool bDump = false;
+    auto walkUp = [&]() {
+        child = parent;
+        auto parentsRange = compiler.getASTContext().getParents(*parent);
+        parent = parentsRange.begin() == parentsRange.end() ? nullptr
+                                                            : parentsRange.begin()->get<Stmt>();
+    };
+    do
+    {
+        if (!parent)
+        {
+            // check if we have an expression like
+            //    int& r = var;
+            auto parentsRange = compiler.getASTContext().getParents(*child);
+            if (parentsRange.begin() != parentsRange.end())
+            {
+                auto varDecl = dyn_cast_or_null<VarDecl>(parentsRange.begin()->get<Decl>());
+                // 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())
+                {
+                    bCannotBeConst = true;
+                }
+            }
+            break;
+        }
+        if (isa<CXXReinterpretCastExpr>(parent))
+        {
+            // once we see one of these, there is not much useful we can know
+            bCannotBeConst = true;
+            break;
+        }
+        else if (isa<CastExpr>(parent) || isa<MemberExpr>(parent) || isa<ParenExpr>(parent)
+                 || isa<ParenListExpr>(parent) || isa<ArrayInitLoopExpr>(parent)
+                 || isa<ExprWithCleanups>(parent))
+        {
+            walkUp();
+        }
+        else if (auto unaryOperator = dyn_cast<UnaryOperator>(parent))
+        {
+            UnaryOperator::Opcode op = unaryOperator->getOpcode();
+            if (op == UO_AddrOf || op == UO_PostInc || op == UO_PostDec || op == UO_PreInc
+                || op == UO_PreDec)
+            {
+                bCannotBeConst = true;
+            }
+            walkUp();
+        }
+        else if (auto operatorCallExpr = dyn_cast<CXXOperatorCallExpr>(parent))
+        {
+            auto callee = getCallee(operatorCallExpr);
+            if (callee)
+            {
+                // if calling a non-const operator on the var
+                auto calleeMethodDecl = callee->getAsCXXMethodDecl();
+                if (calleeMethodDecl && operatorCallExpr->getArg(0) == child
+                    && !calleeMethodDecl->isConst())
+                {
+                    bCannotBeConst = true;
+                }
+                else if (IsPassedByNonConst(varDecl, child, operatorCallExpr, *callee))
+                {
+                    bCannotBeConst = true;
+                }
+            }
+            else
+                bCannotBeConst = true; // conservative, could improve
+            walkUp();
+        }
+        else if (auto cxxMemberCallExpr = dyn_cast<CXXMemberCallExpr>(parent))
+        {
+            const CXXMethodDecl* calleeMethodDecl = cxxMemberCallExpr->getMethodDecl();
+            if (calleeMethodDecl)
+            {
+                // if calling a non-const method on the var
+                const Expr* tmp = dyn_cast<Expr>(child);
+                if (tmp->isBoundMemberFunction(compiler.getASTContext()))
+                {
+                    tmp = dyn_cast<MemberExpr>(tmp)->getBase();
+                }
+                if (cxxMemberCallExpr->getImplicitObjectArgument() == tmp
+                    && !calleeMethodDecl->isConst())
+                {
+                    bCannotBeConst = true;
+                    break;
+                }
+                if (IsPassedByNonConst(varDecl, child, cxxMemberCallExpr,
+                                       CalleeWrapper(calleeMethodDecl)))
+                    bCannotBeConst = true;
+            }
+            else
+                bCannotBeConst = true; // can happen in templates
+            walkUp();
+        }
+        else if (auto cxxConstructExpr = dyn_cast<CXXConstructExpr>(parent))
+        {
+            if (IsPassedByNonConst(varDecl, child, cxxConstructExpr,
+                                   CalleeWrapper(cxxConstructExpr)))
+                bCannotBeConst = true;
+            walkUp();
+        }
+        else if (auto callExpr = dyn_cast<CallExpr>(parent))
+        {
+            auto callee = getCallee(callExpr);
+            if (callee)
+            {
+                if (IsPassedByNonConst(varDecl, child, callExpr, *callee))
+                    bCannotBeConst = true;
+            }
+            else
+                bCannotBeConst = true; // conservative, could improve
+            walkUp();
+        }
+        else if (auto binaryOp = dyn_cast<BinaryOperator>(parent))
+        {
+            BinaryOperator::Opcode op = binaryOp->getOpcode();
+            const bool assignmentOp = op == BO_Assign || op == BO_MulAssign || op == BO_DivAssign
+                                      || op == BO_RemAssign || op == BO_AddAssign
+                                      || op == BO_SubAssign || op == BO_ShlAssign
+                                      || op == BO_ShrAssign || op == BO_AndAssign
+                                      || op == BO_XorAssign || op == BO_OrAssign;
+            if (assignmentOp)
+            {
+                if (binaryOp->getLHS() == child)
+                    bCannotBeConst = true;
+                else if (loplugin::TypeCheck(binaryOp->getLHS()->getType())
+                             .LvalueReference()
+                             .NonConst())
+                    // if the LHS is a non-const reference, we could write to the var later on
+                    bCannotBeConst = true;
+            }
+            walkUp();
+        }
+        else if (isa<ReturnStmt>(parent))
+        {
+            if (insideFunctionDecl)
+            {
+                auto tc = loplugin::TypeCheck(insideFunctionDecl->getReturnType());
+                if (tc.LvalueReference().NonConst())
+                    bCannotBeConst = true;
+            }
+            break;
+        }
+        else if (isa<SwitchStmt>(parent) || isa<WhileStmt>(parent) || isa<ForStmt>(parent)
+                 || isa<IfStmt>(parent) || isa<DoStmt>(parent) || isa<CXXForRangeStmt>(parent)
+                 || isa<DefaultStmt>(parent))
+        {
+            break;
+        }
+        else
+        {
+            walkUp();
+        }
+    } while (true);
+
+    if (bDump)
+    {
+        report(DiagnosticsEngine::Warning, "oh dear, what can the matter be? writtenTo=%0",
+               compat::getBeginLoc(memberExpr))
+            << bCannotBeConst << memberExpr->getSourceRange();
+        if (parent)
+        {
+            report(DiagnosticsEngine::Note, "parent over here", compat::getBeginLoc(parent))
+                << parent->getSourceRange();
+            parent->dump();
+        }
+        memberExpr->dump();
+        varDecl->getType()->dump();
+    }
+
+    if (bCannotBeConst)
+        cannotBeConstSet.insert(varDecl);
+}
+
+bool ConstVars::IsPassedByNonConst(const VarDecl* varDecl, const Stmt* child,
+                                   CallerWrapper callExpr, CalleeWrapper calleeFunctionDecl)
+{
+    unsigned len = std::min(callExpr.getNumArgs(), calleeFunctionDecl.getNumParams());
+    // if it's an array, passing it by value to a method typically means the
+    // callee takes a pointer and can modify the array
+    if (varDecl->getType()->isConstantArrayType())
+    {
+        for (unsigned i = 0; i < len; ++i)
+            if (callExpr.getArg(i) == child)
+                if (loplugin::TypeCheck(calleeFunctionDecl.getParamType(i)).Pointer().NonConst())
+                    return true;
+    }
+    else
+    {
+        for (unsigned i = 0; i < len; ++i)
+            if (callExpr.getArg(i) == child)
+                if (loplugin::TypeCheck(calleeFunctionDecl.getParamType(i))
+                        .LvalueReference()
+                        .NonConst())
+                    return true;
+    }
+    return false;
+}
+
+llvm::Optional<CalleeWrapper> ConstVars::getCallee(CallExpr const* callExpr)
+{
+    FunctionDecl const* functionDecl = callExpr->getDirectCallee();
+    if (functionDecl)
+        return CalleeWrapper(functionDecl);
+
+    // Extract the functionprototype from a type
+    clang::Type const* calleeType = callExpr->getCallee()->getType().getTypePtr();
+    if (auto pointerType = calleeType->getUnqualifiedDesugaredType()->getAs<clang::PointerType>())
+    {
+        if (auto prototype = pointerType->getPointeeType()
+                                 ->getUnqualifiedDesugaredType()
+                                 ->getAs<FunctionProtoType>())
+        {
+            return CalleeWrapper(prototype);
+        }
+    }
+
+    return llvm::Optional<CalleeWrapper>();
+}
+
+/** off by default because it is very expensive, it walks up the AST a lot */
+loplugin::Plugin::Registration<ConstVars> X("constvars", false);
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/compilerplugins/clang/test/constvars.cxx b/compilerplugins/clang/test/constvars.cxx
new file mode 100644
index 000000000000..40f3250a6512
--- /dev/null
+++ b/compilerplugins/clang/test/constvars.cxx
@@ -0,0 +1,49 @@
+/* -*- 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/.
+ */
+
+#if defined _WIN32 //TODO, see corresponding TODO in compilerplugins/clang/writeonlyvars.cxx
+// expected-no-diagnostics
+#else
+
+#include <com/sun/star/uno/Any.hxx>
+
+namespace test1
+{
+int const aFormalArgs[] = { 1, 2 };
+// expected-error at +1 {{static var can be const [loplugin:constvars]}}
+static sal_uInt16 nMediaArgsCount = SAL_N_ELEMENTS(aFormalArgs);
+sal_uInt16 foo()
+{
+    (void)aFormalArgs;
+    return nMediaArgsCount;
+}
+};
+
+// no warning expected
+namespace test2
+{
+static char const* ar[] = { "xxxx" };
+static const char* lcl_DATA_OTHERS = "localedata_others";
+void foo()
+{
+    (void)ar;
+    (void)lcl_DATA_OTHERS;
+}
+};
+
+// no warning expected
+namespace test3
+{
+static sal_uInt16 nMediaArgsCount = 1; // loplugin:constvars:ignore
+sal_uInt16 foo() { return nMediaArgsCount; }
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index d2fb9463141f..be3f3c0f48c3 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -505,7 +505,7 @@ void Desktop::Init()
         // of loading the office configuration initially. To use,
         // either set to true and compile, or set a breakpoint
         // in debugger and change the local bool
-        static bool bTryHardOfficeconfigBroken(false);
+        static bool bTryHardOfficeconfigBroken(false); // loplugin:constvars:ignore
 
         if (bTryHardOfficeconfigBroken)
         {
diff --git a/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx b/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx
index 85cf4cd548fb..96b3de031acc 100644
--- a/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx
@@ -283,9 +283,7 @@ namespace drawinglayer
 
             if(!getFillGradient().isDefault())
             {
-                static bool bOverlapping(true); // allow to test non-overlapping in the debugger
-
-                createFill(rContainer, bOverlapping);
+                createFill(rContainer, /*bOverlapping*/true);
             }
         }
 
diff --git a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
index ea2e9c9aede6..bcf1fc6bbc3b 100644
--- a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
@@ -267,10 +267,7 @@ namespace drawinglayer
                         // to be painted as a single tools::PolyPolygon (XORed as fill rule). Alternatively, a
                         // melting process may be used here one day.
                         const basegfx::B2DPolyPolygon aNewPolyPolygon(aAreaPolyPolygon.getB2DPolygon(b));
-                        static bool bTestByUsingRandomColor(false);
-                        const basegfx::BColor aColor(bTestByUsingRandomColor
-                            ? basegfx::BColor(getRandomColorRange(), getRandomColorRange(), getRandomColorRange())
-                            : getLineAttribute().getColor());
+                        const basegfx::BColor aColor(getLineAttribute().getColor());
                         rContainer.push_back(new PolyPolygonColorPrimitive2D(aNewPolyPolygon, aColor));
                     }
                 }
diff --git a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
index 400dd0f0310c..a15daa84a464 100644
--- a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
@@ -365,7 +365,7 @@ namespace drawinglayer
                         nOversampleValue ? nRasterHeight * nOversampleValue : nRasterHeight);
 
                     // check for parallel execution possibilities
-                    static bool bMultithreadAllowed = true;
+                    static bool bMultithreadAllowed = true; // loplugin:constvars:ignore
                     sal_Int32 nThreadCount(0);
                     comphelper::ThreadPool& rThreadPool(comphelper::ThreadPool::getSharedOptimalPool());
 
@@ -469,7 +469,7 @@ namespace drawinglayer
                         rContainer.push_back(new BitmapPrimitive2D(maOldRenderedBitmap, aNew2DTransform));
 
                         // test: Allow to add an outline in the debugger when tests are needed
-                        static bool bAddOutlineToCreated3DSceneRepresentation(false);
+                        static bool bAddOutlineToCreated3DSceneRepresentation(false); // loplugin:constvars:ignore
 
                         if(bAddOutlineToCreated3DSceneRepresentation)
                         {
diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
index b22ddabf00a0..e30851d23493 100644
--- a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
+++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
@@ -329,7 +329,7 @@ namespace drawinglayer
             const Size aSizePixel(maDestPixel.GetSize());
             const bool bWasEnabledDst(mrOutDev.IsMapModeEnabled());
 #ifdef DBG_UTIL
-            static bool bDoSaveForVisualControl(false);
+            static bool bDoSaveForVisualControl(false); // loplugin:constvars:ignore
 #endif
 
             mrOutDev.EnableMapMode(false);
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index d54d8e1fe1ce..8e9e0db30040 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -922,7 +922,7 @@ namespace drawinglayer
         {
             bool bUsingPDFExtOutDevData(false);
             basegfx::B2DVector aTranslate, aScale;
-            static bool bSuppressPDFExtOutDevDataSupport(false);
+            static bool bSuppressPDFExtOutDevDataSupport(false); // loplugin:constvars:ignore
 
             if(mpPDFExtOutDevData && !bSuppressPDFExtOutDevDataSupport)
             {
@@ -1247,7 +1247,7 @@ namespace drawinglayer
         void VclMetafileProcessor2D::processTextHierarchyParagraphPrimitive2D(const primitive2d::TextHierarchyParagraphPrimitive2D& rParagraphPrimitive)
         {
             const OString aCommentString("XTEXT_EOP");
-            static bool bSuppressPDFExtOutDevDataSupport(false);
+            static bool bSuppressPDFExtOutDevDataSupport(false); // loplugin:constvars:ignore
 
             if(nullptr == mpPDFExtOutDevData || bSuppressPDFExtOutDevDataSupport)
             {
@@ -1995,7 +1995,7 @@ namespace drawinglayer
                     // try to identify a single PolyPolygonColorPrimitive2D in the
                     // content part of the transparence primitive
                     const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = nullptr;
-                    static bool bForceToMetafile(false);
+                    static bool bForceToMetafile(false); // loplugin:constvars:ignore
 
                     if(!bForceToMetafile && 1 == rContent.size())
                     {
@@ -2089,7 +2089,7 @@ namespace drawinglayer
                 // try to identify a single FillGradientPrimitive2D in the
                 // transparence part of the primitive
                 const primitive2d::FillGradientPrimitive2D* pFiGradient = nullptr;
-                static bool bForceToBigTransparentVDev(false);
+                static bool bForceToBigTransparentVDev(false); // loplugin:constvars:ignore
 
                 if(!bForceToBigTransparentVDev && 1 == rTransparence.size())
                 {
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index 741c6762a97f..68d197394a4a 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -422,37 +422,24 @@ namespace drawinglayer
 
         void VclPixelProcessor2D::processWrongSpellPrimitive2D(const primitive2d::WrongSpellPrimitive2D& rWrongSpellPrimitive)
         {
-            // directdraw of wrong spell primitive; added test possibility to check wrong spell decompose
-            static bool bHandleWrongSpellDirectly(true);
-
-            if(bHandleWrongSpellDirectly)
-            {
-                if(!renderWrongSpellPrimitive2D(
-                    rWrongSpellPrimitive,
-                    *mpOutputDevice,
-                    maCurrentTransformation,
-                    maBColorModifierStack))
-                {
-                    // fallback to decomposition (MetaFile)
-                    process(rWrongSpellPrimitive);
-                }
-            }
-            else
+            if(!renderWrongSpellPrimitive2D(
+                rWrongSpellPrimitive,
+                *mpOutputDevice,
+                maCurrentTransformation,
+                maBColorModifierStack))
             {
+                // fallback to decomposition (MetaFile)
                 process(rWrongSpellPrimitive);
             }
         }
 
         void VclPixelProcessor2D::processTextSimplePortionPrimitive2D(const primitive2d::TextSimplePortionPrimitive2D& rCandidate)
         {
-            // directdraw of text simple portion; added test possibility to check text decompose
-            static bool bForceSimpleTextDecomposition(false);
-
             // Adapt evtl. used special DrawMode
             const DrawModeFlags nOriginalDrawMode(mpOutputDevice->GetDrawMode());
             adaptTextToFillDrawMode();
 
-            if(!bForceSimpleTextDecomposition && getOptionsDrawinglayer().IsRenderSimpleTextDirect())
+            if(getOptionsDrawinglayer().IsRenderSimpleTextDirect())
             {
                 RenderTextSimpleOrDecoratedPortionPrimitive2D(rCandidate);
             }
@@ -467,14 +454,11 @@ namespace drawinglayer
 
         void VclPixelProcessor2D::processTextDecoratedPortionPrimitive2D(const primitive2d::TextSimplePortionPrimitive2D& rCandidate)
         {
-            // directdraw of decorated text portion; added test possibility to check text decompose
-            static bool bForceComplexTextDecomposition(false);
-
             // Adapt evtl. used special DrawMode
             const DrawModeFlags nOriginalDrawMode(mpOutputDevice->GetDrawMode());
             adaptTextToFillDrawMode();
 
-            if(!bForceComplexTextDecomposition && getOptionsDrawinglayer().IsRenderDecoratedTextDirect())
+            if(getOptionsDrawinglayer().IsRenderDecoratedTextDirect())
             {
                 RenderTextSimpleOrDecoratedPortionPrimitive2D(rCandidate);
             }
@@ -489,10 +473,7 @@ namespace drawinglayer
 
         void VclPixelProcessor2D::processPolygonHairlinePrimitive2D(const primitive2d::PolygonHairlinePrimitive2D& rPolygonHairlinePrimitive2D)
         {
-            // try to use directly
-            static bool bAllowed(true);
-
-            if(bAllowed && tryDrawPolygonHairlinePrimitive2DDirect(rPolygonHairlinePrimitive2D, 0.0))
+            if(tryDrawPolygonHairlinePrimitive2DDirect(rPolygonHairlinePrimitive2D, 0.0))
             {
                 return;
             }
@@ -554,24 +535,9 @@ namespace drawinglayer
         {
             // try to use directly
             basegfx::B2DPolyPolygon aLocalPolyPolygon;
-            static bool bAllowed(true);
-
-            if(bAllowed)
-            {
-                tryDrawPolyPolygonColorPrimitive2DDirect(rPolyPolygonColorPrimitive2D, 0.0);
-                // okay, done. In this case no gaps should have to be repaired, too
-            }
-            else
-            {
-                // direct draw of tools::PolyPolygon with color
-                const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolyPolygonColorPrimitive2D.getBColor()));
 
-                mpOutputDevice->SetFillColor(Color(aPolygonColor));
-                mpOutputDevice->SetLineColor();
-                aLocalPolyPolygon = rPolyPolygonColorPrimitive2D.getB2DPolyPolygon();
-                aLocalPolyPolygon.transform(maCurrentTransformation);
-                mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
-            }
+            tryDrawPolyPolygonColorPrimitive2DDirect(rPolyPolygonColorPrimitive2D, 0.0);
+            // okay, done. In this case no gaps should have to be repaired, too
 
             // when AA is on and this filled polygons are the result of stroked line geometry,
             // draw the geometry once extra as lines to avoid AA 'gaps' between partial polygons
@@ -617,11 +583,7 @@ namespace drawinglayer
                 {
                     bool bDrawTransparentUsed(false);
 
-                    // since DEV300 m33 DrawTransparent is supported in VCL (for some targets
-                    // natively), so i am now enabling this shortcut
-                    static bool bAllowUsingDrawTransparent(true);
-
-                    if(bAllowUsingDrawTransparent && 1 == rContent.size())
+                    if(1 == rContent.size())
                     {
                         const primitive2d::Primitive2DReference xReference(rContent[0]);
                         const primitive2d::BasePrimitive2D* pBasePrimitive = dynamic_cast< const primitive2d::BasePrimitive2D* >(xReference.get());
@@ -648,11 +610,9 @@ namespace drawinglayer
                                     // do no tallow by default - problem is that self-overlapping parts of this geometry will
                                     // not be in a all-same transparency but will already alpha-cover themselves with blending.
                                     // This is not what the UnifiedTransparencePrimitive2D defines: It requires all its
-                                    // content to be uniformely transparent.
+                                    // content to be uniformly transparent.
                                     // For hairline the effect is pretty minimal, but still not correct.
-                                    static bool bAllowed(false);
-
-                                    bDrawTransparentUsed = bAllowed && tryDrawPolygonHairlinePrimitive2DDirect(*pPoHair, rUniTransparenceCandidate.getTransparence());
+                                    bDrawTransparentUsed = false;
                                     break;
                                 }
                                 case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D:
@@ -664,11 +624,9 @@ namespace drawinglayer
                                     // do no tallow by default - problem is that self-overlapping parts of this geometry will
                                     // not be in a all-same transparency but will already alpha-cover themselves with blending.
                                     // This is not what the UnifiedTransparencePrimitive2D defines: It requires all its
-                                    // content to be uniformely transparent.
+                                    // content to be uniformly transparent.
                                     // To check, activate and draw a wide transparent self-crossing line/curve
-                                    static bool bAllowed(false);
-
-                                    bDrawTransparentUsed = bAllowed && tryDrawPolygonStrokePrimitive2DDirect(*pPoStroke, rUniTransparenceCandidate.getTransparence());
+                                    bDrawTransparentUsed = false;
                                     break;
                                 }
                             default:
@@ -754,28 +712,12 @@ namespace drawinglayer
             adaptLineToFillDrawMode();
 
             // polygon stroke primitive
-            static bool bSuppressFatToHairlineCorrection(false);
-
-            if(bSuppressFatToHairlineCorrection)
-            {
-                // remember that we enter a PolygonStrokePrimitive2D decomposition,
-                // used for AA thick line drawing
-                mnPolygonStrokePrimitive2D++;
 
-                // with AA there is no need to handle thin lines special
-                process(rPolygonStrokePrimitive2D);
-
-                // leave PolygonStrokePrimitive2D
-                mnPolygonStrokePrimitive2D--;
-            }
-            else
-            {
-                // Lines with 1 and 2 pixel width without AA need special treatment since their vsiualisation
-                // as filled polygons is geometrically correct but looks wrong since polygon filling avoids
-                // the right and bottom pixels. The used method evaluates that and takes the correct action,
-                // including calling recursively with decomposition if line is wide enough
-                RenderPolygonStrokePrimitive2D(rPolygonStrokePrimitive2D);
-            }
+            // Lines with 1 and 2 pixel width without AA need special treatment since their vsiualisation
+            // as filled polygons is geometrically correct but looks wrong since polygon filling avoids
+            // the right and bottom pixels. The used method evaluates that and takes the correct action,
+            // including calling recursively with decomposition if line is wide enough
+            RenderPolygonStrokePrimitive2D(rPolygonStrokePrimitive2D);
 
             // restore DrawMode
             mpOutputDevice->SetDrawMode(nOriginalDrawMode);
@@ -783,72 +725,61 @@ namespace drawinglayer
 
         void VclPixelProcessor2D::processFillHatchPrimitive2D(const primitive2d::FillHatchPrimitive2D& rFillHatchPrimitive)
         {
-            static bool bForceIgnoreHatchSmoothing(false);
+            // without AA, use VCL to draw the hatch. It snaps hatch distances to the next pixel
+            // and forces hatch distance to be >= 3 pixels to make the hatch display look smoother.
+            // This is wrong in principle, but looks nicer. This could also be done here directly
+            // without VCL usage if needed
+            const attribute::FillHatchAttribute& rFillHatchAttributes = rFillHatchPrimitive.getFillHatch();
+
+            // create hatch polygon in range size and discrete coordinates
+            basegfx::B2DRange aHatchRange(rFillHatchPrimitive.getOutputRange());
+            aHatchRange.transform(maCurrentTransformation);
+            const basegfx::B2DPolygon aHatchPolygon(basegfx::utils::createPolygonFromRect(aHatchRange));
 
-            if(bForceIgnoreHatchSmoothing || getOptionsDrawinglayer().IsAntiAliasing())
+            if(rFillHatchAttributes.isFillBackground())
             {
-                // if AA is used (or ignore smoothing is on), there is no need to smooth
-                // hatch painting, use decomposition
-                process(rFillHatchPrimitive);
+                // #i111846# background fill is active; draw fill polygon
+                const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor()));
+
+                mpOutputDevice->SetFillColor(Color(aPolygonColor));
+                mpOutputDevice->SetLineColor();
+                mpOutputDevice->DrawPolygon(aHatchPolygon);
             }
-            else
-            {
-                // without AA, use VCL to draw the hatch. It snaps hatch distances to the next pixel
-                // and forces hatch distance to be >= 3 pixels to make the hatch display look smoother.
-                // This is wrong in principle, but looks nicer. This could also be done here directly
-                // without VCL usage if needed
-                const attribute::FillHatchAttribute& rFillHatchAttributes = rFillHatchPrimitive.getFillHatch();
 
-                // create hatch polygon in range size and discrete coordinates
-                basegfx::B2DRange aHatchRange(rFillHatchPrimitive.getOutputRange());
-                aHatchRange.transform(maCurrentTransformation);
-                const basegfx::B2DPolygon aHatchPolygon(basegfx::utils::createPolygonFromRect(aHatchRange));
+            // set hatch line color
+            const basegfx::BColor aHatchColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor()));
+            mpOutputDevice->SetFillColor();
+            mpOutputDevice->SetLineColor(Color(aHatchColor));
 
-                if(rFillHatchAttributes.isFillBackground())
-                {
-                    // #i111846# background fill is active; draw fill polygon
-                    const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor()));
+            // get hatch style
+            HatchStyle eHatchStyle(HatchStyle::Single);
 
-                    mpOutputDevice->SetFillColor(Color(aPolygonColor));
-                    mpOutputDevice->SetLineColor();
-                    mpOutputDevice->DrawPolygon(aHatchPolygon);
+            switch(rFillHatchAttributes.getStyle())
+            {
+                default : // HatchStyle::Single
+                {
+                    break;
                 }
-
-                // set hatch line color
-                const basegfx::BColor aHatchColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor()));
-                mpOutputDevice->SetFillColor();
-                mpOutputDevice->SetLineColor(Color(aHatchColor));
-
-                // get hatch style
-                HatchStyle eHatchStyle(HatchStyle::Single);
-
-                switch(rFillHatchAttributes.getStyle())
+                case attribute::HatchStyle::Double :
                 {
-                    default : // HatchStyle::Single
-                    {
-                        break;
-                    }
-                    case attribute::HatchStyle::Double :
-                    {
-                        eHatchStyle = HatchStyle::Double;
-                        break;
-                    }
-                    case attribute::HatchStyle::Triple :
-                    {
-                        eHatchStyle = HatchStyle::Triple;
-                        break;
-                    }
+                    eHatchStyle = HatchStyle::Double;
+                    break;
                 }
+                case attribute::HatchStyle::Triple :
+                {
+                    eHatchStyle = HatchStyle::Triple;
+                    break;
+                }
+            }
 
-                // create hatch
-                const basegfx::B2DVector aDiscreteDistance(maCurrentTransformation * basegfx::B2DVector(rFillHatchAttributes.getDistance(), 0.0));
-                const sal_uInt32 nDistance(basegfx::fround(aDiscreteDistance.getLength()));
-                const sal_uInt16 nAngle10(static_cast<sal_uInt16>(basegfx::fround(rFillHatchAttributes.getAngle() / F_PI1800)));
-                ::Hatch aVCLHatch(eHatchStyle, Color(rFillHatchAttributes.getColor()), nDistance, nAngle10);
+            // create hatch
+            const basegfx::B2DVector aDiscreteDistance(maCurrentTransformation * basegfx::B2DVector(rFillHatchAttributes.getDistance(), 0.0));
+            const sal_uInt32 nDistance(basegfx::fround(aDiscreteDistance.getLength()));
+            const sal_uInt16 nAngle10(static_cast<sal_uInt16>(basegfx::fround(rFillHatchAttributes.getAngle() / F_PI1800)));
+            ::Hatch aVCLHatch(eHatchStyle, Color(rFillHatchAttributes.getColor()), nDistance, nAngle10);
 
-                // draw hatch using VCL
-                mpOutputDevice->DrawHatch(::tools::PolyPolygon(::tools::Polygon(aHatchPolygon)), aVCLHatch);
-            }
+            // draw hatch using VCL
+            mpOutputDevice->DrawHatch(::tools::PolyPolygon(::tools::Polygon(aHatchPolygon)), aVCLHatch);
         }
 
         void VclPixelProcessor2D::processBackgroundColorPrimitive2D(const primitive2d::BackgroundColorPrimitive2D& rPrimitive)
diff --git a/drawinglayer/source/processor3d/defaultprocessor3d.cxx b/drawinglayer/source/processor3d/defaultprocessor3d.cxx
index 36b6939362d7..ab07e055d894 100644
--- a/drawinglayer/source/processor3d/defaultprocessor3d.cxx
+++ b/drawinglayer/source/processor3d/defaultprocessor3d.cxx
@@ -516,20 +516,9 @@ namespace drawinglayer
                 }
                 case PRIMITIVE3D_ID_HATCHTEXTUREPRIMITIVE3D :
                 {
-                    // HatchTexturePrimitive3D
-                    static bool bDoHatchDecomposition(false);
-
-                    if(bDoHatchDecomposition)
-                    {
-                        // let break down
-                        process(rBasePrimitive.get3DDecomposition(getViewInformation3D()));
-                    }
-                    else
-                    {
-                        // hatchTexturePrimitive3D
-                        const primitive3d::HatchTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::HatchTexturePrimitive3D& >(rBasePrimitive);
-                        impRenderHatchTexturePrimitive3D(rPrimitive);
-                    }
+                    // hatchTexturePrimitive3D
+                    const primitive3d::HatchTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::HatchTexturePrimitive3D& >(rBasePrimitive);
+                    impRenderHatchTexturePrimitive3D(rPrimitive);
                     break;
                 }
                 case PRIMITIVE3D_ID_BITMAPTEXTUREPRIMITIVE3D :
diff --git a/drawinglayer/source/tools/converters.cxx b/drawinglayer/source/tools/converters.cxx
index a993c1884a0c..55cba173e83b 100644
--- a/drawinglayer/source/tools/converters.cxx
+++ b/drawinglayer/source/tools/converters.cxx
@@ -87,7 +87,7 @@ namespace drawinglayer
             if(pContentProcessor)
             {
 #ifdef DBG_UTIL
-                static bool bDoSaveForVisualControl(false);
+                static bool bDoSaveForVisualControl(false); // loplugin:constvars:ignore
 #endif
                 // render content
                 pContentProcessor->process(aSequence);
diff --git a/emfio/source/reader/emfreader.cxx b/emfio/source/reader/emfreader.cxx
index b54698d3b877..574858ccd67d 100644
--- a/emfio/source/reader/emfreader.cxx
+++ b/emfio/source/reader/emfreader.cxx
@@ -1371,7 +1371,7 @@ namespace emfio
                                     }
 
     #ifdef DBG_UTIL
-                                    static bool bDoSaveForVisualControl(false);
+                                    static bool bDoSaveForVisualControl(false); // loplugin:constvars:ignore
 
                                     if(bDoSaveForVisualControl)
                                     {
diff --git a/filter/source/config/cache/typedetection.cxx b/filter/source/config/cache/typedetection.cxx
index b5268857ca9b..3f39602470aa 100644
--- a/filter/source/config/cache/typedetection.cxx
+++ b/filter/source/config/cache/typedetection.cxx
@@ -324,16 +324,15 @@ struct SortByPriority
         // All things being equal, sort them alphabetically.
         return r1.sType > r2.sType;
     }
-} objSortByPriority;
+};
 
 struct SortByType
-
 {
     bool operator() (const FlatDetectionInfo& r1, const FlatDetectionInfo& r2) const
     {
         return r1.sType > r2.sType;
     }
-} objSortByType;
+};
 
 struct EqualByType
 {
@@ -341,7 +340,7 @@ struct EqualByType
     {
         return r1.sType == r2.sType;
     }
-} objEqualByType;
+};
 
 class FindByType
 {
@@ -412,8 +411,8 @@ OUString SAL_CALL TypeDetection::queryTypeByDescriptor(css::uno::Sequence< css::
         // <- SAFE ----------------------------------
 
         // Properly prioritize all candidate types.
-        std::stable_sort(lFlatTypes.begin(), lFlatTypes.end(), objSortByPriority);
-        auto last = std::unique(lFlatTypes.begin(), lFlatTypes.end(), objEqualByType);
+        std::stable_sort(lFlatTypes.begin(), lFlatTypes.end(), SortByPriority());
+        auto last = std::unique(lFlatTypes.begin(), lFlatTypes.end(), EqualByType());
         lFlatTypes.erase(last, lFlatTypes.end());
 
         OUString sLastChance;
@@ -843,8 +842,8 @@ void TypeDetection::impl_getAllFormatTypes(
     }
 
     // Remove duplicates.
-    std::stable_sort(rFlatTypes.begin(), rFlatTypes.end(), objSortByType);
-    auto last = std::unique(rFlatTypes.begin(), rFlatTypes.end(), objEqualByType);
+    std::stable_sort(rFlatTypes.begin(), rFlatTypes.end(), SortByType());
+    auto last = std::unique(rFlatTypes.begin(), rFlatTypes.end(), EqualByType());
     rFlatTypes.erase(last, rFlatTypes.end());
 
     // Mark pre-selected type (if any) to have it prioritized.
diff --git a/filter/source/msfilter/msdffimp.cxx b/filter/source/msfilter/msdffimp.cxx
index d54315516379..edf85fe7cbaa 100644
--- a/filter/source/msfilter/msdffimp.cxx
+++ b/filter/source/msfilter/msdffimp.cxx
@@ -2619,7 +2619,7 @@ void DffPropertyReader::ApplyAttributes( SvStream& rIn, SfxItemSet& rSet, DffObj
     }
     if ( bHasShadow )
     {
-        static bool bCheckShadow(false);
+        static bool bCheckShadow(false); // loplugin:constvars:ignore
 
         // #i124477# Found no reason not to set shadow, esp. since it is applied to evtl. existing text
         // and will lead to an error if in PPT someone used text and added the object shadow to the
diff --git a/i18nlangtag/source/isolang/isolang.cxx b/i18nlangtag/source/isolang/isolang.cxx
index 215a82c64665..8d135bef4bd0 100644
--- a/i18nlangtag/source/isolang/isolang.cxx
+++ b/i18nlangtag/source/isolang/isolang.cxx
@@ -779,7 +779,7 @@ static Bcp47CountryEntry const aImplBcp47CountryEntries[] =
     { LANGUAGE_DONTKNOW,                    "", "", "", k0 }    // marks end of table
 };
 
-static IsoLanguageCountryEntry aLastResortFallbackEntry =
+static const IsoLanguageCountryEntry aLastResortFallbackEntry =
 { LANGUAGE_ENGLISH_US, "en", "US", k0 };
 
 OUString IsoLanguageCountryEntry::getTagString() const
diff --git a/i18npool/source/nativenumber/nativenumbersupplier.cxx b/i18npool/source/nativenumber/nativenumbersupplier.cxx
index 38ae3e116933..738389739b59 100644
--- a/i18npool/source/nativenumber/nativenumbersupplier.cxx
+++ b/i18npool/source/nativenumber/nativenumbersupplier.cxx
@@ -472,7 +472,7 @@ const sal_Char *natnum1Locales[] = {
     "fa",
     "cu"
 };
-sal_Int16 nbOfLocale = SAL_N_ELEMENTS(natnum1Locales);
+const sal_Int16 nbOfLocale = SAL_N_ELEMENTS(natnum1Locales);
 
 //! ATTENTION: Do not change order of elements!
 //! Number and order must match elements of natnum1Locales!
diff --git a/registry/source/reflwrit.cxx b/registry/source/reflwrit.cxx
index e06f575a859c..77ae435101ee 100644
--- a/registry/source/reflwrit.cxx
+++ b/registry/source/reflwrit.cxx
@@ -44,7 +44,7 @@ OString toByteString(rtl_uString const * str) {
 
 }
 
-static sal_Unicode NULL_WSTRING[1] = { 0 };
+static const sal_Unicode NULL_WSTRING[1] = { 0 };
 
 #define BLOP_OFFSET_MAGIC       0
 #define BLOP_OFFSET_SIZE        (BLOP_OFFSET_MAGIC + sizeof(sal_uInt32))
diff --git a/sal/osl/unx/thread.cxx b/sal/osl/unx/thread.cxx
index aa05f6ef407a..f963f302bc53 100644
--- a/sal/osl/unx/thread.cxx
+++ b/sal/osl/unx/thread.cxx
@@ -563,7 +563,7 @@ struct HashEntry
 };
 
 static HashEntry* HashTable[31];
-static int HashSize = SAL_N_ELEMENTS(HashTable);
+static const int HashSize = SAL_N_ELEMENTS(HashTable);
 
 static pthread_mutex_t HashLock = PTHREAD_MUTEX_INITIALIZER;
 
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index acafb14381c1..1d445563d700 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -1051,7 +1051,7 @@ template<class Function>
 static ScMatrixRef lcl_MatrixCalculation(
     const ScMatrix& rMat1, const ScMatrix& rMat2, ScInterpreter* pInterpreter)
 {
-    static Function Op;
+    static const Function Op;
 
     SCSIZE nC1, nC2, nMinC;
     SCSIZE nR1, nR2, nMinR;
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index d2d73f37c56f..97822e9909ed 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -2006,7 +2006,7 @@ public:
     void operator() (const MatrixImplType::element_block_node_type& node)
     {
         using namespace mdds::mtv;
-        static Op op;
+        static const Op op;
 
         switch (node.type)
         {
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index c4cf19cb71ec..2558d14ab539 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1721,7 +1721,7 @@ size_t HashSingleRef( const ScSingleRefData& rRef )
 
 void ScTokenArray::GenHash()
 {
-    static OUStringHash aHasher;
+    static const OUStringHash aHasher;
 
     size_t nHash = 1;
     OpCode eOp;
diff --git a/sd/source/ui/func/futext.cxx b/sd/source/ui/func/futext.cxx
index 6f0dc98bac51..3d5cdaae3ea3 100644
--- a/sd/source/ui/func/futext.cxx
+++ b/sd/source/ui/func/futext.cxx
@@ -134,8 +134,6 @@ static const sal_uInt16 SidArray[] = {
                             0 };
 
 
-static bool bTestText = false;
-
 /**
  * base class for text functions
  */
@@ -1242,8 +1240,7 @@ void FuText::ReceiveRequest(SfxRequest& rReq)
     if (nSlotId == SID_TEXTEDIT)
     {
         // are we currently editing?
-        if(!bTestText)
-            mxTextObj.reset( mpView->GetTextEditObject() );
+        mxTextObj.reset( mpView->GetTextEditObject() );
 
         if (!mxTextObj.is())
         {
diff --git a/sfx2/source/appl/newhelp.cxx b/sfx2/source/appl/newhelp.cxx
index 1e643918361e..56cb15663268 100644
--- a/sfx2/source/appl/newhelp.cxx
+++ b/sfx2/source/appl/newhelp.cxx
@@ -2588,7 +2588,7 @@ void SfxHelpWindow_Impl::Resize()
 void SfxHelpWindow_Impl::Split()
 {
     static const long nMinSplitSize = 5;
-    static long nMaxSplitSize = 99 - nMinSplitSize;
+    static const long nMaxSplitSize = 99 - nMinSplitSize;
 
     SplitWindow::Split();
 
diff --git a/sfx2/source/appl/shutdownicon.cxx b/sfx2/source/appl/shutdownicon.cxx
index da830474037a..a74a785e667a 100644
--- a/sfx2/source/appl/shutdownicon.cxx
+++ b/sfx2/source/appl/shutdownicon.cxx
@@ -123,7 +123,7 @@ extern "C" {
 
 namespace {
 
-boost::logic::tribool loaded(boost::logic::indeterminate);
+boost::logic::tribool loaded(boost::logic::indeterminate); // loplugin:constvars:ignore
 oslGenericFunction pInitSystray = disabled_initSystray;
 oslGenericFunction pDeInitSystray = disabled_deInitSystray;
 
diff --git a/sfx2/source/sidebar/Paint.cxx b/sfx2/source/sidebar/Paint.cxx
index 114ef9339b74..817bd0e54f00 100644
--- a/sfx2/source/sidebar/Paint.cxx
+++ b/sfx2/source/sidebar/Paint.cxx
@@ -59,7 +59,7 @@ const Color& Paint::GetColor() const
     if (meType != ColorPaint)
     {
         assert(meType==ColorPaint);
-        static Color aErrorColor;
+        static const Color aErrorColor;
         return aErrorColor;
     }
     else
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk b/solenv/CompilerTest_compilerplugins_clang.mk
index 7b4acb24ccd9..23e1da6c801b 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -18,6 +18,7 @@ $(eval $(call gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
     compilerplugins/clang/test/commaoperator \
     $(if $(filter-out WNT,$(OS)),compilerplugins/clang/test/constfields) \
     compilerplugins/clang/test/constparams \
+    compilerplugins/clang/test/constvars \
     compilerplugins/clang/test/convertlong \
     compilerplugins/clang/test/cppunitassertequals \
     compilerplugins/clang/test/cstylecast \
diff --git a/sot/source/sdstor/stg.cxx b/sot/source/sdstor/stg.cxx
index 2bf3ac2d8113..f8715d71408a 100644
--- a/sot/source/sdstor/stg.cxx
+++ b/sot/source/sdstor/stg.cxx
@@ -901,7 +901,7 @@ const ClsId& Storage::GetClassId() const
     if ( pEntry )
         return pEntry->m_aEntry.GetClassId();
 
-    static ClsId aDummyId = {0,0,0,{0,0,0,0,0,0,0,0}};
+    static const ClsId aDummyId = {0,0,0,{0,0,0,0,0,0,0,0}};
     return aDummyId;
 }
 
diff --git a/svgio/source/svgreader/svgdocumenthandler.cxx b/svgio/source/svgreader/svgdocumenthandler.cxx
index 9123135fa565..7ab843dfa906 100644
--- a/svgio/source/svgreader/svgdocumenthandler.cxx
+++ b/svgio/source/svgreader/svgdocumenthandler.cxx
@@ -79,7 +79,7 @@ namespace
                                 if(pLast)
                                 {
                                     bool bAddGap(true);
-                                    static bool bNoGapsForBaselineShift(true);
+                                    static bool bNoGapsForBaselineShift(true); // loplugin:constvars:ignore
 
                                     if(bNoGapsForBaselineShift)
                                     {
diff --git a/svtools/source/contnr/imivctl1.cxx b/svtools/source/contnr/imivctl1.cxx
index b67555b706e6..ad9a4dd035f1 100644
--- a/svtools/source/contnr/imivctl1.cxx
+++ b/svtools/source/contnr/imivctl1.cxx
@@ -1405,8 +1405,6 @@ void SvxIconChoiceCtrl_Impl::SetUpdateMode( bool bUpdate )
 void SvxIconChoiceCtrl_Impl::PaintEmphasis(const tools::Rectangle& rTextRect, bool bSelected,
                                            vcl::RenderContext& rRenderContext)
 {
-    static Color aTransparent(COL_TRANSPARENT);
-
     Color aOldFillColor(rRenderContext.GetFillColor());
 
     bool bSolidTextRect = false;
@@ -1415,7 +1413,7 @@ void SvxIconChoiceCtrl_Impl::PaintEmphasis(const tools::Rectangle& rTextRect, bo
     {
         const Color& rFillColor = rRenderContext.GetFont().GetFillColor();
         rRenderContext.SetFillColor(rFillColor);
-        if (rFillColor != aTransparent)
+        if (rFillColor != COL_TRANSPARENT)
             bSolidTextRect = true;
     }
 
diff --git a/svx/source/sdr/contact/objectcontactofpageview.cxx b/svx/source/sdr/contact/objectcontactofpageview.cxx
index 0c6ecf0abc3a..236c35ca9017 100644
--- a/svx/source/sdr/contact/objectcontactofpageview.cxx
+++ b/svx/source/sdr/contact/objectcontactofpageview.cxx
@@ -85,15 +85,8 @@ namespace sdr
         void ObjectContactOfPageView::PrepareProcessDisplay()
         {
             if(IsActive())
-            {
-                static bool bInvalidateDuringPaint(true);
-
-                if(bInvalidateDuringPaint)
-                {
-                    // there are still non-triggered LazyInvalidate events, trigger these
-                    Invoke();
-                }
-            }
+                // there are still non-triggered LazyInvalidate events, trigger these
+                Invoke();
         }
 
         // From baseclass Timer, the timeout call triggered by the LazyInvalidate mechanism
diff --git a/svx/source/sdr/contact/viewcontactofsdrpage.cxx b/svx/source/sdr/contact/viewcontactofsdrpage.cxx
index 5eea087eac66..3214e22823cb 100644
--- a/svx/source/sdr/contact/viewcontactofsdrpage.cxx
+++ b/svx/source/sdr/contact/viewcontactofsdrpage.cxx
@@ -101,7 +101,7 @@ ViewObjectContact& ViewContactOfPageShadow::CreateObjectSpecificViewObjectContac
 
 drawinglayer::primitive2d::Primitive2DContainer ViewContactOfPageShadow::createViewIndependentPrimitive2DSequence() const
 {
-    static bool bUseOldPageShadow(false);
+    static bool bUseOldPageShadow(false); // loplugin:constvars:ignore
     const SdrPage& rPage = getPage();
     basegfx::B2DHomMatrix aPageMatrix;
     aPageMatrix.set(0, 0, static_cast<double>(rPage.GetWidth()));
diff --git a/svx/source/sdr/overlay/overlaymanager.cxx b/svx/source/sdr/overlay/overlaymanager.cxx
index 14460a3ac605..63909dc3344b 100644
--- a/svx/source/sdr/overlay/overlaymanager.cxx
+++ b/svx/source/sdr/overlay/overlaymanager.cxx
@@ -128,15 +128,10 @@ namespace sdr
         {
             // set Property 'ReducedDisplayQuality' to true to allow simpler interaction
             // visualisations
-            static bool bUseReducedDisplayQualityForDrag(true);
-
-            if(bUseReducedDisplayQualityForDrag)
-            {
-                uno::Sequence< beans::PropertyValue > xProperties(1);
-                xProperties[0].Name = "ReducedDisplayQuality";
-                xProperties[0].Value <<= true;
-                maViewInformation2D = drawinglayer::geometry::ViewInformation2D(xProperties);
-            }
+            uno::Sequence< beans::PropertyValue > xProperties(1);
+            xProperties[0].Name = "ReducedDisplayQuality";
+            xProperties[0].Value <<= true;
+            maViewInformation2D = drawinglayer::geometry::ViewInformation2D(xProperties);
         }
 
         rtl::Reference<OverlayManager> OverlayManager::create(OutputDevice& rOutputDevice)
diff --git a/svx/source/sdr/overlay/overlaymanagerbuffered.cxx b/svx/source/sdr/overlay/overlaymanagerbuffered.cxx
index f551bb559385..dfe2c4eaf87f 100644
--- a/svx/source/sdr/overlay/overlaymanagerbuffered.cxx
+++ b/svx/source/sdr/overlay/overlaymanagerbuffered.cxx
@@ -123,18 +123,6 @@ namespace sdr
 
             for(const auto& rRect : aRectangles)
             {
-#ifdef DBG_UTIL
-                // #i72754# possible graphical region test only with non-pro
-                static bool bDoPaintForVisualControl(false);
-
-                if(bDoPaintForVisualControl)
-                {
-                    getOutputDevice().SetLineColor(COL_LIGHTGREEN);
-                    getOutputDevice().SetFillColor();
-                    getOutputDevice().DrawRect(rRect);
-                }
-#endif
-
                 // restore the area
                 const Point aTopLeft(rRect.TopLeft());
                 const Size aSize(rRect.GetSize());
diff --git a/svx/source/sdr/primitive2d/sdrole2primitive2d.cxx b/svx/source/sdr/primitive2d/sdrole2primitive2d.cxx
index cde617b806ac..68c264dd039e 100644
--- a/svx/source/sdr/primitive2d/sdrole2primitive2d.cxx
+++ b/svx/source/sdr/primitive2d/sdrole2primitive2d.cxx
@@ -71,17 +71,14 @@ namespace drawinglayer
         {
             // to take care of getSdrLFSTAttribute() later, the same as in SdrGrafPrimitive2D::create2DDecomposition
             // should happen. For the moment we only need the OLE itself
-            // Added complete primitive preparation using getSdrLFSTAttribute() now. To not do stuff which is not needed now, it
-            // may be suppressed by using a static bool. The paint version only supported text.
-            static bool bBehaveCompatibleToPaintVersion(false);
+            // Added complete primitive preparation using getSdrLFSTAttribute() now.
             Primitive2DContainer  aRetval;
 
             // create unit outline polygon
             const basegfx::B2DPolygon& aUnitOutline(basegfx::utils::createUnitPolygon());
 
             // add fill
-            if(!bBehaveCompatibleToPaintVersion
-                && !getSdrLFSTAttribute().getFill().isDefault())
+            if(!getSdrLFSTAttribute().getFill().isDefault())
             {
                 basegfx::B2DPolyPolygon aTransformed(aUnitOutline);
 
@@ -96,8 +93,7 @@ namespace drawinglayer
             // add line
             // #i97981# condition was inverse to purpose. When being compatible to paint version,
             // border needs to be suppressed
-            if(!bBehaveCompatibleToPaintVersion
-                && !getSdrLFSTAttribute().getLine().isDefault())
+            if(!getSdrLFSTAttribute().getLine().isDefault())
             {
                 // if line width is given, polygon needs to be grown by half of it to make the
                 // outline to be outside of the bitmap
@@ -162,8 +158,7 @@ namespace drawinglayer
             }
 
             // add shadow
-            if(!bBehaveCompatibleToPaintVersion
-                && !getSdrLFSTAttribute().getShadow().isDefault())
+            if(!getSdrLFSTAttribute().getShadow().isDefault())
             {
                 aRetval = createEmbeddedShadowPrimitive(
                     aRetval,
diff --git a/svx/source/svdraw/sdrpaintwindow.cxx b/svx/source/svdraw/sdrpaintwindow.cxx
index 80116583feb8..711da48c53b7 100644
--- a/svx/source/svdraw/sdrpaintwindow.cxx
+++ b/svx/source/svdraw/sdrpaintwindow.cxx
@@ -162,23 +162,6 @@ void SdrPreRenderDevice::OutputPreRenderDevice(const vcl::Region& rExpandedRegio
             aTopLeft, aSize,
             aTopLeft, aSize,
             *mpPreRenderDevice);
-
-#ifdef DBG_UTIL
-        // #i74769#
-        static bool bDoPaintForVisualControlRegion(false);
-
-        if(bDoPaintForVisualControlRegion)
-        {
-            int nR = comphelper::rng::uniform_int_distribution(0, 0x7F-1);
-            int nG = comphelper::rng::uniform_int_distribution(0, 0x7F-1);
-            int nB = comphelper::rng::uniform_int_distribution(0, 0x7F-1);
-            const Color aColor(((((nR|0x80)<<8)|(nG|0x80))<<8)|(nB|0x80));
-
-            mpOutputDevice->SetLineColor(aColor);
-            mpOutputDevice->SetFillColor();
-            mpOutputDevice->DrawRect(rRect);
-        }
-#endif
     }
 
     mpOutputDevice->EnableMapMode(bMapModeWasEnabledDest);
diff --git a/svx/source/svdraw/svdedtv2.cxx b/svx/source/svdraw/svdedtv2.cxx
index a243a9c2d410..f9fd815444b5 100644
--- a/svx/source/svdraw/svdedtv2.cxx
+++ b/svx/source/svdraw/svdedtv2.cxx
@@ -1089,15 +1089,7 @@ void SdrEditView::MergeMarkedObjects(SdrMergeMode eMode)
         case SdrMergeMode::Merge:
         {
             // merge all contained parts (OR)
-            static bool bTestXOR(false);
-            if(bTestXOR)
-            {
-                aMergePolyPolygonA = basegfx::utils::solvePolygonOperationXor(aMergePolyPolygonA, aMergePolyPolygonB);
-            }
-            else
-            {
-                aMergePolyPolygonA = basegfx::utils::solvePolygonOperationOr(aMergePolyPolygonA, aMergePolyPolygonB);
-            }
+            aMergePolyPolygonA = basegfx::utils::solvePolygonOperationOr(aMergePolyPolygonA, aMergePolyPolygonB);
             break;
         }
         case SdrMergeMode::Subtract:
diff --git a/svx/source/svdraw/svdotextdecomposition.cxx b/svx/source/svdraw/svdotextdecomposition.cxx
index a4b7163d1977..a9072395da89 100644
--- a/svx/source/svdraw/svdotextdecomposition.cxx
+++ b/svx/source/svdraw/svdotextdecomposition.cxx
@@ -221,9 +221,8 @@ namespace
         // prepare DXArray content. To make it independent from font size (and such from
         // the text transformation), scale it to unit coordinates
         ::std::vector< double > aDXArray;
-        static bool bDisableTextArray(false);
 
-        if(!bDisableTextArray && rInfo.mpDXArray && rInfo.mnTextLen)
+        if(rInfo.mpDXArray && rInfo.mnTextLen)
         {
             aDXArray.reserve(rInfo.mnTextLen);
 
diff --git a/svx/source/svdraw/svdpntv.cxx b/svx/source/svdraw/svdpntv.cxx
index 967215a3822b..f799c3b098cf 100644
--- a/svx/source/svdraw/svdpntv.cxx
+++ b/svx/source/svdraw/svdpntv.cxx
@@ -553,37 +553,6 @@ void SdrPaintView::CompleteRedraw(OutputDevice* pOut, const vcl::Region& rReg, s
             if(!pWindow->GetPaintRegion().IsEmpty())
             {
                 aOptimizedRepaintRegion.Intersect(pWindow->GetPaintRegion());
-
-#ifdef DBG_UTIL
-                // #i74769# test-paint repaint region
-                static bool bDoPaintForVisualControl(false);
-
-                if(bDoPaintForVisualControl)
-                {
-                    RectangleVector aRectangles;
-                    aOptimizedRepaintRegion.GetRegionRectangles(aRectangles);
-
-                    pWindow->SetLineColor(COL_LIGHTGREEN);
-                    pWindow->SetFillColor();
-
-                    for(const auto& rRect : aRectangles)
-                    {
-                        pWindow->DrawRect(rRect);
-                    }
-
-                    //RegionHandle aRegionHandle(aOptimizedRepaintRegion.BeginEnumRects());
-                    //Rectangle aRegionRectangle;
-
-                    //while(aOptimizedRepaintRegion.GetEnumRects(aRegionHandle, aRegionRectangle))
-                    //{
-                    //  pWindow->SetLineCOL_LIGHTGREEN);
-                    //  pWindow->SetFillColor();
-                    //  pWindow->DrawRect(aRegionRectangle);
-                    //}
-
-                    //aOptimizedRepaintRegion.EndEnumRects(aRegionHandle);
-                }
-#endif
             }
         }
     }
diff --git a/sw/source/core/crsr/paminit.cxx b/sw/source/core/crsr/paminit.cxx
index c5d5124fc9f3..bbc975acf565 100644
--- a/sw/source/core/crsr/paminit.cxx
+++ b/sw/source/core/crsr/paminit.cxx
@@ -21,7 +21,7 @@
 #include <pamtyp.hxx>
 #include <cshtyp.hxx>
 
-static SwMoveFnCollection aFwrd = {
+static const SwMoveFnCollection aFwrd = {
     /* fnNd         */  &GoNext,
     /* fnNds        */  &GoNextNds,
     /* fnDoc        */  &GoEndDoc,
@@ -32,7 +32,7 @@ static SwMoveFnCollection aFwrd = {
     /* fnSection    */  &SwNodes::GoStartOfSection
 };
 
-static SwMoveFnCollection aBwrd = {
+static const SwMoveFnCollection aBwrd = {
     /* fnNd         */  &GoPrevious,
     /* fnNds        */  &GoPreviousNds,
     /* fnDoc        */  &GoStartDoc,
diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx
index eeba3836e663..986b48e48de2 100644
--- a/sw/source/core/doc/docredln.cxx
+++ b/sw/source/core/doc/docredln.cxx
@@ -68,7 +68,7 @@ using namespace com::sun::star;
 
     void sw_DebugRedline( const SwDoc* pDoc )
     {
-        static SwRedlineTable::size_type nWatch = 0;
+        static SwRedlineTable::size_type nWatch = 0; // loplugin:constvars:ignore
         const SwRedlineTable& rTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
         for( SwRedlineTable::size_type n = 0; n < rTable.size(); ++n )
         {
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx
index 680632625da7..c0b0219f0167 100644
--- a/sw/source/core/layout/flylay.cxx
+++ b/sw/source/core/layout/flylay.cxx
@@ -301,7 +301,7 @@ void SwFlyFreeFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
 
 bool SwFlyFreeFrame::supportsAutoContour() const
 {
-    static bool bOverrideHandleContourToAlwaysOff(true);
+    static bool bOverrideHandleContourToAlwaysOff(true); // loplugin:constvars:ignore
 
     // RotateFlyFrameFix: For LO6.0 we need to deactivate the AutoContour feature again, it is simply
     // not clear how/if to use and save/load it in ODF. This has to be discussed.
diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx
index a41bcc7497b5..f0a89b4095c3 100644
--- a/sw/source/core/ole/ndole.cxx
+++ b/sw/source/core/ole/ndole.cxx
@@ -1055,7 +1055,7 @@ drawinglayer::primitive2d::Primitive2DContainer const & SwOLEObj::tryToGetChartC
         if(aXModel.is())
         {
             // disabled for now, need to check deeper
-            static bool bAsynchronousLoadingAllowed = false;
+            static bool bAsynchronousLoadingAllowed = false; // loplugin:constvars:ignore
 
             if(bSynchron ||
                 !bAsynchronousLoadingAllowed)
diff --git a/sw/source/core/text/txtpaint.cxx b/sw/source/core/text/txtpaint.cxx
index 4a1c24a22afd..5609a17b2895 100644
--- a/sw/source/core/text/txtpaint.cxx
+++ b/sw/source/core/text/txtpaint.cxx
@@ -94,14 +94,6 @@ void SwSaveClip::ChgClip_( const SwRect &rRect, const SwTextFrame* pFrame,
             const vcl::Region aClipRegion( aRect );
             pOut->SetClipRegion( aClipRegion );
         }
-#ifdef DBG_UTIL
-        static bool bDbg = false;
-        if( bDbg )
-        {
-            DbgBackColor aDbg( pOut, bDbg );
-            pOut->DrawRect( aRect );
-        }
-#endif
     }
     bChg = true;
 
diff --git a/sw/source/ui/dbui/dbinsdlg.cxx b/sw/source/ui/dbui/dbinsdlg.cxx
index 7eb2341dc3f7..d8dd205ea660 100644
--- a/sw/source/ui/dbui/dbinsdlg.cxx
+++ b/sw/source/ui/dbui/dbinsdlg.cxx
@@ -953,13 +953,7 @@ void SwInsertDBColAutoPilot::DataToDoc( const Sequence<Any>& rSelection,
     Reference< XColumnsSupplier > xColsSupp( xResultSet, UNO_QUERY );
     Reference <XNameAccess> xCols = xColsSupp->getColumns();
 
-    static bool isSelectionBookmarks = true; // TODO is this always true here?
-    uno::Reference<sdbcx::XRowLocate> xRowLocate;
-    if (isSelectionBookmarks)
-    {
-        xRowLocate.set(xResultSet, uno::UNO_QUERY);
-        assert(xRowLocate.is());
-    }
+    uno::Reference<sdbcx::XRowLocate> xRowLocate(xResultSet, uno::UNO_QUERY_THROW);
 
     do{                                 // middle checked loop!!
     if( bAsTable )                      // fill in data as table
@@ -1038,16 +1032,7 @@ void SwInsertDBColAutoPilot::DataToDoc( const Sequence<Any>& rSelection,
             {
                 if(pSelection)
                 {
-                    if (isSelectionBookmarks)
-                    {
-                        bBreak = !xRowLocate->moveToBookmark(pSelection[i]);
-                    }
-                    else
-                    {
-                        sal_Int32 nPos = 0;
-                        pSelection[i] >>= nPos;
-                        bBreak = !xResultSet->absolute(nPos);
-                    }
+                    bBreak = !xRowLocate->moveToBookmark(pSelection[i]);
                 }
                 else if(!i)
                     bBreak = !xResultSet->first();
@@ -1237,16 +1222,7 @@ void SwInsertDBColAutoPilot::DataToDoc( const Sequence<Any>& rSelection,
                 {
                     if(pSelection)
                     {
-                        if (isSelectionBookmarks)
-                        {
-                            bBreak = !xRowLocate->moveToBookmark(pSelection[i]);
-                        }
-                        else
-                        {
-                            sal_Int32 nPos = 0;
-                            pSelection[i] >>= nPos;
-                            bBreak = !xResultSet->absolute(nPos);
-                        }
+                        bBreak = !xRowLocate->moveToBookmark(pSelection[i]);
                     }
                     else if(!i)
                         bBreak = !xResultSet->first();
diff --git a/vcl/qa/cppunit/svm/svmtest.cxx b/vcl/qa/cppunit/svm/svmtest.cxx
index 55bdfc365c73..c8c6847b6ae0 100644
--- a/vcl/qa/cppunit/svm/svmtest.cxx
+++ b/vcl/qa/cppunit/svm/svmtest.cxx
@@ -172,7 +172,7 @@ static GDIMetaFile writeAndRead(GDIMetaFile& rMetaFile, const OUString& sUrl)
     // Turn on to output the SVM bitstreams to files (using the input URL)
     // to inspect the content or to create a reference file, otherwise leave
     // disabled for normal test runs.
-    static bool bOutputToFile = false;
+    static const bool bOutputToFile = false;
 
     if (bOutputToFile)
     {
diff --git a/vcl/source/filter/png/pngread.cxx b/vcl/source/filter/png/pngread.cxx
index a3f449b4f8ab..58acc12c8d60 100644
--- a/vcl/source/filter/png/pngread.cxx
+++ b/vcl/source/filter/png/pngread.cxx
@@ -1408,9 +1408,6 @@ void PNGReaderImpl::ImplDrawScanline( sal_uInt32 nXStart, sal_uInt32 nXAdd )
     }
     else // no palette => truecolor
     {
-        // #i122985# Added fast-lane implementations using CopyScanline with direct supported mem formats
-        static bool bCkeckDirectScanline(true);
-
         if( mbAlphaChannel )
         {
             // has RGB + alpha
@@ -1419,7 +1416,7 @@ void PNGReaderImpl::ImplDrawScanline( sal_uInt32 nXStart, sal_uInt32 nXAdd )
                 // ScanlineFormat::N32BitTcRgba
                 // only use DirectScanline when we have no preview shifting stuff and accesses to content and alpha
                 const bool bDoDirectScanline(
-                    bCkeckDirectScanline && !nXStart && 1 == nXAdd && !mnPreviewShift && mpMaskAcc);
+                    !nXStart && 1 == nXAdd && !mnPreviewShift && mpMaskAcc);
                 const bool bCustomColorTable(mpColorTable != mpDefaultColorTable);
 
                 if(bDoDirectScanline)
@@ -1566,7 +1563,7 @@ void PNGReaderImpl::ImplDrawScanline( sal_uInt32 nXStart, sal_uInt32 nXAdd )
             // ScanlineFormat::N24BitTcRgb
             // only use DirectScanline when we have no preview shifting stuff and access to content
             const bool bDoDirectScanline(
-                bCkeckDirectScanline && !nXStart && 1 == nXAdd && !mnPreviewShift);
+                !nXStart && 1 == nXAdd && !mnPreviewShift);
             const bool bCustomColorTable(mpColorTable != mpDefaultColorTable);
 
             if(bDoDirectScanline && !mpScanline)
diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx
index 4c6588460082..aad555dd5e02 100644
--- a/vcl/source/outdev/bitmap.cxx
+++ b/vcl/source/outdev/bitmap.cxx
@@ -1179,10 +1179,9 @@ void OutputDevice::DrawTransformedBitmapEx(
     const bool bMirroredX(basegfx::fTools::less(aScale.getX(), 0.0));
     const bool bMirroredY(basegfx::fTools::less(aScale.getY(), 0.0));
 
-    static bool bForceToOwnTransformer(false);
     const bool bMetafile = mpMetaFile != nullptr;
 
-    if(!bForceToOwnTransformer && !bRotated && !bSheared && !bMirroredX && !bMirroredY)
+    if(!bRotated && !bSheared && !bMirroredX && !bMirroredY)
     {
         // with no rotation, shear or mirroring it can be mapped to DrawBitmapEx
         // do *not* execute the mirroring here, it's done in the fallback
@@ -1215,7 +1214,7 @@ void OutputDevice::DrawTransformedBitmapEx(
     const basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * rTransformation);
     const bool bTryDirectPaint(!bInvert && !bBitmapChangedColor && !bMetafile );
 
-    if(!bForceToOwnTransformer && bTryDirectPaint)
+    if(bTryDirectPaint)
     {
         bDone = DrawTransformBitmapExDirect(aFullTransform, rBitmapEx);
     }
@@ -1223,7 +1222,7 @@ void OutputDevice::DrawTransformedBitmapEx(
     if(!bDone)
     {
         // take the fallback when no rotate and shear, but mirror (else we would have done this above)
-        if(!bForceToOwnTransformer && !bRotated && !bSheared)
+        if(!bRotated && !bSheared)
         {
             // with no rotation or shear it can be mapped to DrawBitmapEx
             // do *not* execute the mirroring here, it's done in the fallback
@@ -1258,7 +1257,6 @@ void OutputDevice::DrawTransformedBitmapEx(
 
         if(!aVisibleRange.isEmpty())
         {
-            static bool bDoSmoothAtAll(true);
             BitmapEx aTransformed(rBitmapEx);
 
             // #122923# when the result needs an alpha channel due to being rotated or sheared
@@ -1279,7 +1277,7 @@ void OutputDevice::DrawTransformedBitmapEx(
                 aFullTransform,
                 aVisibleRange,
                 fMaximumArea,
-                bDoSmoothAtAll);
+                /*bDoSmoothAtAll*/true);
             basegfx::B2DRange aTargetRange(0.0, 0.0, 1.0, 1.0);
 
             // get logic object target range
diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx
index 6f30a230b43a..33f70be753c9 100644
--- a/vcl/source/window/layout.cxx
+++ b/vcl/source/window/layout.cxx
@@ -222,8 +222,8 @@ void VclContainer::Command(const CommandEvent& rCEvt)
 
             if (bVisibleChildren)
             {
-                static bool bAddButtonsToMenu(true);
-                static bool bAddScreenshotButtonToMenu(true);
+                static bool bAddButtonsToMenu(true); // loplugin:constvars:ignore
+                static bool bAddScreenshotButtonToMenu(true); // loplugin:constvars:ignore
 
                 if (bAddButtonsToMenu || bAddScreenshotButtonToMenu)
                 {
diff --git a/vcl/unx/generic/app/wmadaptor.cxx b/vcl/unx/generic/app/wmadaptor.cxx
index 8ebacc422016..5cdc914a5bff 100644
--- a/vcl/unx/generic/app/wmadaptor.cxx
+++ b/vcl/unx/generic/app/wmadaptor.cxx
@@ -976,18 +976,13 @@ void WMAdaptor::setWMName( X11SalFrame* pFrame, const OUString& rWMName ) const
         aWMLocale = pLang ? pLang : "C";
     }
 
-    static bool bTrustXmb = true;
-
     char* pT = const_cast<char*>(aTitle.getStr());
     XTextProperty aProp = { nullptr, None, 0, 0 };
-    if( bTrustXmb )
-    {
-        XmbTextListToTextProperty( m_pDisplay,
-                                   &pT,
-                                   1,
-                                   XStdICCTextStyle,
-                                   &aProp );
-    }
+    XmbTextListToTextProperty( m_pDisplay,
+                               &pT,
+                               1,
+                               XStdICCTextStyle,
+                               &aProp );
 
     unsigned char const * pData = aProp.nitems ? aProp.value : reinterpret_cast<unsigned char const *>(aTitle.getStr());
     Atom nType = aProp.nitems ? aProp.encoding : XA_STRING;


More information about the Libreoffice-commits mailing list