[Libreoffice-commits] core.git: compilerplugins/clang desktop/source include/editeng include/vcl sd/source svtools/source sw/inc sw/source vcl/inc vcl/source writerfilter/source xmloff/inc

Noel Grandin (via logerrit) logerrit at kemper.freedesktop.org
Tue Aug 18 12:49:34 UTC 2020


 compilerplugins/clang/unusedvarsglobal.cxx               |  968 +++++++++++++++
 compilerplugins/clang/unusedvarsglobal.py                |  118 +
 compilerplugins/clang/unusedvarsglobal.untouched.results |  280 ++++
 desktop/source/splash/unxsplash.hxx                      |    4 
 include/editeng/flditem.hxx                              |    1 
 include/vcl/EnumContext.hxx                              |    1 
 sd/source/ui/inc/MasterPageObserver.hxx                  |    2 
 sd/source/ui/sidebar/PanelFactory.cxx                    |    2 
 svtools/source/control/inettbc.cxx                       |    2 
 sw/inc/calc.hxx                                          |    1 
 sw/inc/poolfmt.hxx                                       |    1 
 sw/inc/swtypes.hxx                                       |    4 
 sw/inc/viewsh.hxx                                        |    1 
 sw/source/filter/ww8/rtfsdrexport.cxx                    |    2 
 sw/source/uibase/inc/initui.hxx                          |   10 
 sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx    |    1 
 vcl/inc/driverblocklist.hxx                              |    1 
 vcl/source/window/EnumContext.cxx                        |    1 
 writerfilter/source/dmapper/DomainMapperTableHandler.cxx |    1 
 writerfilter/source/dmapper/TagLogger.hxx                |    2 
 xmloff/inc/PageMasterStyleMap.hxx                        |    2 
 xmloff/inc/XMLChartPropertySetMapper.hxx                 |    2 
 22 files changed, 1366 insertions(+), 41 deletions(-)

