Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/commandhandler/./../../../dom/commandhandler/nsCommandManager.cpp
Warning:line 154, 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 -O2 -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=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/commandhandler -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/commandhandler -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/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 /root/firefox-clang/dom/commandhandler -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/commandhandler -I /root/firefox-clang/dom/base -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -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-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 -Wno-character-conversion -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c++ Unified_cpp_dom_commandhandler0.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#include "nsCommandManager.h"
6
7#include "nsCOMArray.h"
8#include "nsContentUtils.h"
9#include "nsIController.h"
10#include "nsIControllers.h"
11#include "nsIObserver.h"
12#include "nsPIDOMWindow.h"
13#include "nsPIWindowRoot.h"
14#include "nsServiceManagerUtils.h"
15#include "nsString.h"
16
17nsCommandManager::nsCommandManager(mozIDOMWindowProxy* aWindow)
18 : mWindow(aWindow) {
19 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", "./../../../dom/commandhandler/nsCommandManager.cpp"
, 19); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mWindow"
")"); do { MOZ_CrashSequence(__null, 19); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
20}
21
22nsCommandManager::~nsCommandManager() = default;
23
24NS_IMPL_CYCLE_COLLECTION_CLASS(nsCommandManager)nsCommandManager::cycleCollection nsCommandManager::_cycleCollectorGlobal
;
25
26NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCommandManager)void nsCommandManager::cycleCollection::Unlink(void* p) { nsCommandManager
* tmp = DowncastCCParticipant<nsCommandManager>(p);
27 tmp->mObserversTable.Clear();
28 NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_REFERENCEtmp->ClearWeakReferences();
29NS_IMPL_CYCLE_COLLECTION_UNLINK_END(void)tmp; }
30NS_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"
);
31 for (const auto& entry : tmp->mObserversTable) {
32 nsCommandManager::ObserverList* observers = entry.GetWeak();
33 int32_t numItems = observers->Length();
34 for (int32_t i = 0; i < numItems; ++i) {
35 cb.NoteXPCOMChild(observers->ElementAt(i));
36 }
37 }
38NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END(void)tmp; return NS_OK; }
39
40NS_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" ")", "./../../../dom/commandhandler/nsCommandManager.cpp"
, 40); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 40
); __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; }
41NS_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" ")", "./../../../dom/commandhandler/nsCommandManager.cpp"
, 41); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 41)
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("nsCommandManager" " not thread-safe"
); nsISupports* base = nsCommandManager::cycleCollection::Upcast
(this); nsrefcnt count = mRefCnt.decr(base); if (count == 0) {
NS_CycleCollectableHasRefCntZero(); } NS_LogRelease((this), (
count), ("nsCommandManager")); return count; } void nsCommandManager
::DeleteCycleCollectable(void) { delete (this); }
42
43NS_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", "./../../../dom/commandhandler/nsCommandManager.cpp"
, 43); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant
::kIID), (nsCycleCollectionISupports::kIID)) && (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID)) || LowWordEquals
(aIID, (nsCycleCollectionISupports::kIID)))) { if (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID))) { *aInstancePtr
= nsCommandManager::cycleCollection::GetParticipant(); return
NS_OK; } if (LowWordEquals(aIID, (nsCycleCollectionISupports
::kIID))) { *aInstancePtr = nsCommandManager::cycleCollection
::Upcast(this); return NS_OK; } foundInterface = nullptr; } else
44 NS_INTERFACE_MAP_ENTRY(nsICommandManager)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICommandManager>)) foundInterface
= static_cast<nsICommandManager*>(this); else
45 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupportsWeakReference>)) foundInterface
= static_cast<nsISupportsWeakReference*>(this); else
46 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
47NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::kIID
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aIID.Equals((nsISupports::kIID))", "./../../../dom/commandhandler/nsCommandManager.cpp"
, 47); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 47); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
48
49void nsCommandManager::CommandStatusChanged(const char* aCommandName) {
50 ObserverList* commandObservers;
51 mObserversTable.Get(aCommandName, &commandObservers);
52
53 if (commandObservers) {
54 // XXX Should we worry about observers removing themselves from Observe()?
55 int32_t i, numItems = commandObservers->Length();
56 for (i = 0; i < numItems; ++i) {
57 nsCOMPtr<nsIObserver> observer = commandObservers->ElementAt(i);
58 // should we get the command state to pass here? This might be expensive.
59 observer->Observe(NS_ISUPPORTS_CAST(nsICommandManager*, this)static_cast<nsISupports*>(static_cast<nsICommandManager
*>(this))
,
60 aCommandName, u"command_status_changed");
61 }
62 }
63}
64
65#if 0
66# pragma mark -
67#endif
68
69NS_IMETHODIMPnsresult
70nsCommandManager::AddCommandObserver(nsIObserver* aCommandObserver,
71 const char* aCommandToObserve) {
72 NS_ENSURE_ARG(aCommandObserver)do { if ((__builtin_expect(!!(!(aCommandObserver)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aCommandObserver" ") failed"
, nullptr, "./../../../dom/commandhandler/nsCommandManager.cpp"
, 72); return NS_ERROR_INVALID_ARG; } } while (false)
;
73
74 // XXX todo: handle special cases of aCommandToObserve being null, or empty
75
76 // for each command in the table, we make a list of observers for that command
77 auto* const commandObservers =
78 mObserversTable.GetOrInsertNew(aCommandToObserve);
79
80 // need to check that this command observer hasn't already been registered
81 int32_t existingIndex = commandObservers->IndexOf(aCommandObserver);
82 if (existingIndex == -1) {
83 commandObservers->AppendElement(aCommandObserver);
84 } else {
85 NS_WARNING("Registering command observer twice on the same command")NS_DebugBreak(NS_DEBUG_WARNING, "Registering command observer twice on the same command"
, nullptr, "./../../../dom/commandhandler/nsCommandManager.cpp"
, 85)
;
86 }
87
88 return NS_OK;
89}
90
91NS_IMETHODIMPnsresult
92nsCommandManager::RemoveCommandObserver(nsIObserver* aCommandObserver,
93 const char* aCommandObserved) {
94 NS_ENSURE_ARG(aCommandObserver)do { if ((__builtin_expect(!!(!(aCommandObserver)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aCommandObserver" ") failed"
, nullptr, "./../../../dom/commandhandler/nsCommandManager.cpp"
, 94); return NS_ERROR_INVALID_ARG; } } while (false)
;
95
96 // XXX todo: handle special cases of aCommandToObserve being null, or empty
97
98 ObserverList* commandObservers;
99 if (!mObserversTable.Get(aCommandObserved, &commandObservers)) {
100 return NS_ERROR_UNEXPECTED;
101 }
102
103 commandObservers->RemoveElement(aCommandObserver);
104
105 return NS_OK;
106}
107
108NS_IMETHODIMPnsresult
109nsCommandManager::IsCommandSupported(const char* aCommandName,
110 mozIDOMWindowProxy* aTargetWindow,
111 bool* aResult) {
112 NS_ENSURE_ARG_POINTER(aResult)do { if ((__builtin_expect(!!(!(aResult)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResult" ") failed", nullptr
, "./../../../dom/commandhandler/nsCommandManager.cpp", 112);
return NS_ERROR_INVALID_POINTER; } } while (false)
;
113
114 nsCOMPtr<nsIController> controller;
115 GetControllerForCommand(aCommandName, aTargetWindow,
116 getter_AddRefs(controller));
117 *aResult = (controller.get() != nullptr);
118 return NS_OK;
119}
120
121NS_IMETHODIMPnsresult
122nsCommandManager::IsCommandEnabled(const char* aCommandName,
123 mozIDOMWindowProxy* aTargetWindow,
124 bool* aResult) {
125 NS_ENSURE_ARG_POINTER(aResult)do { if ((__builtin_expect(!!(!(aResult)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResult" ") failed", nullptr
, "./../../../dom/commandhandler/nsCommandManager.cpp", 125);
return NS_ERROR_INVALID_POINTER; } } while (false)
;
126 if (!aCommandName) {
127 *aResult = false;
128 return NS_OK;
129 }
130 *aResult = IsCommandEnabled(nsDependentCString(aCommandName), aTargetWindow);
131 return NS_OK;
132}
133
134bool nsCommandManager::IsCommandEnabled(const nsCString& aCommandName,
135 mozIDOMWindowProxy* aTargetWindow) {
136 nsCOMPtr<nsIController> controller;
137 GetControllerForCommand(aCommandName.get(), aTargetWindow,
138 getter_AddRefs(controller));
139 if (!controller) {
140 return false;
141 }
142
143 bool enabled = false;
144 controller->IsCommandEnabled(aCommandName.get(), &enabled);
145 return enabled;
146}
147
148NS_IMETHODIMPnsresult
149nsCommandManager::GetCommandState(const char* aCommandName,
150 mozIDOMWindowProxy* aTargetWindow,
151 nsICommandParams* aCommandParams) {
152 nsCOMPtr<nsIController> controller;
153 nsAutoString tValue;
154 nsresult rv = GetControllerForCommand(aCommandName, aTargetWindow,
Value stored to 'rv' during its initialization is never read
155 getter_AddRefs(controller));
156 if (!controller) {
157 return NS_ERROR_FAILURE;
158 }
159
160 nsCOMPtr<nsICommandController> commandController =
161 do_QueryInterface(controller);
162 if (commandController) {
163 rv = commandController->GetCommandStateWithParams(aCommandName,
164 aCommandParams);
165 } else {
166 rv = NS_ERROR_NOT_IMPLEMENTED;
167 }
168 return rv;
169}
170
171NS_IMETHODIMPnsresult
172nsCommandManager::DoCommand(const char* aCommandName,
173 nsICommandParams* aCommandParams,
174 mozIDOMWindowProxy* aTargetWindow) {
175 nsCOMPtr<nsIController> controller;
176 nsresult rv = GetControllerForCommand(aCommandName, aTargetWindow,
177 getter_AddRefs(controller));
178 if (!controller) {
179 return NS_ERROR_FAILURE;
180 }
181
182 nsCOMPtr<nsICommandController> commandController =
183 do_QueryInterface(controller);
184 if (commandController && aCommandParams) {
185 rv = commandController->DoCommandWithParams(aCommandName, aCommandParams);
186 } else {
187 rv = controller->DoCommand(aCommandName);
188 }
189 return rv;
190}
191
192nsresult nsCommandManager::GetControllerForCommand(
193 const char* aCommand, mozIDOMWindowProxy* aTargetWindow,
194 nsIController** aResult) {
195 nsresult rv = NS_ERROR_FAILURE;
196 *aResult = nullptr;
197
198 // check if we're in content or chrome
199 // if we're not chrome we must have a target window or we bail
200 if (!nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
201 if (!aTargetWindow) {
202 return rv;
203 }
204
205 // if a target window is specified, it must be the window we expect
206 if (aTargetWindow != mWindow) {
207 return NS_ERROR_FAILURE;
208 }
209 }
210
211 if (auto* targetWindow = nsPIDOMWindowOuter::From(aTargetWindow)) {
212 // get the controller for this particular window
213 nsCOMPtr<nsIControllers> controllers;
214 rv = targetWindow->GetControllers(getter_AddRefs(controllers));
215 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
216 return rv;
217 }
218 if (!controllers) {
219 return NS_ERROR_FAILURE;
220 }
221
222 // dispatch the command
223 return controllers->GetControllerForCommand(aCommand, aResult);
224 }
225
226 auto* window = nsPIDOMWindowOuter::From(mWindow);
227 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(window)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "window" ") failed", nullptr
, "./../../../dom/commandhandler/nsCommandManager.cpp", 227);
return NS_ERROR_FAILURE; } } while (false)
;
228 nsCOMPtr<nsPIWindowRoot> root = window->GetTopWindowRoot();
229 NS_ENSURE_TRUE(root, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(root)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "root" ") failed", nullptr
, "./../../../dom/commandhandler/nsCommandManager.cpp", 229);
return NS_ERROR_FAILURE; } } while (false)
;
230
231 // no target window; send command to focus controller
232 return root->GetControllerForCommand(aCommand, false /* for any window */,
233 aResult);
234}