Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/dom/commandhandler/nsCommandManager.cpp
Warning:line 182, column 12
Value stored to 'rv' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_dom_commandhandler0.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dom/commandhandler -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dom/commandhandler -resource-dir /usr/lib/llvm-18/lib/clang/18 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /var/lib/jenkins/workspace/firefox-scan-build/dom/commandhandler -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dom/commandhandler -I /var/lib/jenkins/workspace/firefox-scan-build/dom/base -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-07-21-021012-413605-1 -x c++ Unified_cpp_dom_commandhandler0.cpp
1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3/* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7#include "nsString.h"
8
9#include "nsIController.h"
10#include "nsIControllers.h"
11#include "nsIObserver.h"
12
13#include "nsServiceManagerUtils.h"
14
15#include "nsContentUtils.h"
16#include "nsPIDOMWindow.h"
17#include "nsPIWindowRoot.h"
18
19#include "nsCOMArray.h"
20
21#include "nsCommandManager.h"
22
23nsCommandManager::nsCommandManager(mozIDOMWindowProxy* aWindow)
24 : mWindow(aWindow) {
25 MOZ_DIAGNOSTIC_ASSERT(mWindow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWindow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mWindow))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mWindow", "/var/lib/jenkins/workspace/firefox-scan-build/dom/commandhandler/nsCommandManager.cpp"
, 25); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mWindow"
")"); do { *((volatile int*)__null) = 25; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
26}
27
28nsCommandManager::~nsCommandManager() = default;
29
30NS_IMPL_CYCLE_COLLECTION_CLASS(nsCommandManager)nsCommandManager::cycleCollection nsCommandManager::_cycleCollectorGlobal
;
31
32NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCommandManager)void nsCommandManager::cycleCollection::Unlink(void* p) { nsCommandManager
* tmp = DowncastCCParticipant<nsCommandManager>(p);
33 tmp->mObserversTable.Clear();
34 NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_REFERENCEtmp->ClearWeakReferences();
35NS_IMPL_CYCLE_COLLECTION_UNLINK_END(void)tmp; }
36NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCommandManager)nsresult nsCommandManager::cycleCollection::TraverseNative( void
* p, nsCycleCollectionTraversalCallback& cb) { nsCommandManager
* tmp = DowncastCCParticipant<nsCommandManager>(p); cb.
DescribeRefCountedNode(tmp->mRefCnt.get(), "nsCommandManager"
);
37 for (const auto& entry : tmp->mObserversTable) {
38 nsCommandManager::ObserverList* observers = entry.GetWeak();
39 int32_t numItems = observers->Length();
40 for (int32_t i = 0; i < numItems; ++i) {
41 cb.NoteXPCOMChild(observers->ElementAt(i));
42 }
43 }
44NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END(void)tmp; return NS_OK; }
45
46NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCommandManager)MozExternalRefCountType nsCommandManager::AddRef(void) { static_assert
(!std::is_destructible_v<nsCommandManager>, "Reference-counted class "
"nsCommandManager" " should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/commandhandler/nsCommandManager.cpp"
, 46); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
46; __attribute__((nomerge)) ::abort(); } while (false); } }
while (false); _mOwningThread.AssertOwnership("nsCommandManager"
" not thread-safe"); nsISupports* base = nsCommandManager::cycleCollection
::Upcast(this); nsrefcnt count = mRefCnt.incr(base); NS_LogAddRef
((this), (count), ("nsCommandManager"), (uint32_t)(sizeof(*this
))); return count; }
47NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCommandManager)MozExternalRefCountType nsCommandManager::Release(void) { do {
static_assert( mozilla::detail::AssertionConditionType<decltype
(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/commandhandler/nsCommandManager.cpp"
, 47); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 47
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("nsCommandManager" " not thread-safe"
); nsISupports* base = nsCommandManager::cycleCollection::Upcast
(this); nsrefcnt count = mRefCnt.decr(base); NS_LogRelease((this
), (count), ("nsCommandManager")); return count; } void nsCommandManager
::DeleteCycleCollectable(void) { delete (this); }
48
49NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCommandManager)nsresult nsCommandManager::QueryInterface(const nsIID& aIID
, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/dom/commandhandler/nsCommandManager.cpp"
, 49); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant
::COMTypeInfo<nsXPCOMCycleCollectionParticipant, void>::
kIID), (nsCycleCollectionISupports::COMTypeInfo<nsCycleCollectionISupports
, void>::kIID)) && (LowWordEquals(aIID, (nsXPCOMCycleCollectionParticipant
::COMTypeInfo<nsXPCOMCycleCollectionParticipant, void>::
kIID)) || LowWordEquals(aIID, (nsCycleCollectionISupports::COMTypeInfo
<nsCycleCollectionISupports, void>::kIID)))) { if (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::COMTypeInfo<nsXPCOMCycleCollectionParticipant
, void>::kIID))) { *aInstancePtr = nsCommandManager::cycleCollection
::GetParticipant(); return NS_OK; } if (LowWordEquals(aIID, (
nsCycleCollectionISupports::COMTypeInfo<nsCycleCollectionISupports
, void>::kIID))) { *aInstancePtr = nsCommandManager::cycleCollection
::Upcast(this); return NS_OK; } foundInterface = nullptr; } else
50 NS_INTERFACE_MAP_ENTRY(nsICommandManager)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICommandManager>)) foundInterface
= static_cast<nsICommandManager*>(this); else
51 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupportsWeakReference>)) foundInterface
= static_cast<nsISupportsWeakReference*>(this); else
52 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICommandManager)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(static_cast<nsICommandManager*>(this
)); else
53NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::COMTypeInfo<nsISupports
, void>::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::COMTypeInfo
<nsISupports, void>::kIID))))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("!aIID.Equals((nsISupports::COMTypeInfo<nsISupports, void>::kIID))"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/commandhandler/nsCommandManager.cpp"
, 53); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::COMTypeInfo<nsISupports, void>::kIID))"
")"); do { *((volatile int*)__null) = 53; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
54
55void nsCommandManager::CommandStatusChanged(const char* aCommandName) {
56 ObserverList* commandObservers;
57 mObserversTable.Get(aCommandName, &commandObservers);
58
59 if (commandObservers) {
60 // XXX Should we worry about observers removing themselves from Observe()?
61 int32_t i, numItems = commandObservers->Length();
62 for (i = 0; i < numItems; ++i) {
63 nsCOMPtr<nsIObserver> observer = commandObservers->ElementAt(i);
64 // should we get the command state to pass here? This might be expensive.
65 observer->Observe(NS_ISUPPORTS_CAST(nsICommandManager*, this)static_cast<nsISupports*>(static_cast<nsICommandManager
*>(this))
,
66 aCommandName, u"command_status_changed");
67 }
68 }
69}
70
71#if 0
72# pragma mark -
73#endif
74
75NS_IMETHODIMPnsresult
76nsCommandManager::AddCommandObserver(nsIObserver* aCommandObserver,
77 const char* aCommandToObserve) {
78 NS_ENSURE_ARG(aCommandObserver)do { if ((__builtin_expect(!!(!(aCommandObserver)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aCommandObserver" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/dom/commandhandler/nsCommandManager.cpp"
, 78); return NS_ERROR_INVALID_ARG; } } while (false)
;
79
80 // XXX todo: handle special cases of aCommandToObserve being null, or empty
81
82 // for each command in the table, we make a list of observers for that command
83 auto* const commandObservers =
84 mObserversTable.GetOrInsertNew(aCommandToObserve);
85
86 // need to check that this command observer hasn't already been registered
87 int32_t existingIndex = commandObservers->IndexOf(aCommandObserver);
88 if (existingIndex == -1) {
89 commandObservers->AppendElement(aCommandObserver);
90 } else {
91 NS_WARNING("Registering command observer twice on the same command")NS_DebugBreak(NS_DEBUG_WARNING, "Registering command observer twice on the same command"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/dom/commandhandler/nsCommandManager.cpp"
, 91)
;
92 }
93
94 return NS_OK;
95}
96
97NS_IMETHODIMPnsresult
98nsCommandManager::RemoveCommandObserver(nsIObserver* aCommandObserver,
99 const char* aCommandObserved) {
100 NS_ENSURE_ARG(aCommandObserver)do { if ((__builtin_expect(!!(!(aCommandObserver)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aCommandObserver" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/dom/commandhandler/nsCommandManager.cpp"
, 100); return NS_ERROR_INVALID_ARG; } } while (false)
;
101
102 // XXX todo: handle special cases of aCommandToObserve being null, or empty
103
104 ObserverList* commandObservers;
105 if (!mObserversTable.Get(aCommandObserved, &commandObservers)) {
106 return NS_ERROR_UNEXPECTED;
107 }
108
109 commandObservers->RemoveElement(aCommandObserver);
110
111 return NS_OK;
112}
113
114NS_IMETHODIMPnsresult
115nsCommandManager::IsCommandSupported(const char* aCommandName,
116 mozIDOMWindowProxy* aTargetWindow,
117 bool* aResult) {
118 NS_ENSURE_ARG_POINTER(aResult)do { if ((__builtin_expect(!!(!(aResult)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResult" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/commandhandler/nsCommandManager.cpp"
, 118); return NS_ERROR_INVALID_POINTER; } } while (false)
;
119
120 nsCOMPtr<nsIController> controller;
121 GetControllerForCommand(aCommandName, aTargetWindow,
122 getter_AddRefs(controller));
123 *aResult = (controller.get() != nullptr);
124 return NS_OK;
125}
126
127NS_IMETHODIMPnsresult
128nsCommandManager::IsCommandEnabled(const char* aCommandName,
129 mozIDOMWindowProxy* aTargetWindow,
130 bool* aResult) {
131 NS_ENSURE_ARG_POINTER(aResult)do { if ((__builtin_expect(!!(!(aResult)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResult" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/commandhandler/nsCommandManager.cpp"
, 131); return NS_ERROR_INVALID_POINTER; } } while (false)
;
132 if (!aCommandName) {
133 *aResult = false;
134 return NS_OK;
135 }
136 *aResult = IsCommandEnabled(nsDependentCString(aCommandName), aTargetWindow);
137 return NS_OK;
138}
139
140bool nsCommandManager::IsCommandEnabled(const nsCString& aCommandName,
141 mozIDOMWindowProxy* aTargetWindow) {
142 nsCOMPtr<nsIController> controller;
143 GetControllerForCommand(aCommandName.get(), aTargetWindow,
144 getter_AddRefs(controller));
145 if (!controller) {
146 return false;
147 }
148
149 bool enabled = false;
150 controller->IsCommandEnabled(aCommandName.get(), &enabled);
151 return enabled;
152}
153
154NS_IMETHODIMPnsresult
155nsCommandManager::GetCommandState(const char* aCommandName,
156 mozIDOMWindowProxy* aTargetWindow,
157 nsICommandParams* aCommandParams) {
158 nsCOMPtr<nsIController> controller;
159 nsAutoString tValue;
160 nsresult rv = GetControllerForCommand(aCommandName, aTargetWindow,
161 getter_AddRefs(controller));
162 if (!controller) {
163 return NS_ERROR_FAILURE;
164 }
165
166 nsCOMPtr<nsICommandController> commandController =
167 do_QueryInterface(controller);
168 if (commandController) {
169 rv = commandController->GetCommandStateWithParams(aCommandName,
170 aCommandParams);
171 } else {
172 rv = NS_ERROR_NOT_IMPLEMENTED;
173 }
174 return rv;
175}
176
177NS_IMETHODIMPnsresult
178nsCommandManager::DoCommand(const char* aCommandName,
179 nsICommandParams* aCommandParams,
180 mozIDOMWindowProxy* aTargetWindow) {
181 nsCOMPtr<nsIController> controller;
182 nsresult rv = GetControllerForCommand(aCommandName, aTargetWindow,
Value stored to 'rv' during its initialization is never read
183 getter_AddRefs(controller));
184 if (!controller) {
185 return NS_ERROR_FAILURE;
186 }
187
188 nsCOMPtr<nsICommandController> commandController =
189 do_QueryInterface(controller);
190 if (commandController && aCommandParams) {
191 rv = commandController->DoCommandWithParams(aCommandName, aCommandParams);
192 } else {
193 rv = controller->DoCommand(aCommandName);
194 }
195 return rv;
196}
197
198nsresult nsCommandManager::GetControllerForCommand(
199 const char* aCommand, mozIDOMWindowProxy* aTargetWindow,
200 nsIController** aResult) {
201 nsresult rv = NS_ERROR_FAILURE;
202 *aResult = nullptr;
203
204 // check if we're in content or chrome
205 // if we're not chrome we must have a target window or we bail
206 if (!nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
207 if (!aTargetWindow) {
208 return rv;
209 }
210
211 // if a target window is specified, it must be the window we expect
212 if (aTargetWindow != mWindow) {
213 return NS_ERROR_FAILURE;
214 }
215 }
216
217 if (auto* targetWindow = nsPIDOMWindowOuter::From(aTargetWindow)) {
218 // get the controller for this particular window
219 nsCOMPtr<nsIControllers> controllers;
220 rv = targetWindow->GetControllers(getter_AddRefs(controllers));
221 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
222 return rv;
223 }
224 if (!controllers) {
225 return NS_ERROR_FAILURE;
226 }
227
228 // dispatch the command
229 return controllers->GetControllerForCommand(aCommand, aResult);
230 }
231
232 auto* window = nsPIDOMWindowOuter::From(mWindow);
233 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(window)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "window" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/commandhandler/nsCommandManager.cpp"
, 233); return NS_ERROR_FAILURE; } } while (false)
;
234 nsCOMPtr<nsPIWindowRoot> root = window->GetTopWindowRoot();
235 NS_ENSURE_TRUE(root, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(root)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "root" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/commandhandler/nsCommandManager.cpp"
, 235); return NS_ERROR_FAILURE; } } while (false)
;
236
237 // no target window; send command to focus controller
238 return root->GetControllerForCommand(aCommand, false /* for any window */,
239 aResult);
240}