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