New commits:
commit 16d9d1d1122bbf9f6dc0748b41826a59a8551716
Author:     Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Mon Aug 17 21:41:33 2020 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Tue Aug 18 14:48:51 2020 +0200

    new loplugin:unusedvarsglobal
    
    I copied and modified the unusedfields plugin to find unused
    variables.
    
    Change-Id: I18ed6daa202da70a2e564e4fe4760aed7ce070ba
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100891
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/compilerplugins/clang/unusedvarsglobal.cxx b/compilerplugins/clang/unusedvarsglobal.cxx
new file mode 100644
index 000000000000..e5ca57c4ba5a
--- /dev/null
+++ b/compilerplugins/clang/unusedvarsglobal.cxx
@@ -0,0 +1,968 @@
+/* -*- 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 "config_clang.h"
+
+#include "plugin.hxx"
+#include "compat.hxx"
+#include "check.hxx"
+
+#if CLANG_VERSION >= 110000
+#include "clang/AST/ParentMapContext.h"
+#endif
+
+/**
+This performs two analyses:
+ (1) look for unused fields
+ (2) look for fields that are write-only
+
+We dmp a list of calls to methods, and a list of field definitions.
+Then we will post-process the 2 lists and find the set of unused methods.
+
+Be warned that it produces around 5G of log file.
+
+The process goes something like this:
+  $ make check
+  $ make FORCE_COMPILE_ALL=1 COMPILER_PLUGIN_TOOL='UnusedVarsGlobal' check
+  $ ./compilerplugins/clang/UnusedVarsGlobal.py
+
+and then
+  $ for dir in *; do make FORCE_COMPILE_ALL=1 UPDATE_FILES=$dir COMPILER_PLUGIN_TOOL='UnusedVarsGlobalremove' $dir; done
+to auto-remove the method declarations
+
+Note that the actual process may involve a fair amount of undoing, hand editing, and general messing around
+to get it to work :-)
+
+*/
+
+namespace
+{
+struct MyVarInfo
+{
+    std::string fieldName;
+    std::string fieldType;
+    std::string sourceLocation;
+};
+bool operator<(const MyVarInfo& lhs, const MyVarInfo& rhs)
+{
+    return std::tie(lhs.sourceLocation, lhs.fieldName)
+           < std::tie(rhs.sourceLocation, rhs.fieldName);
+}
+
+// try to limit the voluminous output a little
+static std::set<MyVarInfo> readFromSet;
+static std::set<MyVarInfo> writeToSet;
+static std::set<MyVarInfo> definitionSet;
+
+/**
+ * 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 UnusedVarsGlobal : public loplugin::FilteringPlugin<UnusedVarsGlobal>
+{
+public:
+    explicit UnusedVarsGlobal(loplugin::InstantiationData const& data)
+        : FilteringPlugin(data)
+    {
+    }
+
+    virtual void run() override;
+
+    bool shouldVisitTemplateInstantiations() const { return true; }
+    bool shouldVisitImplicitCode() const { return true; }
+
+    bool VisitVarDecl(const VarDecl*);
+    bool VisitDeclRefExpr(const DeclRefExpr*);
+    bool TraverseCXXMethodDecl(CXXMethodDecl*);
+    bool TraverseFunctionDecl(FunctionDecl*);
+    bool TraverseIfStmt(IfStmt*);
+
+private:
+    MyVarInfo niceName(const VarDecl*);
+    void checkIfReadFrom(const VarDecl* fieldDecl, const DeclRefExpr* declRefExpr);
+    void checkIfWrittenTo(const VarDecl* fieldDecl, const DeclRefExpr* declRefExpr);
+    bool isSomeKindOfZero(const Expr* arg);
+    bool checkForWriteWhenUsingCollectionType(const CXXMethodDecl* calleeMethodDecl);
+    bool IsPassedByNonConst(const VarDecl* fieldDecl, const Stmt* child, CallerWrapper callExpr,
+                            CalleeWrapper calleeFunctionDecl);
+    llvm::Optional<CalleeWrapper> getCallee(CallExpr const*);
+
+    // 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;
+};
+
+void UnusedVarsGlobal::run()
+{
+    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 MyVarInfo& s : readFromSet)
+        output += "read:\t" + s.sourceLocation + "\t" + s.fieldName + "\n";
+    for (const MyVarInfo& s : writeToSet)
+        output += "write:\t" + s.sourceLocation + "\t" + s.fieldName + "\n";
+    for (const MyVarInfo& s : definitionSet)
+        output
+            += "definition:\t" + s.fieldName + "\t" + s.fieldType + "\t" + s.sourceLocation + "\n";
+    std::ofstream myfile;
+    myfile.open(WORKDIR "/loplugin.unusedvarsglobal.log", std::ios::app | std::ios::out);
+    myfile << output;
+    myfile.close();
+}
+
+MyVarInfo UnusedVarsGlobal::niceName(const VarDecl* varDecl)
+{
+    MyVarInfo aInfo;
+
+    aInfo.fieldName = varDecl->getNameAsString();
+    // sometimes the name (if it's an anonymous thing) contains the full path of the build folder, which we don't need
+    size_t idx = aInfo.fieldName.find(SRCDIR);
+    if (idx != std::string::npos)
+    {
+        aInfo.fieldName = aInfo.fieldName.replace(idx, strlen(SRCDIR), "");
+    }
+    aInfo.fieldType = varDecl->getType().getAsString();
+
+    SourceLocation expansionLoc
+        = compiler.getSourceManager().getExpansionLoc(varDecl->getLocation());
+    StringRef name = getFilenameOfLocation(expansionLoc);
+    aInfo.sourceLocation
+        = std::string(name.substr(strlen(SRCDIR) + 1)) + ":"
+          + std::to_string(compiler.getSourceManager().getSpellingLineNumber(expansionLoc));
+    loplugin::normalizeDotDotInFilePath(aInfo.sourceLocation);
+
+    return aInfo;
+}
+
+bool UnusedVarsGlobal::VisitVarDecl(const VarDecl* varDecl)
+{
+    varDecl = varDecl->getCanonicalDecl();
+    if (isa<ParmVarDecl>(varDecl))
+        return true;
+    if (varDecl->isConstexpr())
+        return true;
+    if (!varDecl->getLocation().isValid() || ignoreLocation(varDecl))
+        return true;
+    // ignore stuff that forms part of the stable URE interface
+    if (isInUnoIncludeFile(compiler.getSourceManager().getSpellingLoc(varDecl->getLocation())))
+        return true;
+
+    auto initExpr = varDecl->getAnyInitializer();
+    if (initExpr && !isSomeKindOfZero(initExpr))
+        writeToSet.insert(niceName(varDecl));
+
+    definitionSet.insert(niceName(varDecl));
+    return true;
+}
+
+bool UnusedVarsGlobal::VisitDeclRefExpr(const DeclRefExpr* declRefExpr)
+{
+    const Decl* decl = declRefExpr->getDecl();
+    const VarDecl* varDecl = dyn_cast<VarDecl>(decl);
+    if (!varDecl)
+        return true;
+    if (isa<ParmVarDecl>(varDecl))
+        return true;
+    if (varDecl->isConstexpr())
+        return true;
+    varDecl = varDecl->getCanonicalDecl();
+    if (!varDecl->getLocation().isValid() || ignoreLocation(varDecl))
+        return true;
+    // ignore stuff that forms part of the stable URE interface
+    if (isInUnoIncludeFile(compiler.getSourceManager().getSpellingLoc(varDecl->getLocation())))
+        return true;
+    checkIfReadFrom(varDecl, declRefExpr);
+    checkIfWrittenTo(varDecl, declRefExpr);
+    return true;
+}
+
+/**
+ Does the expression being used to initialise a field value evaluate to
+ the same as a default value?
+ */
+bool UnusedVarsGlobal::isSomeKindOfZero(const Expr* arg)
+{
+    assert(arg);
+    if (arg->isValueDependent())
+        return false;
+    if (arg->getType().isNull())
+        return false;
+    if (isa<CXXDefaultArgExpr>(arg))
+        arg = dyn_cast<CXXDefaultArgExpr>(arg)->getExpr();
+    arg = arg->IgnoreParenCasts();
+    // ignore this, it seems to trigger an infinite recursion
+    if (isa<UnaryExprOrTypeTraitExpr>(arg))
+        return false;
+    if (auto cxxConstructExpr = dyn_cast<CXXConstructExpr>(arg))
+        return cxxConstructExpr->getConstructor()->isDefaultConstructor();
+    APSInt x1;
+    if (compat::EvaluateAsInt(arg, x1, compiler.getASTContext()))
+        return x1 == 0;
+    if (isa<CXXNullPtrLiteralExpr>(arg))
+        return true;
+    if (isa<MaterializeTemporaryExpr>(arg))
+    {
+        const CXXBindTemporaryExpr* strippedArg
+            = dyn_cast_or_null<CXXBindTemporaryExpr>(arg->IgnoreParenCasts());
+        if (strippedArg)
+        {
+            auto temp = dyn_cast<CXXTemporaryObjectExpr>(strippedArg->getSubExpr());
+            if (temp->getNumArgs() == 0)
+            {
+                if (loplugin::TypeCheck(temp->getType())
+                        .Class("OUString")
+                        .Namespace("rtl")
+                        .GlobalNamespace())
+                    return true;
+                if (loplugin::TypeCheck(temp->getType())
+                        .Class("OString")
+                        .Namespace("rtl")
+                        .GlobalNamespace())
+                    return true;
+                return false;
+            }
+        }
+    }
+
+    // Get the expression contents.
+    // This helps us find params which are always initialised with something like "OUString()".
+    SourceManager& SM = compiler.getSourceManager();
+    SourceLocation startLoc = compat::getBeginLoc(arg);
+    SourceLocation endLoc = compat::getEndLoc(arg);
+    const char* p1 = SM.getCharacterData(startLoc);
+    const char* p2 = SM.getCharacterData(endLoc);
+    if (!p1 || !p2 || (p2 - p1) < 0 || (p2 - p1) > 40)
+        return false;
+    unsigned n = Lexer::MeasureTokenLength(endLoc, SM, compiler.getLangOpts());
+    std::string s(p1, p2 - p1 + n);
+    // strip linefeed and tab characters so they don't interfere with the parsing of the log file
+    std::replace(s.begin(), s.end(), '\r', ' ');
+    std::replace(s.begin(), s.end(), '\n', ' ');
+    std::replace(s.begin(), s.end(), '\t', ' ');
+
+    // now normalize the value. For some params, like OUString, we can pass it as OUString() or "" and they are the same thing
+    if (s == "OUString()")
+        return true;
+    else if (s == "OString()")
+        return true;
+    else if (s == "aEmptyOUStr") //sw
+        return true;
+    else if (s == "EMPTY_OUSTRING") //sc
+        return true;
+    else if (s == "GetEmptyOUString()") //sc
+        return true;
+    return false;
+}
+
+static char easytolower(char in)
+{
+    if (in <= 'Z' && in >= 'A')
+        return in - ('Z' - 'z');
+    return in;
+}
+
+bool startswith(const std::string& rStr, const char* pSubStr)
+{
+    return rStr.compare(0, strlen(pSubStr), pSubStr) == 0;
+}
+
+bool UnusedVarsGlobal::TraverseCXXMethodDecl(CXXMethodDecl* cxxMethodDecl)
+{
+    auto copy2 = insideFunctionDecl;
+    insideFunctionDecl = cxxMethodDecl;
+    bool ret = RecursiveASTVisitor::TraverseCXXMethodDecl(cxxMethodDecl);
+    insideFunctionDecl = copy2;
+    return ret;
+}
+
+bool UnusedVarsGlobal::TraverseFunctionDecl(FunctionDecl* functionDecl)
+{
+    auto copy2 = insideFunctionDecl;
+    insideFunctionDecl = functionDecl;
+    bool ret = RecursiveASTVisitor::TraverseFunctionDecl(functionDecl);
+    insideFunctionDecl = copy2;
+    return ret;
+}
+
+bool UnusedVarsGlobal::TraverseIfStmt(IfStmt* ifStmt)
+{
+    VarDecl const* varDecl = nullptr;
+    Expr const* cond = ifStmt->getCond()->IgnoreParenImpCasts();
+
+    if (auto memberCallExpr = dyn_cast<CXXMemberCallExpr>(cond))
+    {
+        if (auto cxxConvert = dyn_cast_or_null<CXXConversionDecl>(memberCallExpr->getMethodDecl()))
+        {
+            if (cxxConvert->getConversionType()->isBooleanType())
+                if (auto declRefExpr = dyn_cast<DeclRefExpr>(
+                        memberCallExpr->getImplicitObjectArgument()->IgnoreParenImpCasts()))
+                    if ((varDecl = dyn_cast<VarDecl>(declRefExpr->getDecl())))
+                        insideConditionalCheckOfVarSet.push_back(varDecl);
+        }
+    }
+    else 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;
+}
+
+void UnusedVarsGlobal::checkIfReadFrom(const VarDecl* varDecl, const DeclRefExpr* declRefExpr)
+{
+    auto parentsRange = compiler.getASTContext().getParents(*declRefExpr);
+    const Stmt* child = declRefExpr;
+    const Stmt* parent
+        = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>();
+    // walk up the tree until we find something interesting
+    bool bPotentiallyReadFrom = 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're inside a CXXCtorInitializer or a VarDecl
+            auto parentsRange = compiler.getASTContext().getParents(*child);
+            if (parentsRange.begin() != parentsRange.end())
+            {
+                const Decl* decl = parentsRange.begin()->get<Decl>();
+                if (decl && (isa<CXXConstructorDecl>(decl) || isa<VarDecl>(decl)))
+                    bPotentiallyReadFrom = true;
+            }
+            if (!bPotentiallyReadFrom)
+                return;
+            break;
+        }
+        if (isa<CXXReinterpretCastExpr>(parent))
+        {
+            // once we see one of these, there is not much useful we can know
+            bPotentiallyReadFrom = 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 (declRefExpr->getType()->isArrayType() && op == UO_Deref)
+            {
+                // ignore, deref'ing an array does not count as a read
+            }
+            else if (op == UO_AddrOf || op == UO_Deref || op == UO_Plus || op == UO_Minus
+                     || op == UO_Not || op == UO_LNot)
+            {
+                bPotentiallyReadFrom = true;
+                break;
+            }
+            /* The following are technically reads, but from a code-sense they're more of a write/modify, so
+                ignore them to find interesting fields that only modified, not usefully read:
+                UO_PreInc / UO_PostInc / UO_PreDec / UO_PostDec
+                But we still walk up in case the result of the expression is used in a read sense.
+            */
+            walkUp();
+        }
+        else if (auto caseStmt = dyn_cast<CaseStmt>(parent))
+        {
+            bPotentiallyReadFrom = caseStmt->getLHS() == child || caseStmt->getRHS() == child;
+            break;
+        }
+        else if (auto ifStmt = dyn_cast<IfStmt>(parent))
+        {
+            bPotentiallyReadFrom = ifStmt->getCond() == child;
+            break;
+        }
+        else if (auto doStmt = dyn_cast<DoStmt>(parent))
+        {
+            bPotentiallyReadFrom = doStmt->getCond() == child;
+            break;
+        }
+        else if (auto arraySubscriptExpr = dyn_cast<ArraySubscriptExpr>(parent))
+        {
+            if (arraySubscriptExpr->getIdx() == child)
+            {
+                bPotentiallyReadFrom = true;
+                break;
+            }
+            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 (binaryOp->getLHS() == child && assignmentOp)
+                break;
+            else
+            {
+                bPotentiallyReadFrom = true;
+                break;
+            }
+        }
+        else if (auto operatorCallExpr = dyn_cast<CXXOperatorCallExpr>(parent))
+        {
+            auto op = operatorCallExpr->getOperator();
+            const bool assignmentOp = op == OO_Equal || op == OO_StarEqual || op == OO_SlashEqual
+                                      || op == OO_PercentEqual || op == OO_PlusEqual
+                                      || op == OO_MinusEqual || op == OO_LessLessEqual
+                                      || op == OO_AmpEqual || op == OO_CaretEqual
+                                      || op == OO_PipeEqual;
+            if (operatorCallExpr->getArg(0) == child && assignmentOp)
+                break;
+            else if (op == OO_GreaterGreaterEqual && operatorCallExpr->getArg(1) == child)
+                break; // this is a write-only call
+            else
+            {
+                bPotentiallyReadFrom = true;
+                break;
+            }
+        }
+        else if (auto cxxMemberCallExpr = dyn_cast<CXXMemberCallExpr>(parent))
+        {
+            bool bWriteOnlyCall = false;
+            const CXXMethodDecl* callee = cxxMemberCallExpr->getMethodDecl();
+            if (callee)
+            {
+                const Expr* tmp = dyn_cast<Expr>(child);
+                if (tmp->isBoundMemberFunction(compiler.getASTContext()))
+                {
+                    tmp = dyn_cast<MemberExpr>(tmp)->getBase();
+                }
+                if (cxxMemberCallExpr->getImplicitObjectArgument() == tmp)
+                {
+                    // FIXME perhaps a better solution here would be some kind of SAL_PARAM_WRITEONLY attribute
+                    // which we could scatter around.
+                    std::string name = callee->getNameAsString();
+                    std::transform(name.begin(), name.end(), name.begin(), easytolower);
+                    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 == "reset" || name == "clear" || name == "fill")
+                        // write-only modifications to collections
+                        bWriteOnlyCall = true;
+                    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
+                        bWriteOnlyCall = true;
+                }
+            }
+            if (!bWriteOnlyCall)
+                bPotentiallyReadFrom = true;
+            break;
+        }
+        else if (auto callExpr = dyn_cast<CallExpr>(parent))
+        {
+            bool bWriteOnlyCall = false;
+            // check for calls to ReadXXX(foo) type methods, where foo is write-only
+            auto callee = getCallee(callExpr);
+            if (callee)
+            {
+                // FIXME perhaps a better solution here would be some kind of SAL_PARAM_WRITEONLY attribute
+                // which we could scatter around.
+                std::string name = callee->getNameAsString();
+                std::transform(name.begin(), name.end(), name.begin(), easytolower);
+                if (startswith(name, "read"))
+                    // this is a write-only call
+                    bWriteOnlyCall = true;
+            }
+            if (!bWriteOnlyCall)
+                bPotentiallyReadFrom = true;
+            break;
+        }
+        else if (isa<ReturnStmt>(parent) || isa<CXXConstructExpr>(parent)
+                 || isa<ConditionalOperator>(parent) || isa<SwitchStmt>(parent)
+                 || isa<DeclStmt>(parent) || isa<WhileStmt>(parent) || isa<CXXNewExpr>(parent)
+                 || isa<ForStmt>(parent) || isa<InitListExpr>(parent)
+                 || isa<CXXDependentScopeMemberExpr>(parent) || isa<UnresolvedMemberExpr>(parent)
+                 || isa<MaterializeTemporaryExpr>(parent))
+        {
+            bPotentiallyReadFrom = true;
+            break;
+        }
+        else if (isa<CXXDeleteExpr>(parent) || isa<UnaryExprOrTypeTraitExpr>(parent)
+                 || isa<CXXUnresolvedConstructExpr>(parent) || isa<CompoundStmt>(parent)
+                 || isa<LabelStmt>(parent) || isa<CXXForRangeStmt>(parent)
+                 || isa<CXXTypeidExpr>(parent) || isa<DefaultStmt>(parent)
+                 || isa<GCCAsmStmt>(parent) || isa<LambdaExpr>(parent) // TODO
+                 || isa<CXXDefaultArgExpr>(parent) || isa<AtomicExpr>(parent)
+                 || isa<VAArgExpr>(parent) || isa<DeclRefExpr>(parent)
+#if CLANG_VERSION >= 80000
+                 || isa<ConstantExpr>(parent)
+#endif
+                 || isa<SubstNonTypeTemplateParmExpr>(parent))
+        {
+            break;
+        }
+        else
+        {
+            bPotentiallyReadFrom = true;
+            bDump = true;
+            break;
+        }
+    } while (true);
+
+    if (bDump)
+    {
+        report(DiagnosticsEngine::Warning, "oh dear, what can the matter be?",
+               compat::getBeginLoc(declRefExpr))
+            << declRefExpr->getSourceRange();
+        report(DiagnosticsEngine::Note, "parent over here", compat::getBeginLoc(parent))
+            << parent->getSourceRange();
+        parent->dump();
+        declRefExpr->dump();
+    }
+
+    if (bPotentiallyReadFrom)
+        readFromSet.insert(niceName(varDecl));
+}
+
+void UnusedVarsGlobal::checkIfWrittenTo(const VarDecl* varDecl, const DeclRefExpr* declRefExpr)
+{
+    // if we're inside a block that looks like
+    //   if (varDecl)
+    //       ...
+    // then writes to this field don't matter, because unless we find another write to this field, this field is dead
+    if (std::find(insideConditionalCheckOfVarSet.begin(), insideConditionalCheckOfVarSet.end(),
+                  varDecl)
+        != insideConditionalCheckOfVarSet.end())
+        return;
+
+    auto parentsRange = compiler.getASTContext().getParents(*declRefExpr);
+    const Stmt* child = declRefExpr;
+    const Stmt* parent
+        = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>();
+    // walk up the tree until we find something interesting
+    bool bPotentiallyWrittenTo = 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 = m_field;
+            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())
+                {
+                    bPotentiallyWrittenTo = true;
+                }
+            }
+            break;
+        }
+        if (isa<CXXReinterpretCastExpr>(parent))
+        {
+            // once we see one of these, there is not much useful we can know
+            bPotentiallyWrittenTo = 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)
+            {
+                bPotentiallyWrittenTo = true;
+            }
+            break;
+        }
+        else if (auto arraySubscriptExpr = dyn_cast<ArraySubscriptExpr>(parent))
+        {
+            if (arraySubscriptExpr->getIdx() == child)
+                break;
+            walkUp();
+        }
+        else if (auto operatorCallExpr = dyn_cast<CXXOperatorCallExpr>(parent))
+        {
+            auto callee = getCallee(operatorCallExpr);
+            if (callee)
+            {
+                // if calling a non-const operator on the field
+                auto calleeMethodDecl = callee->getAsCXXMethodDecl();
+                if (calleeMethodDecl && operatorCallExpr->getArg(0) == child)
+                {
+                    if (!calleeMethodDecl->isConst())
+                        bPotentiallyWrittenTo
+                            = checkForWriteWhenUsingCollectionType(calleeMethodDecl);
+                }
+                else if (IsPassedByNonConst(varDecl, child, operatorCallExpr, *callee))
+                {
+                    bPotentiallyWrittenTo = true;
+                }
+            }
+            else
+                bPotentiallyWrittenTo = true; // conservative, could improve
+            break;
+        }
+        else if (auto cxxMemberCallExpr = dyn_cast<CXXMemberCallExpr>(parent))
+        {
+            const CXXMethodDecl* calleeMethodDecl = cxxMemberCallExpr->getMethodDecl();
+            if (calleeMethodDecl)
+            {
+                // if calling a non-const method on the field
+                const Expr* tmp = dyn_cast<Expr>(child);
+                if (tmp->isBoundMemberFunction(compiler.getASTContext()))
+                {
+                    tmp = dyn_cast<MemberExpr>(tmp)->getBase();
+                }
+                if (cxxMemberCallExpr->getImplicitObjectArgument() == tmp)
+                {
+                    if (!calleeMethodDecl->isConst())
+                        bPotentiallyWrittenTo
+                            = checkForWriteWhenUsingCollectionType(calleeMethodDecl);
+                    break;
+                }
+                else if (IsPassedByNonConst(varDecl, child, cxxMemberCallExpr,
+                                            CalleeWrapper(calleeMethodDecl)))
+                    bPotentiallyWrittenTo = true;
+            }
+            else
+                bPotentiallyWrittenTo = true; // can happen in templates
+            break;
+        }
+        else if (auto cxxConstructExpr = dyn_cast<CXXConstructExpr>(parent))
+        {
+            if (IsPassedByNonConst(varDecl, child, cxxConstructExpr,
+                                   CalleeWrapper(cxxConstructExpr)))
+                bPotentiallyWrittenTo = true;
+            break;
+        }
+        else if (auto callExpr = dyn_cast<CallExpr>(parent))
+        {
+            auto callee = getCallee(callExpr);
+            if (callee)
+            {
+                if (IsPassedByNonConst(varDecl, child, callExpr, *callee))
+                    bPotentiallyWrittenTo = true;
+            }
+            else
+                bPotentiallyWrittenTo = true; // conservative, could improve
+            break;
+        }
+        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)
+                    bPotentiallyWrittenTo = true;
+                else if (loplugin::TypeCheck(binaryOp->getLHS()->getType())
+                             .LvalueReference()
+                             .NonConst())
+                    // if the LHS is a non-const reference, we could write to the field later on
+                    bPotentiallyWrittenTo = true;
+            }
+            break;
+        }
+        else if (isa<ReturnStmt>(parent))
+        {
+            if (insideFunctionDecl)
+            {
+                auto tc = loplugin::TypeCheck(insideFunctionDecl->getReturnType());
+                if (tc.LvalueReference().NonConst())
+                    bPotentiallyWrittenTo = true;
+            }
+            break;
+        }
+        else if (isa<ConditionalOperator>(parent) || isa<SwitchStmt>(parent)
+                 || isa<DeclStmt>(parent) || isa<WhileStmt>(parent) || isa<CXXNewExpr>(parent)
+                 || isa<ForStmt>(parent) || isa<InitListExpr>(parent)
+                 || isa<CXXDependentScopeMemberExpr>(parent) || isa<UnresolvedMemberExpr>(parent)
+                 || isa<MaterializeTemporaryExpr>(parent) || isa<IfStmt>(parent)
+                 || isa<DoStmt>(parent) || isa<CXXDeleteExpr>(parent)
+                 || isa<UnaryExprOrTypeTraitExpr>(parent) || isa<CXXUnresolvedConstructExpr>(parent)
+                 || isa<CompoundStmt>(parent) || isa<LabelStmt>(parent)
+                 || isa<CXXForRangeStmt>(parent) || isa<CXXTypeidExpr>(parent)
+                 || isa<DefaultStmt>(parent) || isa<GCCAsmStmt>(parent)
+#if CLANG_VERSION >= 80000
+                 || isa<ConstantExpr>(parent)
+#endif
+                 || isa<AtomicExpr>(parent) || isa<CXXDefaultArgExpr>(parent)
+                 || isa<VAArgExpr>(parent) || isa<DeclRefExpr>(parent)
+                 || isa<SubstNonTypeTemplateParmExpr>(parent) || isa<LambdaExpr>(parent)) // TODO
+        {
+            break;
+        }
+        else
+        {
+            bPotentiallyWrittenTo = true;
+            bDump = true;
+            break;
+        }
+    } while (true);
+
+    if (bDump)
+    {
+        report(DiagnosticsEngine::Warning, "oh dear, what can the matter be? writtenTo=%0",
+               compat::getBeginLoc(declRefExpr))
+            << bPotentiallyWrittenTo << declRefExpr->getSourceRange();
+        if (parent)
+        {
+            report(DiagnosticsEngine::Note, "parent over here", compat::getBeginLoc(parent))
+                << parent->getSourceRange();
+            parent->dump();
+        }
+        declRefExpr->dump();
+        varDecl->getType()->dump();
+    }
+
+    if (bPotentiallyWrittenTo)
+        writeToSet.insert(niceName(varDecl));
+}
+
+// return true if this not a collection type, or if it is a collection type, and we might be writing to it
+bool UnusedVarsGlobal::checkForWriteWhenUsingCollectionType(const CXXMethodDecl* calleeMethodDecl)
+{
+    auto const tc = loplugin::TypeCheck(calleeMethodDecl->getParent());
+    bool listLike = false, setLike = false, mapLike = false, cssSequence = false;
+    if (tc.Class("deque").StdNamespace() || tc.Class("list").StdNamespace()
+        || tc.Class("queue").StdNamespace() || tc.Class("vector").StdNamespace())
+    {
+        listLike = true;
+    }
+    else if (tc.Class("set").StdNamespace() || tc.Class("unordered_set").StdNamespace())
+    {
+        setLike = true;
+    }
+    else if (tc.Class("map").StdNamespace() || tc.Class("unordered_map").StdNamespace())
+    {
+        mapLike = true;
+    }
+    else if (tc.Class("Sequence")
+                 .Namespace("uno")
+                 .Namespace("star")
+                 .Namespace("sun")
+                 .Namespace("com")
+                 .GlobalNamespace())
+    {
+        cssSequence = true;
+    }
+    else
+        return true;
+
+    if (calleeMethodDecl->isOverloadedOperator())
+    {
+        auto oo = calleeMethodDecl->getOverloadedOperator();
+        if (oo == OO_Equal)
+            return true;
+        // This is operator[]. We only care about things that add elements to the collection.
+        // if nothing modifies the size of the collection, then nothing useful
+        // is stored in it.
+        if (listLike)
+            return false;
+        return true;
+    }
+
+    auto name = calleeMethodDecl->getName();
+    if (listLike || setLike || mapLike)
+    {
+        if (name == "reserve" || name == "shrink_to_fit" || name == "clear" || name == "erase"
+            || name == "pop_back" || name == "pop_front" || name == "front" || name == "back"
+            || name == "data" || name == "remove" || name == "remove_if" || name == "unique"
+            || name == "sort" || name == "begin" || name == "end" || name == "rbegin"
+            || name == "rend" || name == "at" || name == "find" || name == "equal_range"
+            || name == "lower_bound" || name == "upper_bound")
+            return false;
+    }
+    if (cssSequence)
+    {
+        if (name == "getArray" || name == "begin" || name == "end")
+            return false;
+    }
+
+    return true;
+}
+
+bool UnusedVarsGlobal::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> UnusedVarsGlobal::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>();
+}
+
+loplugin::Plugin::Registration<UnusedVarsGlobal> X("unusedvarsglobal", false);
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/compilerplugins/clang/unusedvarsglobal.py b/compilerplugins/clang/unusedvarsglobal.py
new file mode 100755
index 000000000000..1231edf9bd18
--- /dev/null
+++ b/compilerplugins/clang/unusedvarsglobal.py
@@ -0,0 +1,118 @@
+#!/usr/bin/python2
+
+import sys
+import re
+import io
+
+definitionSet = set()
+readFromSet = set()
+writeToSet = set()
+defToTypeMap = dict()
+
+def parseFieldInfo( tokens ):
+    return (tokens[1].strip(), tokens[2].strip())
+
+with io.open("workdir/loplugin.unusedvarsglobal.log", "rb", buffering=1024*1024) as txt:
+    for line in txt:
+        try:
+            tokens = line.strip().split("\t")
+            if tokens[0] == "definition:":
+                srcLoc = tokens[3]
+                # ignore external source code
+                if (srcLoc.startswith("external/")):
+                    continue
+                # ignore build folder
+                if (srcLoc.startswith("workdir/")):
+                    continue
+                varname = tokens[1].strip()
+                vartype = tokens[2].strip()
+                if vartype.startswith("const "):
+                    vartype = vartype[6:]
+                if vartype.startswith("class "):
+                    vartype = vartype[6:]
+                if vartype.startswith("struct "):
+                    vartype = vartype[7:]
+                if vartype.startswith("::"):
+                    vartype = vartype[2:]
+                fieldInfo = (srcLoc, varname)
+                definitionSet.add(fieldInfo)
+                defToTypeMap[fieldInfo] = vartype
+            elif tokens[0] == "read:":
+                if len(tokens) == 3:
+                    readFromSet.add(parseFieldInfo(tokens))
+            elif tokens[0] == "write:":
+                if len(tokens) == 3:
+                    writeToSet.add(parseFieldInfo(tokens))
+            else:
+                print( "unknown line: " + line)
+        except IndexError:
+            print "problem with line " + line.strip()
+            raise
+
+definitionSet2 = set()
+for d in definitionSet:
+    varname = d[1]
+    vartype = defToTypeMap[d]
+    if len(varname) == 0:
+        continue
+    if varname.startswith("autoRegister"): # auto-generated CPPUNIT stuff
+        continue
+    if vartype in ["css::uno::ContextLayer", "SolarMutexGuard", "SolarMutexReleaser", "OpenGLZone"]:
+        continue
+    if vartype in ["PreDefaultWinNoOpenGLZone", "SchedulerGuard", "SkiaZone", "OpenGLVCLContextZone"]:
+        continue
+    if vartype in ["SwXDispatchProviderInterceptor::DispatchMutexLock_Impl", "SfxObjectShellLock", "OpenCLZone"]:
+        continue
+    if vartype in ["OpenCLInitialZone", "pyuno::PyThreadDetach", "SortRefUpdateSetter", "oglcanvas::TransformationPreserver"]:
+        continue
+    if vartype in ["StackHack"]:
+        continue
+    definitionSet2.add(d)
+
+# Calculate untouched
+untouchedSet = set()
+for d in definitionSet2:
+    if d in readFromSet or d in writeToSet:
+        continue
+    varname = d[1]
+    if len(varname) == 0:
+        continue
+    untouchedSet.add(d)
+
+writeonlySet = set()
+for d in definitionSet2:
+    if d in readFromSet or d in untouchedSet:
+        continue
+    writeonlySet.add(d)
+
+readonlySet = set()
+for d in definitionSet2:
+    if d in writeToSet or d in untouchedSet:
+        continue
+    readonlySet.add(d)
+
+# sort the results using a "natural order" so sequences like [item1,item2,item10] sort nicely
+def natural_sort_key(s, _nsre=re.compile('([0-9]+)')):
+    return [int(text) if text.isdigit() else text.lower()
+            for text in re.split(_nsre, s)]
+
+# sort results by name and line number
+tmp1list = sorted(untouchedSet, key=lambda v: natural_sort_key(v[0]))
+tmp2list = sorted(writeonlySet, key=lambda v: natural_sort_key(v[0]))
+tmp3list = sorted(readonlySet, key=lambda v: natural_sort_key(v[0]))
+
+# print out the results
+with open("compilerplugins/clang/unusedvarsglobal.untouched.results", "wt") as f:
+    for t in tmp1list:
+        f.write( t[0] + "\n" )
+        f.write( "    " + defToTypeMap[t] + " " + t[1] + "\n" )
+with open("compilerplugins/clang/unusedvarsglobal.writeonly.results", "wt") as f:
+    for t in tmp2list:
+        f.write( t[0] + "\n" )
+        f.write( "    " + defToTypeMap[t] + " " + t[1] + "\n" )
+with open("compilerplugins/clang/unusedvarsglobal.readonly.results", "wt") as f:
+    for t in tmp3list:
+        f.write( t[0] + "\n" )
+        f.write( "    " + defToTypeMap[t] + " " + t[1] + "\n" )
+
+
diff --git a/compilerplugins/clang/unusedvarsglobal.untouched.results b/compilerplugins/clang/unusedvarsglobal.untouched.results
new file mode 100644
index 000000000000..f8fcbf0f32a7
--- /dev/null
+++ b/compilerplugins/clang/unusedvarsglobal.untouched.results
@@ -0,0 +1,280 @@
+basic/source/classes/sbxmod.cxx:1714
+    (anonymous namespace)::ErrorHdlResetter aErrHdl
+canvas/workben/canvasdemo.cxx:672
+    (anonymous namespace)::DemoApp aApp
+chart2/source/view/main/DrawModelWrapper.cxx:82
+    E3dObjFactory aObjFactory
+connectivity/source/drivers/evoab2/EApi.h:52
+    gconstpointer (*)(EContact *, EContactField) e_contact_get_const
+connectivity/source/drivers/postgresql/pq_baseresultset.hxx:52
+    sal_Int32 BASERESULTSET_CURSOR_NAME
+connectivity/source/drivers/postgresql/pq_preparedstatement.hxx:55
+    sal_Int32 PREPARED_STATEMENT_CURSOR_NAME
+connectivity/source/drivers/postgresql/pq_statement.hxx:53
+    sal_Int32 STATEMENT_CURSOR_NAME
+cppu/source/uno/check.cxx:315
+    (anonymous namespace)::BinaryCompatible_Impl aTest
+dbaccess/source/filter/xml/xmlfilter.cxx:230
+    dbaxml::(anonymous namespace)::FocusWindowWaitGuard aWindowFocusGuard
+dbaccess/source/ui/inc/TypeInfo.hxx:31
+    sal_uInt16 TYPE_UNKNOWN
+desktop/source/app/sofficemain.cxx:71
+    desktop::Desktop aDesktop
+desktop/source/splash/unxsplash.hxx:33
+    desktop::UnxSplashScreen * m_pINSTANCE
+desktop/source/splash/unxsplash.hxx:35
+    osl::Mutex m_aMutex
+desktop/unx/source/splashx.c:301
+    uint32_t tmp
+desktop/unx/source/splashx.c:315
+    uint32_t tmp
+desktop/unx/source/splashx.c:334
+    uint32_t tmp
+desktop/unx/source/splashx.c:343
+    uint32_t tmp
+drawinglayer/source/tools/emfppen.hxx:31
+    sal_uInt32 EmfPlusLineJoinTypeMiter
+drawinglayer/source/tools/emfppen.hxx:36
+    sal_Int32 EmfPlusLineStyleSolid
+extensions/source/scanner/sane.cxx:712
+    int __d0
+extensions/source/scanner/sane.cxx:712
+    int __d1
+filter/source/pdf/pdffilter.cxx:222
+    (anonymous namespace)::FocusWindowWaitCursor aCur
+framework/source/services/ContextChangeEventMultiplexer.cxx:381
+    framework::(anonymous namespace)::Hook g_hook
+framework/source/uiconfiguration/windowstateconfiguration.cxx:63
+    sal_Int16 PROPERTY_LOCKED
+hwpfilter/source/nodes.h:92
+    int count
+i18nlangtag/source/languagetag/languagetag.cxx:848
+    Runner aRunner
+include/editeng/flditem.hxx:43
+    sal_Int32 UNKNOWN_FIELD
+include/oox/helper/helper.hxx:87
+    sal_Int16 API_LINE_SOLID
+include/oox/helper/helper.hxx:92
+    sal_Int16 API_LINE_NONE
+include/oox/helper/helper.hxx:98
+    sal_Int16 API_ESCAPE_NONE
+include/oox/ole/axcontrol.hxx:123
+    sal_Int32 AX_PICALIGN_TOPLEFT
+include/vcl/EnumContext.hxx:139
+    sal_Int32 OptimalMatch
+lotuswordpro/source/filter/LotusWordProImportFilter.cxx:74
+    uno::Reference<XDocumentHandler> xHandler
+lotuswordpro/source/filter/lwpsilverbullet.hxx:71
+    sal_uInt16 NUMCHAR_none
+oox/source/dump/oledumper.cxx:163
+    sal_uInt16 OLEPROP_TYPE_SIMPLE
+oox/source/ole/olehelper.cxx:67
+    sal_uInt32 OLE_COLORTYPE_CLIENT
+pyuno/source/loader/pyuno_loader.cxx:240
+    pyuno_loader::(anonymous namespace)::PythonInit s_Init
+pyuno/source/module/pyuno.cxx:1505
+    pyuno::Runtime runtime
+pyuno/source/module/pyuno_gc.cxx:45
+    pyuno::(anonymous namespace)::StaticDestructorGuard guard
+pyuno/source/module/pyuno_struct.cxx:251
+    pyuno::Runtime runtime
+sal/osl/all/utility.cxx:45
+    osl::(anonymous namespace)::OGlobalTimer aGlobalTimer
+sal/qa/osl/file/osl_File.cxx:5199
+    (anonymous namespace)::GlobalObject theGlobalObject
+sal/qa/osl/pipe/osl_Pipe.cxx:875
+    osl_StreamPipe::(anonymous namespace)::Pipe_DataSink_Thread myDataSinkThread
+sal/qa/OStringBuffer/rtl_String_Const.h:118
+    sal_Int32 kTestStr25Len
+sal/rtl/cmdargs.cxx:46
+    (anonymous namespace)::ArgHolder argHolder
+salhelper/qa/test_api.cxx:171
+    salhelper::ORealDynamicLoader * p
+sc/qa/unit/tiledrendering/tiledrendering.cxx:612
+    (anonymous namespace)::ViewCallback aView2
+sc/qa/unit/tiledrendering/tiledrendering.cxx:651
+    (anonymous namespace)::ViewCallback aView2
+sc/qa/unit/tiledrendering/tiledrendering.cxx:746
+    (anonymous namespace)::ViewCallback aView1
+sc/qa/unit/tiledrendering/tiledrendering.cxx:758
+    (anonymous namespace)::ViewCallback aView2
+sc/qa/unit/tiledrendering/tiledrendering.cxx:780
+    (anonymous namespace)::ViewCallback aView1
+sc/qa/unit/tiledrendering/tiledrendering.cxx:1152
+    (anonymous namespace)::ViewCallback aView1
+sc/qa/unit/tiledrendering/tiledrendering.cxx:1158
+    (anonymous namespace)::ViewCallback aView2
+sc/qa/unit/tiledrendering/tiledrendering.cxx:1216
+    (anonymous namespace)::ViewCallback aView1
+sc/qa/unit/tiledrendering/tiledrendering.cxx:1222
+    (anonymous namespace)::ViewCallback aView2
+sc/qa/unit/ucalc_sort.cxx:1027
+    SortRefNoUpdateSetter aUpdateSet
+sc/qa/unit/ucalc_sort.cxx:1336
+    SortRefNoUpdateSetter aUpdateSet
+sc/qa/unit/ucalc_sort.cxx:1474
+    SortRefNoUpdateSetter aUpdateSet
+sc/qa/unit/ucalc_sort.cxx:1674
+    SortRefNoUpdateSetter aUpdateSet
+sc/source/filter/inc/biffhelper.hxx:401
+    sal_uInt16 BIFF2_ID_DIMENSION
+sc/source/filter/inc/biffhelper.hxx:539
+    sal_uInt16 BIFF_ID_OBJEND
+sc/source/filter/inc/biffhelper.hxx:575
+    sal_uInt8 BIFF_DATATYPE_EMPTY
+sc/source/filter/inc/biffhelper.hxx:581
+    sal_uInt8 BIFF_BOOLERR_BOOL
+sc/source/filter/inc/defnamesbuffer.hxx:37
+    sal_Unicode BIFF_DEFNAME_CONSOLIDATEAREA
+sc/source/filter/inc/formulabase.hxx:61
+    sal_uInt8 BIFF_TOKID_NONE
+sc/source/filter/inc/formulabase.hxx:96
+    sal_uInt8 BIFF_TOKID_ARRAY
+sc/source/filter/inc/formulabase.hxx:121
+    sal_uInt8 BIFF_TOK_ARRAY_DOUBLE
+sc/source/filter/inc/formulabase.hxx:139
+    sal_uInt8 BIFF_TOK_ATTR_SPACE_SP
+sc/source/filter/inc/xlchart.hxx:198
+    sal_uInt16 EXC_CHFRBLOCK_FRAME_STANDARD
+sc/source/filter/inc/xlchart.hxx:227
+    sal_uInt16 EXC_CHSERIES_DATE
+sc/source/filter/inc/xlchart.hxx:335
+    sal_uInt8 EXC_CHLEGEND_CLOSE
+sc/source/filter/inc/xlchart.hxx:386
+    sal_uInt16 EXC_CHCHARTLINE_DROP
+sc/source/filter/inc/xlchart.hxx:453
+    sal_uInt16 EXC_CHDEFTEXT_TEXTLABEL
+sc/source/filter/inc/xlchart.hxx:641
+    sal_uInt16 EXC_CHFRAMEPOS_POINTS
+sc/source/filter/inc/xlchart.hxx:682
+    sal_uInt8 EXC_CHSERERR_END_BLANK
+sc/source/filter/inc/xlconst.hxx:127
+    sal_Int32 EXC_RK_DBL
+sc/source/filter/inc/xlcontent.hxx:40
+    sal_uInt16 EXC_FILEPASS_BIFF5
+sc/source/filter/inc/xlescher.hxx:99
+    sal_uInt8 EXC_OBJ_ARROW_NONE
+sc/source/filter/inc/xlescher.hxx:105
+    sal_uInt8 EXC_OBJ_ARROW_NARROW
+sc/source/filter/inc/xlescher.hxx:197
+    sal_uInt16 EXC_OBJ_DROPDOWN_LISTBOX
+sc/source/filter/inc/xlname.hxx:48
+    sal_Unicode EXC_BUILTIN_CONSOLIDATEAREA
+sc/source/filter/oox/externallinkbuffer.cxx:52
+    sal_uInt16 BIFF12_EXTERNALBOOK_BOOK
+sc/source/filter/oox/stylesbuffer.cxx:135
+    sal_uInt8 BIFF12_COLOR_AUTO
+sc/source/filter/oox/stylesbuffer.cxx:163
+    sal_uInt16 BIFF12_DXF_FILL_PATTERN
+sc/source/filter/oox/stylesbuffer.cxx:203
+    sal_uInt8 BIFF_FONTUNDERL_NONE
+sc/source/ui/vba/excelvbahelper.cxx:160
+    ooo::vba::excel::(anonymous namespace)::PasteCellsWarningReseter resetWarningBox
+sc/source/ui/vba/excelvbahelper.cxx:211
+    ooo::vba::excel::(anonymous namespace)::PasteCellsWarningReseter resetWarningBox
+sd/qa/unit/tiledrendering/tiledrendering.cxx:1462
+    (anonymous namespace)::ViewCallback aView1
+sd/qa/unit/tiledrendering/tiledrendering.cxx:1915
+    (anonymous namespace)::ViewCallback aView1
+sd/qa/unit/tiledrendering/tiledrendering.cxx:1923
+    (anonymous namespace)::ViewCallback aView2
+sd/source/ui/animations/CustomAnimationDialog.hxx:29
+    sal_Int32 nHandleSound
+sd/source/ui/inc/MasterPageObserver.hxx:79
+    osl::Mutex maMutex
+sd/source/ui/sidebar/PanelFactory.cxx:47
+    Reference<lang::XEventListener> mxControllerDisposeListener
+sfx2/source/appl/shutdownicon.cxx:663
+    sal_Int32 PROPHANDLE_TERMINATEVETOSTATE
+sfx2/source/doc/objstor.cxx:573
+    FontLockGuard aFontLockGuard
+sfx2/source/view/lokhelper.cxx:127
+    (anonymous namespace)::DisableCallbacks dc
+soltools/cpp/cpp.h:239
+    int Lflag
+soltools/mkdepend/parse.c:40
+    symhash * maininclist
+soltools/mkdepend/pr.c:34
+    int width
+starmath/source/mathmlimport.cxx:2717
+    uno::Reference<beans::XPropertySet> xInfoSet
+svl/qa/unit/items/test_IndexedStyleSheets.cxx:74
+    svl::IndexedStyleSheets iss
+svtools/source/control/inettbc.cxx:87
+    osl::Mutex * pDirMutex
+svx/source/gallery2/galctrl.cxx:244
+    GalleryProgress aProgress
+svx/source/gengal/gengal.cxx:323
+    (anonymous namespace)::GalApp aGalApp
+sw/inc/calc.hxx:88
+    char [] sCalc_Tdif
+sw/inc/poolfmt.hxx:64
+    sal_uInt16 POOL_FMT
+sw/inc/swtypes.hxx:101
+    SwPathFinder * pPathFinder
+sw/inc/viewsh.hxx:167
+    vcl::DeleteOnDeinit<VclPtr<vcl::Window> > mpCareWindow
+sw/qa/extras/ooxmlexport/ooxmlexport8.cxx:405
+    BorderTest borderTest
+sw/qa/extras/rtfexport/rtfexport2.cxx:548
+    BorderTest borderTest
+sw/qa/extras/ww8export/ww8export.cxx:266
+    BorderTest borderTest
+sw/source/core/layout/paintfrm.cxx:3922
+    (anonymous namespace)::BorderLinesGuard blg
+sw/source/core/text/frmform.cxx:1801
+    (anonymous namespace)::FormatLevel aLevel
+sw/source/core/view/viewsh.cxx:706
+    SwSaveSetLRUOfst aSaveLRU
+sw/source/core/view/viewsh.cxx:983
+    SwSaveSetLRUOfst aSaveLRU
+sw/source/filter/basflt/shellio.cxx:733
+    SwPauseThreadStarting aPauseThreadStarting
+sw/source/filter/html/swhtml.cxx:5596
+    (anonymous namespace)::FontCacheGuard aFontCacheGuard
+sw/source/filter/ww8/rtfsdrexport.cxx:489
+    char *[] pShapeTypes
+sw/source/filter/ww8/ww8par.cxx:6264
+    (anonymous namespace)::FontCacheGuard aFontCacheGuard
+sw/source/filter/xml/xmlexp.cxx:98
+    SwPauseThreadStarting aPauseThreadStarting
+sw/source/uibase/inc/initui.hxx:33
+    SwThesaurus * pThes
+sw/source/uibase/lingu/hhcwrp.cxx:123
+    (anonymous namespace)::SwKeepConversionDirectionStateContext aContext
+sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx:326
+    svx::sidebar::TreeNode aChild
+vcl/backendtest/VisualBackendTest.cxx:745
+    (anonymous namespace)::VisualBackendTestApp aApplication
+vcl/inc/driverblocklist.hxx:96
+    uint64_t allDriverVersions
+vcl/qa/cppunit/BitmapScaleTest.cxx:288
+    BitmapSymmetryCheck aBitmapSymmetryCheck
+vcl/source/outdev/font.cxx:156
+    (anonymous namespace)::UpdateFontsGuard aUpdateFontsGuard
+vcl/source/uipreviewer/previewer.cxx:113
+    (anonymous namespace)::UIPreviewApp aApp
+vcl/unx/generic/app/saldata.cxx:314
+    int __d0
+vcl/unx/generic/app/saldata.cxx:314
+    int __d1
+vcl/unx/generic/app/saldata.cxx:315
+    int __d1
+vcl/unx/generic/app/saldata.cxx:315
+    int __d0
+vcl/workben/icontest.cxx:216
+    (anonymous namespace)::IconTestApp aApp
+vcl/workben/mtfdemo.cxx:162
+    (anonymous namespace)::DemoMtfApp aApp
+vcl/workben/vcldemo.cxx:2445
+    (anonymous namespace)::DemoApp aApp
+writerfilter/source/dmapper/DomainMapperTableHandler.cxx:825
+    std::optional<PropertyMap::Property> oRowCellBorder
+writerfilter/source/dmapper/TagLogger.hxx:35
+    tools::SvRef<TagLogger> instance
+xmloff/inc/PageMasterStyleMap.hxx:193
+    XMLPropertyMapEntry [] aXMLPageMasterHeaderImportStyleMap
+xmloff/inc/PageMasterStyleMap.hxx:194
+    XMLPropertyMapEntry [] aXMLPageMasterFooterImportStyleMap
+xmloff/inc/XMLChartPropertySetMapper.hxx:28
+    XMLPropertyMapEntry [] aXMLChartPropMap
diff --git a/desktop/source/splash/unxsplash.hxx b/desktop/source/splash/unxsplash.hxx
index fa7ce196cda4..cf822d287c8d 100644
--- a/desktop/source/splash/unxsplash.hxx
+++ b/desktop/source/splash/unxsplash.hxx
@@ -30,10 +30,6 @@ private:
 
     virtual ~UnxSplashScreen() override;
 
