Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / compilerplugins / clang / unusedvariableplus.cxx
blobe8a8385bb3cd50b494b9bae486c5a095ddd0925f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * Based on LLVM/Clang.
7 * This file is distributed under the University of Illinois Open Source
8 * License. See LICENSE.TXT for details.
12 #ifndef LO_CLANG_SHARED_PLUGINS
14 #include "plugin.hxx"
15 #include "config_clang.h"
16 #include <unordered_set>
19 * Very aggressive unused variable checker, we allowlist types that are known
20 * good when unused.
23 namespace
25 static bool startswith(const std::string& rStr, const char* pSubStr)
27 return rStr.compare(0, strlen(pSubStr), pSubStr) == 0;
30 class UnusedVariablePlus : public loplugin::FilteringPlugin<UnusedVariablePlus>
32 public:
33 explicit UnusedVariablePlus(loplugin::InstantiationData const& data)
34 : FilteringPlugin(data)
38 virtual bool preRun() override
40 std::string fn(handler.getMainFileName());
41 loplugin::normalizeDotDotInFilePath(fn);
42 if (loplugin::hasPathnamePrefix(fn, SRCDIR "/canvas/workben/"))
43 return false;
44 if (loplugin::isSamePathname(fn, SRCDIR "/vcl/source/uipreviewer/previewer.cxx"))
45 return false;
46 if (loplugin::hasPathnamePrefix(fn, SRCDIR "/vcl/workben/"))
47 return false;
48 if (loplugin::hasPathnamePrefix(fn, SRCDIR "/vcl/qa/"))
49 return false;
50 if (loplugin::hasPathnamePrefix(fn, SRCDIR "/vcl/backendtest/"))
51 return false;
52 if (loplugin::hasPathnamePrefix(fn, SRCDIR "/lotuswordpro/"))
53 return false;
54 if (loplugin::hasPathnamePrefix(fn, SRCDIR "/salhelper/qa/"))
55 return false;
56 if (loplugin::hasPathnamePrefix(fn, SRCDIR "/sal/qa/"))
57 return false;
58 if (loplugin::isSamePathname(fn, SRCDIR "/idl/source/prj/svidl.cxx"))
59 return false;
60 if (loplugin::isSamePathname(fn, SRCDIR "/sot/source/unoolestorage/xolesimplestorage.cxx"))
61 return false;
62 if (loplugin::isSamePathname(fn, SRCDIR "/sc/source/core/tool/interpr7.cxx"))
63 return false;
64 if (loplugin::isSamePathname(fn, SRCDIR "/sc/source/ui/vba/vbaapplication.cxx"))
65 return false;
66 if (loplugin::isSamePathname(fn, SRCDIR "/sw/source/core/doc/doccomp.cxx"))
67 return false;
68 if (loplugin::isSamePathname(fn, SRCDIR "/sw/source/core/swg/SwXMLTextBlocks.cxx"))
69 return false;
70 if (loplugin::isSamePathname(fn, SRCDIR "/sw/source/filter/ww8/wrtw8esh.cxx"))
71 return false;
72 if (loplugin::isSamePathname(fn, SRCDIR
73 "/shell/source/sessioninstall/SyncDbusSessionHelper.cxx"))
74 return false;
75 if (loplugin::isSamePathname(fn, SRCDIR "/svl/qa/unit/items/test_IndexedStyleSheets.cxx"))
76 return false;
77 if (loplugin::isSamePathname(fn, SRCDIR "/sd/qa/unit/export-tests-ooxml2.cxx"))
78 return false;
79 if (loplugin::isSamePathname(fn, SRCDIR "/sc/qa/unit/subsequent_export-test.cxx"))
80 return false;
81 if (loplugin::isSamePathname(fn, SRCDIR "/vcl/skia/SkiaHelper.cxx"))
82 return false;
83 if (loplugin::isSamePathname(fn, SRCDIR "/svx/source/dialog/dlgctrl.cxx"))
84 return false;
86 // clang has a bug here, with vars in destructing assignments
87 if (loplugin::hasPathnamePrefix(fn, SRCDIR "/binaryurp/"))
88 return false;
89 if (loplugin::isSamePathname(fn, SRCDIR "/sc/source/filter/excel/xestring.cxx"))
90 return false;
91 return true;
94 virtual void run() override
96 if (preRun())
97 TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
100 bool VisitVarDecl(const VarDecl* var)
102 if (ignoreLocation(var))
103 return true;
104 if (var->isReferenced() || var->isUsed())
105 return true;
106 if (var->isDefinedOutsideFunctionOrMethod())
107 return true;
108 if (var->isExceptionVariable()) // not interesting
109 return true;
110 if (isa<DecompositionDecl>(var))
111 return true;
113 auto type = var->getType().getCanonicalType().getUnqualifiedType();
114 auto typeName = type.getAsString();
115 if (typeName.compare(0, 7, "struct ") == 0)
116 typeName = typeName.substr(7);
117 if (typeName.compare(0, 6, "class ") == 0)
118 typeName = typeName.substr(6);
119 if (typeName.compare(0, 2, "::") == 0)
120 typeName = typeName.substr(2);
121 if (typeName.compare(0, 23, "(anonymous namespace)::") == 0)
122 typeName = typeName.substr(23);
123 static std::unordered_set<std::string> ignoreClassNamesSet{
124 "apphelper::NegativeGuard<class osl::Mutex>",
125 "avmedia::gstreamer::(anonymous namespace)::FlagGuard",
126 "BoolEnv_Impl",
127 "BoolResetter",
128 "boost::io::basic_ios_all_saver<char, struct std::char_traits<char> >",
129 "BorderLinesGuard",
130 "BorderTest",
131 "BroadcastRecalcOnRefMoveGuard",
132 "CacheLockGuard",
133 "cc_reset",
134 "chart::ControllerLockGuard",
135 "chart::ControllerLockGuardUNO",
136 "chart::HiddenUndoContext",
137 "chart::sidebar::(anonymous namespace)::PreventUpdate",
138 "chart::TimerTriggeredControllerLock",
139 "chart::TrueGuard",
140 "ClearableClipRegion",
141 "osl::ClearableGuard<class osl::Mutex>",
142 "rptui::ColorChanger",
143 "SortRefUpdateSetter",
144 "SortRefNoUpdateSetter",
145 "com::sun::star::uno::ContextLayer",
146 "comphelper::FlagGuard",
147 "comphelper::FlagRestorationGuard",
148 "comphelper::ValueRestorationGuard<_Bool>",
149 "comphelper::(anonymous namespace)::ProfileZone",
150 "comphelper::ProfileZone",
151 "comphelper::ORelease<class osl::Mutex>",
152 "comphelper::OStreamSection",
153 "ConfigurationController::Lock",
154 "SortTypeSetter",
155 "SkiaZone",
156 "MockMetadatable",
157 "connectivity::(anonymous namespace)::ForbidQueryName",
158 "connectivity::calc::OCalcConnection::ODocHolder",
159 "connectivity::writer::OWriterConnection::ODocHolder",
160 "connectivity::jdbc::ContextClassLoaderScope",
161 "CurrShell",
162 "dbaccess::ModifyLock",
163 "dbaccess::NameChangeNotifier",
164 "dbaccess::OFilteredContainer::EnsureReset",
165 "dbaccess::OQuery::OAutoActionReset",
166 "dbaccess::OQueryContainer::OAutoActionReset",
167 "dbaccess::(anonymous namespace)::LayoutManagerLock",
168 "dbaccess::(anonymous namespace)::LockModifiable",
169 "dbaccess::(anonymous namespace)::OExecuteImpl",
170 "dbaccess::(anonymous namespace)::PreserveVisualAreaSize",
171 "dbaccess::(anonymous namespace)::ProtectFlag",
172 "dbaui::BrowserViewStatusDisplay",
173 "dbaui::SbaXDataBrowserController::FormErrorHelper",
174 "dbaui::(anonymous namespace)::SelectionGuard",
175 "dbaxml::(anonymous namespace)::FocusWindowWaitGuard",
176 "DBG_Model",
177 "DeactivateUpdateMode",
178 "DepthProtect",
179 "desktop::Desktop",
180 "desktop::(anonymous namespace)::ConditionSetGuard",
181 "desktop::(anonymous namespace)::RefClearGuard<class "
182 "com::sun::star::uno::Reference<class com::sun::star::frame::XSynchronousDispatch> "
183 ">",
184 "DetachCurrentThread",
185 "DialogReleaseGuard",
186 "DisableCallbackAction",
187 "DisableCallbacks",
188 "DisableGetPivotData",
189 "DispatchMutexLock_Impl",
190 "DisplayLockGuard",
191 "DocTemplLocker_Impl",
192 "DocumentSettingsGuard",
193 "DocxTableExportContext",
194 "dp_misc::AbortChannel::Chain",
195 "dp_misc::ProgressLevel",
196 "E3DModifySceneSnapRectUpdater",
197 "E3dObjFactory",
198 "ErrorHdlResetter",
199 "EscherExAtom",
200 "EscherExContainer",
201 "ExportDataSaveRestore",
202 "ExtensionRemoveGuard",
203 "frm::(anonymous namespace)::FieldChangeNotifier",
204 "frm::(anonymous namespace)::DocumentModifyGuard",
205 "FieldDeletionModify",
206 "FieldDeletionListener",
207 "FileHandle_Impl::Guard",
208 "FlowFrameJoinLockGuard",
209 "FmXFormShell::SuspendPropertyTracking",
210 "FocusWindowWaitCursor",
211 "formula::(anonymous namespace)::OpCodeList",
212 "formula::(anonymous namespace)::FormulaCompilerRecursionGuard",
213 "FontCacheGuard",
214 "FontLockGuard",
215 "FormatLevel",
216 "FormulaGrammarSwitch",
217 "framework::DocumentUndoGuard",
218 "framework::ShareGuard",
219 "framework::TransactionGuard",
220 "framework::(anonymous namespace)::QuickstartSuppressor",
221 "GalApp",
222 "GalleryProgress",
223 "GlibThreadDefaultMainContextScope",
224 "Guard",
225 "HandleResetAttrAtTextNode",
226 "HandleSetAttrAtTextNode",
227 "HelpParser",
228 "HtmlExport",
229 "HTMLSaveData",
230 "http_dav_ucp::CurlUri",
231 "IMapCompat",
232 "jni_uno::JLocalAutoRef",
233 "LoadMediumGuard",
234 "LockGuard",
235 "MacroInterpretIncrementer",
236 "MakeAllOutlineContentTemporarilyVisible",
237 "MailMergeExecuteFinalizer",
238 "ModifyBlocker_Impl",
239 "MutexRelease",
240 "MutexType",
241 "NewTextListsHelper",
242 "OAutoRegistration",
243 "rptui::GeometryHandler::OBlocker",
244 "rptui::OXReportControllerObserver::OEnvLock",
245 "oglcanvas::TransformationPreserver",
246 "io_acceptor::(anonymous namespace)::BeingInAccept",
247 "desktop::LibLibreOffice_Impl",
248 "ToolbarUnoDispatcher",
249 "ooo::vba::excel::(anonymous namespace)::PasteCellsWarningReseter",
250 "oox::drawingml::(anonymous namespace)::ActionLockGuard",
251 "oox::dump::IndentGuard",
252 "oox::dump::ItemGuard",
253 "oox::dump::MultiItemsGuard",
254 "oox::dump::TableGuard",
255 "OpenCLInitialZone",
256 "OpenCLZone",
257 "OpenGLVCLContextZone",
258 "OpenGLZone",
259 "osl::MutexGuard",
260 "rptui::OXUndoEnvironment::OUndoMode",
261 "rptui::OXUndoEnvironment::OUndoEnvLock",
262 "PaMIntoCursorShellRing",
263 "ParserCleanup",
264 "pcr::ComposedUIAutoFireGuard",
265 "PngDestructor",
266 "writerperfect::(anonymous namespace)::PositionHolder",
267 "pq_sdbc_driver::DisposeGuard",
268 "PropertyChangeNotifier",
269 "ProtectFormulaGroupContext",
270 "PreventUpdate",
271 "pyuno::PyThreadAttach",
272 "pyuno::PyThreadDetach",
273 "pyuno_loader::(anonymous namespace)::PythonInit",
274 "RecursionCounter",
275 "RefGuard",
276 "icu_65::RegexMatcher",
277 "RestoreMapMode",
278 "Runner",
279 "pyuno::Runtime",
280 "salhelper::ConditionModifier",
281 "salhelper::ConditionWaiter",
282 "SaveRunState",
283 "SbiExpression",
284 "sc::AutoCalcSwitch",
285 "sc::DelayDeletingBroadcasters",
286 "sc::DelayFormulaGroupingSwitch",
287 "sc::IdleSwitch",
288 "sc::UndoSwitch",
289 "ScBulkBroadcast",
290 "ScChartLockGuard",
291 "ScCompiler",
292 "ScDocument::NumFmtMergeHandler",
293 "ScDocShellModificator",
294 "ScDocShell::PrepareSaveGuard",
295 "ScExternalRefManager::ApiGuard",
296 "ScFormulaGroupCycleCheckGuard",
297 "ScFormulaGroupDependencyComputeGuard",
298 "SchedulerGuard",
299 "ScMutationDisable",
300 "ScNoteCaptionCreator",
301 "ScValidationRegisteredDlg",
302 "ScopedAntialiasing",
303 "ScRefreshTimerProtector",
304 "ScWaitCursorOff",
305 "ScXMLImport::MutexGuard",
306 "SdIOCompat",
307 "sd::slidesorter::controller::FocusManager::FocusHider",
308 "sd::slidesorter::controller::SlideSorterController::ModelChangeLock",
309 "sd::slidesorter::controller::PageSelector::BroadcastLock",
310 "sd::slidesorter::view::SlideSorterView::DrawLock",
311 "sd::slidesorter::controller::PageSelector::UpdateLock",
312 "sd::ViewShellManager::Implementation::UpdateLock",
313 "sd::(anonymous namespace)::LockUI",
314 "sd::ToolBarManager::UpdateLock",
315 "sd::ViewShellManager::UpdateLock",
316 "sd::OutlineViewPageChangesGuard",
317 "sd::framework::ConfigurationController::Lock",
318 "sd::slidesorter::controller::VisibleAreaManager::TemporaryDisabler",
319 "sd::slidesorter::controller::SelectionObserver::Context",
320 "sd::ToolBarManager::Implementation::UpdateLockImplementation",
321 "sd::OutlineViewModelChangeGuard",
322 "sd::slidesorter::controller::(anonymous "
323 "namespace)::TemporarySlideTrackingDeactivator",
324 "sd::ModifyGuard",
325 "sd::OutlineViewModelChangeGuard",
326 "setFastDocumentHandlerGuard",
327 "SmMathConfig::CommitLocker",
328 "SfxErrorContext",
329 "SfxFilterListener",
330 "SfxObjectShellLock",
331 "SfxProgress",
332 "SfxSaveGuard",
333 "SfxStack",
334 "ShellMoveCursor",
335 "SkAutoCanvasRestore",
336 "SolarMutexGuard",
337 "SolarMutexReleaser",
338 "StackHack",
339 "std::lock_guard<class std::mutex>",
340 "std::scoped_lock<class std::mutex>",
341 "std::unique_lock<class std::mutex>",
342 "std::unique_lock<class std::recursive_mutex>",
343 "std::unique_ptr<class com::sun::star::uno::ContextLayer>",
344 "std::unique_ptr<class weld::WaitObject>",
345 "std::unique_ptr<class ClearableClipRegion, struct o3tl::default_delete<class "
346 "ClearableClipRegion>>",
347 "std::unique_ptr<class SfxObjectShell::LockAllViewsGuard>",
348 "std::unique_ptr<class SwDocShell::LockAllViewsGuard>",
349 "std::unique_ptr<class SwSaveFootnoteHeight>",
350 "std::unique_ptr<class SwModelTestBase::Resetter>",
351 "StreamExceptionsEnabler",
352 "SvAddressParser_Impl",
353 "svl::undo::impl::LockGuard",
354 "svt::table::(anonymous namespace)::SuppressCursor",
355 "svx::(anonymous namespace)::FontSwitch",
356 "SvXMLElementExport",
357 "svxform::(anonymous namespace)::QuitGuard",
358 "sw::DrawUndoGuard",
359 "sw::FlyCreationSuppressor",
360 "sw::GroupUndoGuard",
361 "sw::UndoGuard",
362 "sw::(anonymous namespace)::CursorGuard",
363 "SwActContext",
364 "SwAutoFormat",
365 "SwCallLink",
366 "SwContentNotify",
367 "SwCursorSaveState",
368 "SwCSS1OutMode",
369 "SwDataChanged",
370 "SwDigitModeModifier",
371 "SwDrawViewSave",
372 "SwDropSave",
373 "SwEnhancedPDFExportHelper",
374 "SwEnterLeave",
375 "SwFieldSlot",
376 "SwFilterOptions",
377 "SwFntAccess",
378 "SwFontSave",
379 "SwFootnoteSave",
380 "SwFrameDeleteGuard",
381 "SwModelTestBase::Resetter",
382 "std::unique_ptr<class ScTokenArray>", // ScCompiler::CompileString has nasty semantics
383 "Resetter",
384 "SwFrameSwapper",
385 "SwFlyNotify",
386 "SwForbidFollowFormat",
387 "SwHandleAnchorNodeChg",
388 "SwHookOut",
389 "SwImplShellAction",
390 "SwKeepConversionDirectionStateContext",
391 "SwLayIdle",
392 "SwLayNotify",
393 "SwLayoutModeModifier",
394 "SwMvContext",
395 "SwNotifyAccAboutInvalidTextSelections",
396 "SwObjPositioningInProgress",
397 "SwParaSelection",
398 "SwPauseThreadStarting",
399 "SwPosNotify",
400 "SwRedlineItr", // ???
401 "SwRegHistory",
402 "SwSaveFootnoteHeight",
403 "SwSaveSetLRUOfst",
404 "SwStyleBase_Impl::ItemSetOverrider",
405 "SwSwapIfNotSwapped",
406 "SwSwapIfSwapped",
407 "SwTableNumFormatMerge",
408 "SwTaggedPDFHelper",
409 "SwTestFormat",
410 "SwTextCursorSave",
411 "SwTextSlot",
412 "SwTrnsfrActionAndUndo",
413 "SwWait",
414 "SwXDispatchProviderInterceptor::DispatchMutexLock_Impl",
415 "TableWait",
416 "TargetStateControl_Impl",
417 "TempErrorHandler",
418 "TemporaryCellGroupMaker",
419 "TemporaryRedlineUpdater",
420 "TextFrameLockGuard",
421 "TimerContext",
422 "TimerTriggeredControllerLock",
423 "ToggleSaveToModule",
424 "toolkit::(anonymous namespace)::ResetFlagOnExit",
425 "tools::ScopedJsonWriterArray",
426 "tools::ScopedJsonWriterNode",
427 "tools::ScopedJsonWriterStruct",
428 "TravelSuspension",
429 "TreeUpdateSwitch",
430 "rptui::UndoContext",
431 "rptui::UndoSuppressor",
432 "UndoRedoRedlineGuard",
433 "UnoActionRemoveContext",
434 "UnoActionContext",
435 "UpdateFontsGuard",
436 "utl::CloseableComponent",
437 "utl::DisposableComponent",
438 "ValueCounter_Impl",
439 "VclListenerLock",
440 "vclcanvas::tools::OutDevStateKeeper",
441 "vcl::PaintBufferGuard",
442 "vcl::RoadmapWizardTravelSuspension",
443 "vcl::ScopedAntialiasing",
444 "vcl::WizardTravelSuspension",
445 "VerbExecutionControllerGuard",
446 "VersionCompatRead",
447 "VersionCompatWrite",
448 "ViewCallback",
449 "SlideShowImpl::WaitSymbolLock",
450 "weld::WaitObject",
451 "writerfilter::ooxml::(anonymous namespace)::StatusIndicatorGuard",
452 "WriterSpecificAutoFormatBlock",
453 "xmloff::OOfficeFormsExport",
454 "xmlscript::(anonymous namespace)::MGuard",
455 "XMLTextCharStyleNamesElementExport",
457 if (ignoreClassNamesSet.find(typeName) != ignoreClassNamesSet.end())
458 return true;
459 if (startswith(typeName, "comphelper::ScopeGuard<"))
460 return true;
461 if (startswith(typeName, "comphelper::ValueRestorationGuard<"))
462 return true;
463 if (startswith(typeName, "osl::Guard<"))
464 return true;
465 if (startswith(typeName, "dbaui::OMultiInstanceAutoRegistration<"))
466 return true;
467 if (startswith(typeName, "pcr::OAutoRegistration<"))
468 return true;
470 if (var->getIdentifier())
472 auto name = var->getName();
473 if (name == "aBroadcastGuard" || name == "aDeleteRef" || name == "aGuard"
474 || name == "aGuard2" || name == "aHoldSelf" || name == "aKeepDoc"
475 || name == "aAutoRegistration" || name == "aLoadContentIfExists"
476 || name == "aOwnRef" || name == "createImpl" || name == "flyHolder"
477 || name == "guard" || name == "ensureDelete" || name == "s_xTerminateListener"
478 || name == "pThis" || name == "pOldViewShell" || name == "self"
479 || name == "xDocStor" || name == "xDeleteUponLeaving" || name == "xDeleteRef"
480 || name == "xHoldAlive" || name == "xHolder" || name == "xHoldRefForMethodAlive"
481 || name == "xLock" || name == "xMutexGuard" || name == "xKeepAlive"
482 || name == "xKeepContentHolderAlive" || name == "xKeepDocAlive"
483 || name == "xKeepMeAlive" || name == "xKeepProviderAlive"
484 || name == "xOperationHold" || name == "xPreventDelete" || name == "xSelf"
485 || name == "xSelfHold" || name == "xTempHold" || name == "xDisposeAfterNewOne"
486 || name == "xThis" || name == "xThisPackage" || name == "xTriggerInit"
487 || name == "xLifeCycle" || name == "xAnotherLifeCycle")
488 return true;
491 if (isa<ParmVarDecl>(var))
492 return true;
494 if (typeName.find("Reference") != std::string::npos && var->getInit())
496 if (auto cxxConstructExpr
497 = dyn_cast<CXXConstructExpr>(var->getInit()->IgnoreImplicit()))
498 if (cxxConstructExpr->getNumArgs() == 2)
499 if (auto param1 = dyn_cast<DeclRefExpr>(cxxConstructExpr->getArg(1)))
500 if (auto enumDecl = dyn_cast<EnumConstantDecl>(param1->getDecl()))
501 if (enumDecl->getName() == "UNO_QUERY_THROW"
502 || enumDecl->getName() == "UNO_SET_THROW")
503 return true;
506 report(DiagnosticsEngine::Warning, "unused variable %0 of type %1", var->getLocation())
507 << var->getDeclName() << typeName;
509 return true;
513 loplugin::Plugin::Registration<UnusedVariablePlus> unusedvariableplus("unusedvariableplus", false);
515 } // namespace
517 #endif // LO_CLANG_SHARED_PLUGINS
519 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */