base::UnsafeDanglingUntriaged in base/observer_list_threadsafe.h

Unfortunately there doesn't seem to be a clean way to undangle the
pointer here without re-working the memory management of the entire
observer stack. That said, the current design already forces mgmt to the
ownership layer so the intent of the function really is to have dangling
pointers.

Design Doc:
https://docs.google.com/document/d/164SnySRX6MZgFkX8qLLLClTnZ0S8s5wLiNFWNyQ8f4E/edit#

Bug: 1381412
Change-Id: I4d723b0d39ec857268c2e3b169bca9bab0b50812
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4125916
Reviewed-by: Gabriel Charette <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Commit-Queue: Ari Chivukula <[email protected]>
Auto-Submit: Ari Chivukula <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1091267}
diff --git a/base/observer_list_threadsafe.h b/base/observer_list_threadsafe.h
index 412a7e2..9bc7ba0b 100644
--- a/base/observer_list_threadsafe.h
+++ b/base/observer_list_threadsafe.h
@@ -14,6 +14,7 @@
 #include "base/check_op.h"
 #include "base/containers/contains.h"
 #include "base/dcheck_is_on.h"
+#include "base/functional/bind.h"
 #include "base/lazy_instance.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
@@ -155,7 +156,12 @@
         task_runner->PostTask(
             current_notification->from_here,
             BindOnce(&ObserverListThreadSafe<ObserverType>::NotifyWrapper, this,
-                     UnsafeDanglingUntriaged(observer),
+                     // While `observer` may be dangling, we pass it and
+                     // check it wasn't deallocated in NotifyWrapper() which can
+                     // check `observers_` to verify presence (the owner of the
+                     // observer is responsible for removing it from that list
+                     // before deallocation).
+                     UnsafeDangling(observer),
                      NotificationData(this, observer_id,
                                       current_notification->from_here,
                                       notification_data->method)));
@@ -201,7 +207,12 @@
       observer.second.task_runner->PostTask(
           from_here,
           BindOnce(&ObserverListThreadSafe<ObserverType>::NotifyWrapper, this,
-                   base::UnsafeDanglingUntriaged(observer.first),
+                   // While `observer.first` may be dangling, we pass it and
+                   // check it wasn't deallocated in NotifyWrapper() which can
+                   // check `observers_` to verify presence (the owner of the
+                   // observer is responsible for removing it from that list
+                   // before deallocation).
+                   UnsafeDangling(observer.first),
                    NotificationData(this, observer.second.observer_id,
                                     from_here, method)));
     }
@@ -225,7 +236,7 @@
 
   ~ObserverListThreadSafe() override = default;
 
-  void NotifyWrapper(ObserverType* observer,
+  void NotifyWrapper(MayBeDangling<ObserverType> observer,
                      const NotificationData& notification) {
     {
       AutoLock auto_lock(lock_);