-    static  UnxSplashScreen *m_pINSTANCE;
-
-    static osl::Mutex m_aMutex;
-
     FILE *m_pOutFd;
 
 public:
diff --git a/include/editeng/flditem.hxx b/include/editeng/flditem.hxx
index 2f44c8e2522b..59bb1c54e667 100644
--- a/include/editeng/flditem.hxx
+++ b/include/editeng/flditem.hxx
@@ -40,7 +40,6 @@ class MetaAction;
 class EDITENG_DLLPUBLIC SvxFieldData
 {
 public:
-    static const sal_Int32 UNKNOWN_FIELD;
 
     static SvxFieldData* Create(const css::uno::Reference<css::text::XTextContent>& xContent);
 
diff --git a/include/vcl/EnumContext.hxx b/include/vcl/EnumContext.hxx
index 3609640fe17f..1c356979d858 100644
--- a/include/vcl/EnumContext.hxx
+++ b/include/vcl/EnumContext.hxx
@@ -136,7 +136,6 @@ public:
         wildcards we introduce an integer evaluation for matches.
     */
     const static sal_Int32 NoMatch;
-    const static sal_Int32 OptimalMatch;
 
     static Application GetApplicationEnum (const OUString& rsApplicationName);
     static const OUString& GetApplicationName (const Application eApplication);
diff --git a/sd/source/ui/inc/MasterPageObserver.hxx b/sd/source/ui/inc/MasterPageObserver.hxx
index ae8267f30b40..4febb242aa21 100644
--- a/sd/source/ui/inc/MasterPageObserver.hxx
+++ b/sd/source/ui/inc/MasterPageObserver.hxx
@@ -76,8 +76,6 @@ public:
     void RemoveEventListener (const Link<MasterPageObserverEvent&,void>& rEventListener);
 
 private:
-    static ::osl::Mutex maMutex;
-
     class Implementation;
     ::std::unique_ptr<Implementation> mpImpl;
 
diff --git a/sd/source/ui/sidebar/PanelFactory.cxx b/sd/source/ui/sidebar/PanelFactory.cxx
index d0b91cbbea29..554d4f1c2b73 100644
--- a/sd/source/ui/sidebar/PanelFactory.cxx
+++ b/sd/source/ui/sidebar/PanelFactory.cxx
@@ -44,8 +44,6 @@ using namespace ::sd::framework;
 
 namespace sd::sidebar {
 
-static Reference<lang::XEventListener> mxControllerDisposeListener;
-
 //----- PanelFactory --------------------------------------------------------
 
 PanelFactory::PanelFactory()
diff --git a/svtools/source/control/inettbc.cxx b/svtools/source/control/inettbc.cxx
index 7192bd6271c0..eb14db000011 100644
--- a/svtools/source/control/inettbc.cxx
+++ b/svtools/source/control/inettbc.cxx
@@ -84,8 +84,6 @@ public:
 
 class SvtMatchContext_Impl: public salhelper::Thread
 {
-    static ::osl::Mutex*            pDirMutex;
-
     std::vector<OUString>           aPickList;
     std::vector<OUString>           aCompletions;
     std::vector<OUString>           aURLs;
diff --git a/sw/inc/calc.hxx b/sw/inc/calc.hxx
index 86e33f4cb618..979e68b0421d 100644
--- a/sw/inc/calc.hxx
+++ b/sw/inc/calc.hxx
@@ -85,7 +85,6 @@ extern const char sCalc_Tan[];
 extern const char sCalc_Asin[];
 extern const char sCalc_Acos[];
 extern const char sCalc_Atan[];
-extern const char sCalc_Tdif[];
 extern const char sCalc_Round[];
 extern const char sCalc_Date[];
 
diff --git a/sw/inc/poolfmt.hxx b/sw/inc/poolfmt.hxx
index 44d9214fe0f2..799134fd5017 100644
--- a/sw/inc/poolfmt.hxx
+++ b/sw/inc/poolfmt.hxx
@@ -61,7 +61,6 @@ const sal_uInt16 POOLGRP_NOCOLLID       =  (1 << 10);
 /// POLLCOLL-groups:
 
 const sal_uInt16 USER_FMT               =  (1 << 15);
-const sal_uInt16 POOL_FMT               =  (0 << 15);
 
 const sal_uInt16 COLL_TEXT_BITS         =  (1 << 11);
 const sal_uInt16 COLL_LISTS_BITS        =  (2 << 11);
diff --git a/sw/inc/swtypes.hxx b/sw/inc/swtypes.hxx
index 0f7d3af3e962..f457004570f7 100644
--- a/sw/inc/swtypes.hxx
+++ b/sw/inc/swtypes.hxx
@@ -96,10 +96,6 @@ const sal_uInt8 MAXLEVEL = 10;
 
 const sal_uInt8 NO_NUMLEVEL  = 0x20;    // "or" with the levels.
 
-// pPathFinder is initialized by the UI.
-// The class delivers all paths needed.
-extern SwPathFinder *pPathFinder;
-
 //  Values for indents at numbering and bullet lists.
 //  (For more levels the values have to be multiplied with the levels+1;
 //  levels 0 ..4!)
diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx
index fe3fee74bcea..23409190bdf8 100644
--- a/sw/inc/viewsh.hxx
+++ b/sw/inc/viewsh.hxx
@@ -164,7 +164,6 @@ class SW_DLLPUBLIC SwViewShell : public sw::Ring<SwViewShell>
 
 protected:
     static ShellResource*      mpShellRes;      ///< Resources for the Shell.
-    static vcl::DeleteOnDeinit< VclPtr<vcl::Window> > mpCareWindow;    ///< Avoid this window.
     static vcl::DeleteOnDeinit< std::shared_ptr<weld::Window> > mpCareDialog;    ///< Avoid this window.
 
     SwRect                  maVisArea;       ///< The modern version of VisArea.
diff --git a/sw/source/filter/ww8/rtfsdrexport.cxx b/sw/source/filter/ww8/rtfsdrexport.cxx
index 8f15b03b9102..d6ddc0d47d91 100644
--- a/sw/source/filter/ww8/rtfsdrexport.cxx
+++ b/sw/source/filter/ww8/rtfsdrexport.cxx
@@ -486,8 +486,6 @@ void RtfSdrExport::AddRectangleDimensions(OStringBuffer& rBuffer,
     rBuffer.append(OOO_STRING_SVTOOLS_RTF_SHPBOTTOM).append(rRectangle.Bottom());
 }
 
-extern const char* pShapeTypes[];
-
 static void lcl_AppendSP(OStringBuffer& rRunText, const char cName[], const OString& rValue)
 {
     rRunText.append('{')
diff --git a/sw/source/uibase/inc/initui.hxx b/sw/source/uibase/inc/initui.hxx
index 5f2b145eafb8..c9eec95d3bc3 100644
--- a/sw/source/uibase/inc/initui.hxx
+++ b/sw/source/uibase/inc/initui.hxx
@@ -22,16 +22,6 @@
 #include <swdllapi.h>
 #include <rtl/ustring.hxx>
 
-/*
- * Forward Declarations
- */
-class SwThesaurus;
-
-/*
- * Extern Definitions
- */
-extern  SwThesaurus*    pThes;
-
 SW_DLLPUBLIC const OUString& GetCurrGlosGroup();
 SW_DLLPUBLIC void SetCurrGlosGroup(const OUString& sStr);
 
diff --git a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
index 3af99a1fb9e6..4fa626d3cebf 100644
--- a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
+++ b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
@@ -323,7 +323,6 @@ static svx::sidebar::TreeNode BorderToTreeNode(const OUString& rName, const css:
 {
     table::BorderLine2 aBorder;
     rVal >>= aBorder;
-    svx::sidebar::TreeNode aChild;
     svx::sidebar::TreeNode aCurNode;
     aCurNode.sNodeName = PropertyNametoRID(rName);
     aCurNode.NodeType = svx::sidebar::TreeNode::ComplexProperty;
diff --git a/vcl/inc/driverblocklist.hxx b/vcl/inc/driverblocklist.hxx
index d8f8a40dfdbd..f28dc418383a 100644
--- a/vcl/inc/driverblocklist.hxx
+++ b/vcl/inc/driverblocklist.hxx
@@ -93,7 +93,6 @@ struct DriverInfo
     /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
     uint64_t mnDriverVersion;
     uint64_t mnDriverVersionMax;
-    static uint64_t allDriverVersions;
 
     OUString maSuggestedVersion;
     OUString maMsg;
diff --git a/vcl/source/window/EnumContext.cxx b/vcl/source/window/EnumContext.cxx
index b7d001c1b50b..7d3d704180f4 100644
--- a/vcl/source/window/EnumContext.cxx
+++ b/vcl/source/window/EnumContext.cxx
@@ -40,7 +40,6 @@ o3tl::enumarray<EnumContext::Context, OUString> maContextVector;
 }
 
 const sal_Int32 EnumContext::NoMatch = 4;
-const sal_Int32 EnumContext::OptimalMatch = 0;  // Neither application nor context name is "any".
 
 EnumContext::EnumContext()
     : meApplication(Application::NONE),
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index f202bda076e5..b44325fa06d3 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -822,7 +822,6 @@ CellPropertyValuesSeq_t DomainMapperTableHandler::endTableGetCellProperties(Tabl
                     for (const PropertyIds& rBorder : pBorders)
                     {
                         std::optional<PropertyMap::Property> oStyleCellBorder = pStyleProps->getProperty(rBorder);
-                        std::optional<PropertyMap::Property> oRowCellBorder;
                         std::optional<PropertyMap::Property> oDirectCellBorder = (*aCellIterator)->getProperty(rBorder);
                         if (oStyleCellBorder && oDirectCellBorder)
                         {
diff --git a/writerfilter/source/dmapper/TagLogger.hxx b/writerfilter/source/dmapper/TagLogger.hxx
index e61895a30a50..b1bba8f6166e 100644
--- a/writerfilter/source/dmapper/TagLogger.hxx
+++ b/writerfilter/source/dmapper/TagLogger.hxx
@@ -32,8 +32,6 @@ namespace writerfilter
     class TagLogger
     {
     private:
-        static tools::SvRef<TagLogger> instance;
-
         xmlTextWriterPtr pWriter;
         const char* pName;
 
diff --git a/xmloff/inc/PageMasterStyleMap.hxx b/xmloff/inc/PageMasterStyleMap.hxx
index f27d4ce84bbd..a52b2e3aeb59 100644
--- a/xmloff/inc/PageMasterStyleMap.hxx
+++ b/xmloff/inc/PageMasterStyleMap.hxx
@@ -190,8 +190,6 @@
 
 extern const XMLPropertyMapEntry aXMLPageMasterStyleMap[];
 extern const XMLPropertyMapEntry g_XMLPageMasterDrawingPageStyleMap[];
-extern const XMLPropertyMapEntry aXMLPageMasterHeaderImportStyleMap[];
-extern const XMLPropertyMapEntry aXMLPageMasterFooterImportStyleMap[];
 
 #endif
 
diff --git a/xmloff/inc/XMLChartPropertySetMapper.hxx b/xmloff/inc/XMLChartPropertySetMapper.hxx
index 74a71509cce1..72d486f158c7 100644
--- a/xmloff/inc/XMLChartPropertySetMapper.hxx
+++ b/xmloff/inc/XMLChartPropertySetMapper.hxx
@@ -25,8 +25,6 @@
 #include <xmloff/xmlimp.hxx>
 #include <xmloff/prhdlfac.hxx>
 
-extern const XMLPropertyMapEntry aXMLChartPropMap[];
-
 class SvXMLExport;
 
 class XMLChartPropHdlFactory final : public XMLPropertyHandlerFactory


More information about the Libreoffice-commits mailing list