diff options
Diffstat (limited to 'compilerplugins/clang/unusedvariableplus.cxx')
-rw-r--r-- | compilerplugins/clang/unusedvariableplus.cxx | 519 |
1 files changed, 519 insertions, 0 deletions
diff --git a/compilerplugins/clang/unusedvariableplus.cxx b/compilerplugins/clang/unusedvariableplus.cxx new file mode 100644 index 000000000..e8a8385bb --- /dev/null +++ b/compilerplugins/clang/unusedvariableplus.cxx @@ -0,0 +1,519 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * Based on LLVM/Clang. + * + * This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + * + */ + +#ifndef LO_CLANG_SHARED_PLUGINS + +#include "plugin.hxx" +#include "config_clang.h" +#include <unordered_set> + +/* + * Very aggressive unused variable checker, we allowlist types that are known + * good when unused. +*/ + +namespace +{ +static bool startswith(const std::string& rStr, const char* pSubStr) +{ + return rStr.compare(0, strlen(pSubStr), pSubStr) == 0; +} + +class UnusedVariablePlus : public loplugin::FilteringPlugin<UnusedVariablePlus> +{ +public: + explicit UnusedVariablePlus(loplugin::InstantiationData const& data) + : FilteringPlugin(data) + { + } + + virtual bool preRun() override + { + std::string fn(handler.getMainFileName()); + loplugin::normalizeDotDotInFilePath(fn); + if (loplugin::hasPathnamePrefix(fn, SRCDIR "/canvas/workben/")) + return false; + if (loplugin::isSamePathname(fn, SRCDIR "/vcl/source/uipreviewer/previewer.cxx")) + return false; + if (loplugin::hasPathnamePrefix(fn, SRCDIR "/vcl/workben/")) + return false; + if (loplugin::hasPathnamePrefix(fn, SRCDIR "/vcl/qa/")) + return false; + if (loplugin::hasPathnamePrefix(fn, SRCDIR "/vcl/backendtest/")) + return false; + if (loplugin::hasPathnamePrefix(fn, SRCDIR "/lotuswordpro/")) + return false; + if (loplugin::hasPathnamePrefix(fn, SRCDIR "/salhelper/qa/")) + return false; + if (loplugin::hasPathnamePrefix(fn, SRCDIR "/sal/qa/")) + return false; + if (loplugin::isSamePathname(fn, SRCDIR "/idl/source/prj/svidl.cxx")) + return false; + if (loplugin::isSamePathname(fn, SRCDIR "/sot/source/unoolestorage/xolesimplestorage.cxx")) + return false; + if (loplugin::isSamePathname(fn, SRCDIR "/sc/source/core/tool/interpr7.cxx")) + return false; + if (loplugin::isSamePathname(fn, SRCDIR "/sc/source/ui/vba/vbaapplication.cxx")) + return false; + if (loplugin::isSamePathname(fn, SRCDIR "/sw/source/core/doc/doccomp.cxx")) + return false; + if (loplugin::isSamePathname(fn, SRCDIR "/sw/source/core/swg/SwXMLTextBlocks.cxx")) + return false; + if (loplugin::isSamePathname(fn, SRCDIR "/sw/source/filter/ww8/wrtw8esh.cxx")) + return false; + if (loplugin::isSamePathname(fn, SRCDIR + "/shell/source/sessioninstall/SyncDbusSessionHelper.cxx")) + return false; + if (loplugin::isSamePathname(fn, SRCDIR "/svl/qa/unit/items/test_IndexedStyleSheets.cxx")) + return false; + if (loplugin::isSamePathname(fn, SRCDIR "/sd/qa/unit/export-tests-ooxml2.cxx")) + return false; + if (loplugin::isSamePathname(fn, SRCDIR "/sc/qa/unit/subsequent_export-test.cxx")) + return false; + if (loplugin::isSamePathname(fn, SRCDIR "/vcl/skia/SkiaHelper.cxx")) + return false; + if (loplugin::isSamePathname(fn, SRCDIR "/svx/source/dialog/dlgctrl.cxx")) + return false; + + // clang has a bug here, with vars in destructing assignments + if (loplugin::hasPathnamePrefix(fn, SRCDIR "/binaryurp/")) + return false; + if (loplugin::isSamePathname(fn, SRCDIR "/sc/source/filter/excel/xestring.cxx")) + return false; + return true; + } + + virtual void run() override + { + if (preRun()) + TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); + } + + bool VisitVarDecl(const VarDecl* var) + { + if (ignoreLocation(var)) + return true; + if (var->isReferenced() || var->isUsed()) + return true; + if (var->isDefinedOutsideFunctionOrMethod()) + return true; + if (var->isExceptionVariable()) // not interesting + return true; + if (isa<DecompositionDecl>(var)) + return true; + + auto type = var->getType().getCanonicalType().getUnqualifiedType(); + auto typeName = type.getAsString(); + if (typeName.compare(0, 7, "struct ") == 0) + typeName = typeName.substr(7); + if (typeName.compare(0, 6, "class ") == 0) + typeName = typeName.substr(6); + if (typeName.compare(0, 2, "::") == 0) + typeName = typeName.substr(2); + if (typeName.compare(0, 23, "(anonymous namespace)::") == 0) + typeName = typeName.substr(23); + static std::unordered_set<std::string> ignoreClassNamesSet{ + "apphelper::NegativeGuard<class osl::Mutex>", + "avmedia::gstreamer::(anonymous namespace)::FlagGuard", + "BoolEnv_Impl", + "BoolResetter", + "boost::io::basic_ios_all_saver<char, struct std::char_traits<char> >", + "BorderLinesGuard", + "BorderTest", + "BroadcastRecalcOnRefMoveGuard", + "CacheLockGuard", + "cc_reset", + "chart::ControllerLockGuard", + "chart::ControllerLockGuardUNO", + "chart::HiddenUndoContext", + "chart::sidebar::(anonymous namespace)::PreventUpdate", + "chart::TimerTriggeredControllerLock", + "chart::TrueGuard", + "ClearableClipRegion", + "osl::ClearableGuard<class osl::Mutex>", + "rptui::ColorChanger", + "SortRefUpdateSetter", + "SortRefNoUpdateSetter", + "com::sun::star::uno::ContextLayer", + "comphelper::FlagGuard", + "comphelper::FlagRestorationGuard", + "comphelper::ValueRestorationGuard<_Bool>", + "comphelper::(anonymous namespace)::ProfileZone", + "comphelper::ProfileZone", + "comphelper::ORelease<class osl::Mutex>", + "comphelper::OStreamSection", + "ConfigurationController::Lock", + "SortTypeSetter", + "SkiaZone", + "MockMetadatable", + "connectivity::(anonymous namespace)::ForbidQueryName", + "connectivity::calc::OCalcConnection::ODocHolder", + "connectivity::writer::OWriterConnection::ODocHolder", + "connectivity::jdbc::ContextClassLoaderScope", + "CurrShell", + "dbaccess::ModifyLock", + "dbaccess::NameChangeNotifier", + "dbaccess::OFilteredContainer::EnsureReset", + "dbaccess::OQuery::OAutoActionReset", + "dbaccess::OQueryContainer::OAutoActionReset", + "dbaccess::(anonymous namespace)::LayoutManagerLock", + "dbaccess::(anonymous namespace)::LockModifiable", + "dbaccess::(anonymous namespace)::OExecuteImpl", + "dbaccess::(anonymous namespace)::PreserveVisualAreaSize", + "dbaccess::(anonymous namespace)::ProtectFlag", + "dbaui::BrowserViewStatusDisplay", + "dbaui::SbaXDataBrowserController::FormErrorHelper", + "dbaui::(anonymous namespace)::SelectionGuard", + "dbaxml::(anonymous namespace)::FocusWindowWaitGuard", + "DBG_Model", + "DeactivateUpdateMode", + "DepthProtect", + "desktop::Desktop", + "desktop::(anonymous namespace)::ConditionSetGuard", + "desktop::(anonymous namespace)::RefClearGuard<class " + "com::sun::star::uno::Reference<class com::sun::star::frame::XSynchronousDispatch> " + ">", + "DetachCurrentThread", + "DialogReleaseGuard", + "DisableCallbackAction", + "DisableCallbacks", + "DisableGetPivotData", + "DispatchMutexLock_Impl", + "DisplayLockGuard", + "DocTemplLocker_Impl", + "DocumentSettingsGuard", + "DocxTableExportContext", + "dp_misc::AbortChannel::Chain", + "dp_misc::ProgressLevel", + "E3DModifySceneSnapRectUpdater", + "E3dObjFactory", + "ErrorHdlResetter", + "EscherExAtom", + "EscherExContainer", + "ExportDataSaveRestore", + "ExtensionRemoveGuard", + "frm::(anonymous namespace)::FieldChangeNotifier", + "frm::(anonymous namespace)::DocumentModifyGuard", + "FieldDeletionModify", + "FieldDeletionListener", + "FileHandle_Impl::Guard", + "FlowFrameJoinLockGuard", + "FmXFormShell::SuspendPropertyTracking", + "FocusWindowWaitCursor", + "formula::(anonymous namespace)::OpCodeList", + "formula::(anonymous namespace)::FormulaCompilerRecursionGuard", + "FontCacheGuard", + "FontLockGuard", + "FormatLevel", + "FormulaGrammarSwitch", + "framework::DocumentUndoGuard", + "framework::ShareGuard", + "framework::TransactionGuard", + "framework::(anonymous namespace)::QuickstartSuppressor", + "GalApp", + "GalleryProgress", + "GlibThreadDefaultMainContextScope", + "Guard", + "HandleResetAttrAtTextNode", + "HandleSetAttrAtTextNode", + "HelpParser", + "HtmlExport", + "HTMLSaveData", + "http_dav_ucp::CurlUri", + "IMapCompat", + "jni_uno::JLocalAutoRef", + "LoadMediumGuard", + "LockGuard", + "MacroInterpretIncrementer", + "MakeAllOutlineContentTemporarilyVisible", + "MailMergeExecuteFinalizer", + "ModifyBlocker_Impl", + "MutexRelease", + "MutexType", + "NewTextListsHelper", + "OAutoRegistration", + "rptui::GeometryHandler::OBlocker", + "rptui::OXReportControllerObserver::OEnvLock", + "oglcanvas::TransformationPreserver", + "io_acceptor::(anonymous namespace)::BeingInAccept", + "desktop::LibLibreOffice_Impl", + "ToolbarUnoDispatcher", + "ooo::vba::excel::(anonymous namespace)::PasteCellsWarningReseter", + "oox::drawingml::(anonymous namespace)::ActionLockGuard", + "oox::dump::IndentGuard", + "oox::dump::ItemGuard", + "oox::dump::MultiItemsGuard", + "oox::dump::TableGuard", + "OpenCLInitialZone", + "OpenCLZone", + "OpenGLVCLContextZone", + "OpenGLZone", + "osl::MutexGuard", + "rptui::OXUndoEnvironment::OUndoMode", + "rptui::OXUndoEnvironment::OUndoEnvLock", + "PaMIntoCursorShellRing", + "ParserCleanup", + "pcr::ComposedUIAutoFireGuard", + "PngDestructor", + "writerperfect::(anonymous namespace)::PositionHolder", + "pq_sdbc_driver::DisposeGuard", + "PropertyChangeNotifier", + "ProtectFormulaGroupContext", + "PreventUpdate", + "pyuno::PyThreadAttach", + "pyuno::PyThreadDetach", + "pyuno_loader::(anonymous namespace)::PythonInit", + "RecursionCounter", + "RefGuard", + "icu_65::RegexMatcher", + "RestoreMapMode", + "Runner", + "pyuno::Runtime", + "salhelper::ConditionModifier", + "salhelper::ConditionWaiter", + "SaveRunState", + "SbiExpression", + "sc::AutoCalcSwitch", + "sc::DelayDeletingBroadcasters", + "sc::DelayFormulaGroupingSwitch", + "sc::IdleSwitch", + "sc::UndoSwitch", + "ScBulkBroadcast", + "ScChartLockGuard", + "ScCompiler", + "ScDocument::NumFmtMergeHandler", + "ScDocShellModificator", + "ScDocShell::PrepareSaveGuard", + "ScExternalRefManager::ApiGuard", + "ScFormulaGroupCycleCheckGuard", + "ScFormulaGroupDependencyComputeGuard", + "SchedulerGuard", + "ScMutationDisable", + "ScNoteCaptionCreator", + "ScValidationRegisteredDlg", + "ScopedAntialiasing", + "ScRefreshTimerProtector", + "ScWaitCursorOff", + "ScXMLImport::MutexGuard", + "SdIOCompat", + "sd::slidesorter::controller::FocusManager::FocusHider", + "sd::slidesorter::controller::SlideSorterController::ModelChangeLock", + "sd::slidesorter::controller::PageSelector::BroadcastLock", + "sd::slidesorter::view::SlideSorterView::DrawLock", + "sd::slidesorter::controller::PageSelector::UpdateLock", + "sd::ViewShellManager::Implementation::UpdateLock", + "sd::(anonymous namespace)::LockUI", + "sd::ToolBarManager::UpdateLock", + "sd::ViewShellManager::UpdateLock", + "sd::OutlineViewPageChangesGuard", + "sd::framework::ConfigurationController::Lock", + "sd::slidesorter::controller::VisibleAreaManager::TemporaryDisabler", + "sd::slidesorter::controller::SelectionObserver::Context", + "sd::ToolBarManager::Implementation::UpdateLockImplementation", + "sd::OutlineViewModelChangeGuard", + "sd::slidesorter::controller::(anonymous " + "namespace)::TemporarySlideTrackingDeactivator", + "sd::ModifyGuard", + "sd::OutlineViewModelChangeGuard", + "setFastDocumentHandlerGuard", + "SmMathConfig::CommitLocker", + "SfxErrorContext", + "SfxFilterListener", + "SfxObjectShellLock", + "SfxProgress", + "SfxSaveGuard", + "SfxStack", + "ShellMoveCursor", + "SkAutoCanvasRestore", + "SolarMutexGuard", + "SolarMutexReleaser", + "StackHack", + "std::lock_guard<class std::mutex>", + "std::scoped_lock<class std::mutex>", + "std::unique_lock<class std::mutex>", + "std::unique_lock<class std::recursive_mutex>", + "std::unique_ptr<class com::sun::star::uno::ContextLayer>", + "std::unique_ptr<class weld::WaitObject>", + "std::unique_ptr<class ClearableClipRegion, struct o3tl::default_delete<class " + "ClearableClipRegion>>", + "std::unique_ptr<class SfxObjectShell::LockAllViewsGuard>", + "std::unique_ptr<class SwDocShell::LockAllViewsGuard>", + "std::unique_ptr<class SwSaveFootnoteHeight>", + "std::unique_ptr<class SwModelTestBase::Resetter>", + "StreamExceptionsEnabler", + "SvAddressParser_Impl", + "svl::undo::impl::LockGuard", + "svt::table::(anonymous namespace)::SuppressCursor", + "svx::(anonymous namespace)::FontSwitch", + "SvXMLElementExport", + "svxform::(anonymous namespace)::QuitGuard", + "sw::DrawUndoGuard", + "sw::FlyCreationSuppressor", + "sw::GroupUndoGuard", + "sw::UndoGuard", + "sw::(anonymous namespace)::CursorGuard", + "SwActContext", + "SwAutoFormat", + "SwCallLink", + "SwContentNotify", + "SwCursorSaveState", + "SwCSS1OutMode", + "SwDataChanged", + "SwDigitModeModifier", + "SwDrawViewSave", + "SwDropSave", + "SwEnhancedPDFExportHelper", + "SwEnterLeave", + "SwFieldSlot", + "SwFilterOptions", + "SwFntAccess", + "SwFontSave", + "SwFootnoteSave", + "SwFrameDeleteGuard", + "SwModelTestBase::Resetter", + "std::unique_ptr<class ScTokenArray>", // ScCompiler::CompileString has nasty semantics + "Resetter", + "SwFrameSwapper", + "SwFlyNotify", + "SwForbidFollowFormat", + "SwHandleAnchorNodeChg", + "SwHookOut", + "SwImplShellAction", + "SwKeepConversionDirectionStateContext", + "SwLayIdle", + "SwLayNotify", + "SwLayoutModeModifier", + "SwMvContext", + "SwNotifyAccAboutInvalidTextSelections", + "SwObjPositioningInProgress", + "SwParaSelection", + "SwPauseThreadStarting", + "SwPosNotify", + "SwRedlineItr", // ??? + "SwRegHistory", + "SwSaveFootnoteHeight", + "SwSaveSetLRUOfst", + "SwStyleBase_Impl::ItemSetOverrider", + "SwSwapIfNotSwapped", + "SwSwapIfSwapped", + "SwTableNumFormatMerge", + "SwTaggedPDFHelper", + "SwTestFormat", + "SwTextCursorSave", + "SwTextSlot", + "SwTrnsfrActionAndUndo", + "SwWait", + "SwXDispatchProviderInterceptor::DispatchMutexLock_Impl", + "TableWait", + "TargetStateControl_Impl", + "TempErrorHandler", + "TemporaryCellGroupMaker", + "TemporaryRedlineUpdater", + "TextFrameLockGuard", + "TimerContext", + "TimerTriggeredControllerLock", + "ToggleSaveToModule", + "toolkit::(anonymous namespace)::ResetFlagOnExit", + "tools::ScopedJsonWriterArray", + "tools::ScopedJsonWriterNode", + "tools::ScopedJsonWriterStruct", + "TravelSuspension", + "TreeUpdateSwitch", + "rptui::UndoContext", + "rptui::UndoSuppressor", + "UndoRedoRedlineGuard", + "UnoActionRemoveContext", + "UnoActionContext", + "UpdateFontsGuard", + "utl::CloseableComponent", + "utl::DisposableComponent", + "ValueCounter_Impl", + "VclListenerLock", + "vclcanvas::tools::OutDevStateKeeper", + "vcl::PaintBufferGuard", + "vcl::RoadmapWizardTravelSuspension", + "vcl::ScopedAntialiasing", + "vcl::WizardTravelSuspension", + "VerbExecutionControllerGuard", + "VersionCompatRead", + "VersionCompatWrite", + "ViewCallback", + "SlideShowImpl::WaitSymbolLock", + "weld::WaitObject", + "writerfilter::ooxml::(anonymous namespace)::StatusIndicatorGuard", + "WriterSpecificAutoFormatBlock", + "xmloff::OOfficeFormsExport", + "xmlscript::(anonymous namespace)::MGuard", + "XMLTextCharStyleNamesElementExport", + }; + if (ignoreClassNamesSet.find(typeName) != ignoreClassNamesSet.end()) + return true; + if (startswith(typeName, "comphelper::ScopeGuard<")) + return true; + if (startswith(typeName, "comphelper::ValueRestorationGuard<")) + return true; + if (startswith(typeName, "osl::Guard<")) + return true; + if (startswith(typeName, "dbaui::OMultiInstanceAutoRegistration<")) + return true; + if (startswith(typeName, "pcr::OAutoRegistration<")) + return true; + + if (var->getIdentifier()) + { + auto name = var->getName(); + if (name == "aBroadcastGuard" || name == "aDeleteRef" || name == "aGuard" + || name == "aGuard2" || name == "aHoldSelf" || name == "aKeepDoc" + || name == "aAutoRegistration" || name == "aLoadContentIfExists" + || name == "aOwnRef" || name == "createImpl" || name == "flyHolder" + || name == "guard" || name == "ensureDelete" || name == "s_xTerminateListener" + || name == "pThis" || name == "pOldViewShell" || name == "self" + || name == "xDocStor" || name == "xDeleteUponLeaving" || name == "xDeleteRef" + || name == "xHoldAlive" || name == "xHolder" || name == "xHoldRefForMethodAlive" + || name == "xLock" || name == "xMutexGuard" || name == "xKeepAlive" + || name == "xKeepContentHolderAlive" || name == "xKeepDocAlive" + || name == "xKeepMeAlive" || name == "xKeepProviderAlive" + || name == "xOperationHold" || name == "xPreventDelete" || name == "xSelf" + || name == "xSelfHold" || name == "xTempHold" || name == "xDisposeAfterNewOne" + || name == "xThis" || name == "xThisPackage" || name == "xTriggerInit" + || name == "xLifeCycle" || name == "xAnotherLifeCycle") + return true; + } + + if (isa<ParmVarDecl>(var)) + return true; + + if (typeName.find("Reference") != std::string::npos && var->getInit()) + { + if (auto cxxConstructExpr + = dyn_cast<CXXConstructExpr>(var->getInit()->IgnoreImplicit())) + if (cxxConstructExpr->getNumArgs() == 2) + if (auto param1 = dyn_cast<DeclRefExpr>(cxxConstructExpr->getArg(1))) + if (auto enumDecl = dyn_cast<EnumConstantDecl>(param1->getDecl())) + if (enumDecl->getName() == "UNO_QUERY_THROW" + || enumDecl->getName() == "UNO_SET_THROW") + return true; + } + + report(DiagnosticsEngine::Warning, "unused variable %0 of type %1", var->getLocation()) + << var->getDeclName() << typeName; + + return true; + } +}; + +loplugin::Plugin::Registration<UnusedVariablePlus> unusedvariableplus("unusedvariableplus", false); + +} // namespace + +#endif // LO_CLANG_SHARED_PLUGINS + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |