Rewrite T& into raw_ref<T> under base/

The changes were generated by running
tools/clang/rewrite_raw_ref_fields/rewrite-multiple-platforms.sh with
tool-arg=--enable_raw_ref_rewrite

`raw_ref` is a smart pointer for a pointer which can not be null, and
which provides Use-after-Free protection in the same ways as raw_ptr.
This class acts like a combination of std::reference_wrapper and
raw_ptr.

See raw_ptr and //base/memory/raw_ptr.md for more details on the
Use-after-Free protection.

Bug: 1357022
Change-Id: Iea06ee400a9f14101053c63bf89755dbeca331ff
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4016454
Commit-Queue: danakj <[email protected]>
Owners-Override: danakj <[email protected]>
Commit-Queue: Ali Hijazi <[email protected]>
Reviewed-by: danakj <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1069975}
diff --git a/base/containers/adapters.h b/base/containers/adapters.h
index b1d2707..943a79d4 100644
--- a/base/containers/adapters.h
+++ b/base/containers/adapters.h
@@ -10,6 +10,8 @@
 #include <iterator>
 #include <utility>
 
+#include "base/memory/raw_ref.h"
+
 namespace base {
 
 namespace internal {
@@ -24,11 +26,15 @@
   ReversedAdapter(const ReversedAdapter& ra) : t_(ra.t_) {}
   ReversedAdapter& operator=(const ReversedAdapter&) = delete;
 
-  Iterator begin() const { return std::rbegin(t_); }
-  Iterator end() const { return std::rend(t_); }
+  Iterator begin() const { return std::rbegin(*t_); }
+  Iterator end() const { return std::rend(*t_); }
 
  private:
-  T& t_;
+  // `ReversedAdapter` and therefore `t_` are only used inside for loops. The
+  // container being iterated over should be the one holding a raw_ref/raw_ptr
+  // ideally. This member's type was rewritten into `const raw_ref` since it
+  // didn't hurt binary size at the time of the rewrite.
+  const raw_ref<T> t_;
 };
 
 }  // namespace internal
diff --git a/base/containers/flat_tree.h b/base/containers/flat_tree.h
index c5bc387..bd527bcd 100644
--- a/base/containers/flat_tree.h
+++ b/base/containers/flat_tree.h
@@ -476,7 +476,10 @@
     const K& extract_if_value_type(const K& k) const {
       return k;
     }
-
+    // This field was not rewritten into `const raw_ref<const key_compare>` due
+    // to binary size increase. There's also little value to rewriting this
+    // member as it points to `flat_tree::comp_`. The flat_tree itself should be
+    // holding raw_ptr/raw_ref if necessary.
     const key_compare& comp_;
   };
 
diff --git a/base/containers/ring_buffer.h b/base/containers/ring_buffer.h
index ce816f5..021ca9ff 100644
--- a/base/containers/ring_buffer.h
+++ b/base/containers/ring_buffer.h
@@ -8,6 +8,7 @@
 #include <stddef.h>
 
 #include "base/check.h"
+#include "base/memory/raw_ref.h"
 
 namespace base {
 
@@ -64,8 +65,8 @@
    public:
     size_t index() const { return index_; }
 
-    const T* operator->() const { return &buffer_.ReadBuffer(index_); }
-    const T* operator*() const { return &buffer_.ReadBuffer(index_); }
+    const T* operator->() const { return &buffer_->ReadBuffer(index_); }
+    const T* operator*() const { return &buffer_->ReadBuffer(index_); }
 
     Iterator& operator++() {
       index_++;
@@ -82,14 +83,14 @@
     }
 
     operator bool() const {
-      return !out_of_range_ && buffer_.IsFilledIndex(index_);
+      return !out_of_range_ && buffer_->IsFilledIndex(index_);
     }
 
    private:
     Iterator(const RingBuffer<T, kSize>& buffer, size_t index)
         : buffer_(buffer), index_(index), out_of_range_(false) {}
 
-    const RingBuffer<T, kSize>& buffer_;
+    const raw_ref<const RingBuffer<T, kSize>> buffer_;
     size_t index_;
     bool out_of_range_;
 
diff --git a/base/debug/crash_logging_unittest.cc b/base/debug/crash_logging_unittest.cc
index d2c5497d..ad13e35 100644
--- a/base/debug/crash_logging_unittest.cc
+++ b/base/debug/crash_logging_unittest.cc
@@ -8,6 +8,7 @@
 #include <memory>
 #include <sstream>
 
+#include "base/memory/raw_ref.h"
 #include "base/strings/string_piece.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -35,19 +36,19 @@
   }
 
   void Set(CrashKeyString* crash_key, base::StringPiece value) override {
-    ASSERT_TRUE(data_.emplace(crash_key->name, value).second);
+    ASSERT_TRUE(data_->emplace(crash_key->name, value).second);
   }
 
   void Clear(CrashKeyString* crash_key) override {
-    ASSERT_EQ(1u, data_.erase(crash_key->name));
+    ASSERT_EQ(1u, data_->erase(crash_key->name));
   }
 
   void OutputCrashKeysToStream(std::ostream& out) override {
-    out << "Got " << data_.size() << " crash keys.";
+    out << "Got " << data_->size() << " crash keys.";
   }
 
  private:
-  std::map<std::string, std::string>& data_;
+  const raw_ref<std::map<std::string, std::string>> data_;
 };
 
 }  // namespace
diff --git a/base/debug/dwarf_line_no.cc b/base/debug/dwarf_line_no.cc
index 4501a1a1..b35cc5d 100644
--- a/base/debug/dwarf_line_no.cc
+++ b/base/debug/dwarf_line_no.cc
@@ -4,6 +4,8 @@
 
 #include "base/debug/dwarf_line_no.h"
 
+#include "base/memory/raw_ref.h"
+
 #ifdef USE_SYMBOLIZE
 #include <algorithm>
 #include <cstdint>
@@ -188,7 +190,7 @@
    private:
     raw_ptr<LineNumberInfo> info;
     uint64_t module_relative_pc;
-    const ProgramInfo& program_info;
+    const raw_ref<const ProgramInfo> program_info;
 
    public:
     OnCommitImpl(LineNumberInfo* info,
@@ -213,7 +215,7 @@
           module_relative_pc >= registers->address)
         return;
 
-      if (registers->last_file < program_info.num_filenames) {
+      if (registers->last_file < program_info->num_filenames) {
         info->line = registers->last_line;
         info->column = registers->last_column;
 
@@ -222,19 +224,19 @@
         // follow spec, but seems to be common behavior. See the following LLVM
         // bug for more info: https://reviews.llvm.org/D11003
         if (registers->last_file == 0 &&
-            program_info.filename_offsets[0] == 0 &&
-            1 < program_info.num_filenames) {
-          program_info.filename_offsets[0] = program_info.filename_offsets[1];
-          program_info.filename_dirs[0] = program_info.filename_dirs[1];
+            program_info->filename_offsets[0] == 0 &&
+            1 < program_info->num_filenames) {
+          program_info->filename_offsets[0] = program_info->filename_offsets[1];
+          program_info->filename_dirs[0] = program_info->filename_dirs[1];
         }
 
         if (registers->last_file < kMaxFilenames) {
           info->module_filename_offset =
-              program_info.filename_offsets[registers->last_file];
+              program_info->filename_offsets[registers->last_file];
 
-          uint8_t dir = program_info.filename_dirs[registers->last_file];
-          info->module_dir_offset = program_info.directory_offsets[dir];
-          info->dir_size = program_info.directory_sizes[dir];
+          uint8_t dir = program_info->filename_dirs[registers->last_file];
+          info->module_dir_offset = program_info->directory_offsets[dir];
+          info->dir_size = program_info->directory_sizes[dir];
         }
       }
     }
diff --git a/base/debug/task_trace_unittest.cc b/base/debug/task_trace_unittest.cc
index 659c979..a394d4c 100644
--- a/base/debug/task_trace_unittest.cc
+++ b/base/debug/task_trace_unittest.cc
@@ -7,6 +7,7 @@
 #include <ostream>
 
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_ref.h"
 #include "base/run_loop.h"
 #include "base/test/bind.h"
 #include "base/test/task_environment.h"
@@ -26,8 +27,8 @@
   ThreeTasksTest() {}
 
   void Run() {
-    task_runner.PostTask(FROM_HERE, base::BindOnce(&ThreeTasksTest::TaskA,
-                                                   base::Unretained(this)));
+    task_runner->PostTask(FROM_HERE, base::BindOnce(&ThreeTasksTest::TaskA,
+                                                    base::Unretained(this)));
     task_environment.RunUntilIdle();
   }
 
@@ -37,8 +38,8 @@
     base::span<const void* const> addresses = task_trace.AddressesForTesting();
     EXPECT_EQ(addresses.size(), 1ul);
     task_a_address = addresses[0];
-    task_runner.PostTask(FROM_HERE, base::BindOnce(&ThreeTasksTest::TaskB,
-                                                   base::Unretained(this)));
+    task_runner->PostTask(FROM_HERE, base::BindOnce(&ThreeTasksTest::TaskB,
+                                                    base::Unretained(this)));
   }
 
   void TaskB() {
@@ -48,8 +49,8 @@
     EXPECT_EQ(addresses.size(), 2ul);
     task_b_address = addresses[0];
     EXPECT_EQ(addresses[1], task_a_address);
-    task_runner.PostTask(FROM_HERE, base::BindOnce(&ThreeTasksTest::TaskC,
-                                                   base::Unretained(this)));
+    task_runner->PostTask(FROM_HERE, base::BindOnce(&ThreeTasksTest::TaskC,
+                                                    base::Unretained(this)));
   }
 
   void TaskC() {
@@ -63,8 +64,8 @@
 
  private:
   base::test::TaskEnvironment task_environment;
-  base::SingleThreadTaskRunner& task_runner =
-      *task_environment.GetMainThreadTaskRunner();
+  const raw_ref<base::SingleThreadTaskRunner> task_runner{
+      *task_environment.GetMainThreadTaskRunner()};
 
   raw_ptr<const void> task_a_address = nullptr;
   raw_ptr<const void> task_b_address = nullptr;
diff --git a/base/file_version_info_win.cc b/base/file_version_info_win.cc
index 71c507db..aa74187 100644
--- a/base/file_version_info_win.cc
+++ b/base/file_version_info_win.cc
@@ -171,10 +171,10 @@
 }
 
 base::Version FileVersionInfoWin::GetFileVersion() const {
-  return base::Version({HIWORD(fixed_file_info_.dwFileVersionMS),
-                        LOWORD(fixed_file_info_.dwFileVersionMS),
-                        HIWORD(fixed_file_info_.dwFileVersionLS),
-                        LOWORD(fixed_file_info_.dwFileVersionLS)});
+  return base::Version({HIWORD(fixed_file_info_->dwFileVersionMS),
+                        LOWORD(fixed_file_info_->dwFileVersionMS),
+                        HIWORD(fixed_file_info_->dwFileVersionLS),
+                        LOWORD(fixed_file_info_->dwFileVersionLS)});
 }
 
 FileVersionInfoWin::FileVersionInfoWin(std::vector<uint8_t>&& data,
diff --git a/base/file_version_info_win.h b/base/file_version_info_win.h
index 87c1ac0..925d550 100644
--- a/base/file_version_info_win.h
+++ b/base/file_version_info_win.h
@@ -16,6 +16,7 @@
 #include "base/base_export.h"
 #include "base/file_version_info.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_ref.h"
 #include "base/version.h"
 
 struct tagVS_FIXEDFILEINFO;
@@ -71,7 +72,7 @@
   const WORD code_page_;
 
   // This is a reference for a portion of |data_|.
-  const VS_FIXEDFILEINFO& fixed_file_info_;
+  const raw_ref<const VS_FIXEDFILEINFO> fixed_file_info_;
 };
 
 #endif  // BASE_FILE_VERSION_INFO_WIN_H_
diff --git a/base/files/file_descriptor_watcher_posix.cc b/base/files/file_descriptor_watcher_posix.cc
index bbda71b..ab1a036 100644
--- a/base/files/file_descriptor_watcher_posix.cc
+++ b/base/files/file_descriptor_watcher_posix.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/memory/ptr_util.h"
+#include "base/memory/raw_ref.h"
 #include "base/message_loop/message_pump_for_io.h"
 #include "base/no_destructor.h"
 #include "base/synchronization/waitable_event.h"
@@ -71,7 +72,7 @@
 
   // WaitableEvent to signal to ensure that the Watcher is always destroyed
   // before the Controller.
-  base::WaitableEvent& on_destroyed_;
+  const raw_ref<base::WaitableEvent> on_destroyed_;
 
   // Whether this Watcher is notified when |fd_| becomes readable or writable
   // without blocking.
@@ -109,7 +110,7 @@
 
   // Stop watching the descriptor before signalling |on_destroyed_|.
   CHECK(fd_watch_controller_.StopWatchingFileDescriptor());
-  on_destroyed_.Signal();
+  on_destroyed_->Signal();
 }
 
 void FileDescriptorWatcher::Controller::Watcher::StartWatching() {
diff --git a/base/memory/raw_ptr_unittest.cc b/base/memory/raw_ptr_unittest.cc
index 6ab13d0d..f66585a 100644
--- a/base/memory/raw_ptr_unittest.cc
+++ b/base/memory/raw_ptr_unittest.cc
@@ -1637,7 +1637,7 @@
             Unretained(this))) {}
 
   void DeleteItselfAndCheckIfInQuarantine() {
-    auto& allocator = owning_allocator;
+    auto& allocator = *owning_allocator;
     EXPECT_TRUE(IsQuarantineEmpty(allocator));
 
     // Since we use a non-default partition, `delete` has to be simulated.
@@ -1647,7 +1647,7 @@
     EXPECT_FALSE(IsQuarantineEmpty(allocator));
   }
 
-  partition_alloc::PartitionAllocator& owning_allocator;
+  const raw_ref<partition_alloc::PartitionAllocator> owning_allocator;
   OnceClosure once_callback;
   RepeatingClosure repeating_callback;
 };
diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc
index aadd052..d3453dcb 100644
--- a/base/metrics/histogram.cc
+++ b/base/metrics/histogram.cc
@@ -23,6 +23,7 @@
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_ref.h"
 #include "base/metrics/dummy_histogram.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/metrics_hashes.h"
@@ -136,7 +137,7 @@
   // Allocate the correct Histogram object off the heap (in case persistent
   // memory is not available).
   virtual std::unique_ptr<HistogramBase> HeapAlloc(const BucketRanges* ranges) {
-    return WrapUnique(new Histogram(GetPermanentName(name_), ranges));
+    return WrapUnique(new Histogram(GetPermanentName(*name_), ranges));
   }
 
   // Perform any required datafill on the just-created histogram.  If
@@ -147,7 +148,7 @@
   // These values are protected (instead of private) because they need to
   // be accessible to methods of sub-classes in order to avoid passing
   // unnecessary parameters everywhere.
-  const std::string& name_;
+  const raw_ref<const std::string> name_;
   const HistogramType histogram_type_;
   HistogramBase::Sample minimum_;
   HistogramBase::Sample maximum_;
@@ -156,11 +157,11 @@
 };
 
 HistogramBase* Histogram::Factory::Build() {
-  HistogramBase* histogram = StatisticsRecorder::FindHistogram(name_);
+  HistogramBase* histogram = StatisticsRecorder::FindHistogram(*name_);
   if (!histogram) {
     // constructor. Refactor code to avoid the additional call.
     bool should_record = StatisticsRecorder::ShouldRecordHistogram(
-        HashMetricNameAs32Bits(name_));
+        HashMetricNameAs32Bits(*name_));
     if (!should_record)
       return DummyHistogram::GetInstance();
     // To avoid racy destruction at shutdown, the following will be leaked.
@@ -192,13 +193,8 @@
     PersistentHistogramAllocator* allocator = GlobalHistogramAllocator::Get();
     if (allocator) {
       tentative_histogram = allocator->AllocateHistogram(
-          histogram_type_,
-          name_,
-          minimum_,
-          maximum_,
-          registered_ranges,
-          flags_,
-          &histogram_ref);
+          histogram_type_, *name_, minimum_, maximum_, registered_ranges,
+          flags_, &histogram_ref);
     }
 
     // Handle the case where no persistent allocator is present or the
@@ -237,8 +233,8 @@
     // return would cause Chrome to crash; better to just record it for later
     // analysis.
     UmaHistogramSparse("Histogram.MismatchedConstructionArguments",
-                       static_cast<Sample>(HashMetricName(name_)));
-    DLOG(ERROR) << "Histogram " << name_
+                       static_cast<Sample>(HashMetricName(*name_)));
+    DLOG(ERROR) << "Histogram " << *name_
                 << " has mismatched construction arguments";
     return DummyHistogram::GetInstance();
   }
@@ -705,7 +701,7 @@
 
   std::unique_ptr<HistogramBase> HeapAlloc(
       const BucketRanges* ranges) override {
-    return WrapUnique(new LinearHistogram(GetPermanentName(name_), ranges));
+    return WrapUnique(new LinearHistogram(GetPermanentName(*name_), ranges));
   }
 
   void FillHistogram(HistogramBase* base_histogram) override {
@@ -987,7 +983,7 @@
 
   std::unique_ptr<HistogramBase> HeapAlloc(
       const BucketRanges* ranges) override {
-    return WrapUnique(new BooleanHistogram(GetPermanentName(name_), ranges));
+    return WrapUnique(new BooleanHistogram(GetPermanentName(*name_), ranges));
   }
 };
 
@@ -1087,7 +1083,7 @@
 
   std::unique_ptr<HistogramBase> HeapAlloc(
       const BucketRanges* ranges) override {
-    return WrapUnique(new CustomHistogram(GetPermanentName(name_), ranges));
+    return WrapUnique(new CustomHistogram(GetPermanentName(*name_), ranges));
   }
 
  private:
diff --git a/base/profiler/stack_copier_suspend_unittest.cc b/base/profiler/stack_copier_suspend_unittest.cc
index 03b6e43..46de91d 100644
--- a/base/profiler/stack_copier_suspend_unittest.cc
+++ b/base/profiler/stack_copier_suspend_unittest.cc
@@ -9,6 +9,7 @@
 #include <utility>
 
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_ref.h"
 #include "base/profiler/stack_buffer.h"
 #include "base/profiler/stack_copier_suspend.h"
 #include "base/profiler/suspendable_thread_delegate.h"
@@ -61,16 +62,17 @@
       *thread_context = *thread_context_;
     // Set the stack pointer to be consistent with the provided fake stack.
     RegisterContextStackPointer(thread_context) =
-        reinterpret_cast<uintptr_t>(&fake_stack_[0]);
+        reinterpret_cast<uintptr_t>(&(*fake_stack_)[0]);
     RegisterContextInstructionPointer(thread_context) =
-        reinterpret_cast<uintptr_t>(fake_stack_[0]);
+        reinterpret_cast<uintptr_t>((*fake_stack_)[0]);
     return true;
   }
 
   PlatformThreadId GetThreadId() const override { return PlatformThreadId(); }
 
   uintptr_t GetStackBaseAddress() const override {
-    return reinterpret_cast<uintptr_t>(&fake_stack_[0] + fake_stack_.size());
+    return reinterpret_cast<uintptr_t>(&(*fake_stack_)[0] +
+                                       fake_stack_->size());
   }
 
   bool CanCopyStack(uintptr_t stack_pointer) override { return true; }
@@ -83,7 +85,7 @@
  private:
   // Must be a reference to retain the underlying allocation from the vector
   // passed to the constructor.
-  const std::vector<uintptr_t>& fake_stack_;
+  const raw_ref<const std::vector<uintptr_t>> fake_stack_;
   raw_ptr<RegisterContext> thread_context_;
 };
 
diff --git a/base/profiler/stack_sampler_unittest.cc b/base/profiler/stack_sampler_unittest.cc
index da98050..8b10555 100644
--- a/base/profiler/stack_sampler_unittest.cc
+++ b/base/profiler/stack_sampler_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_ref.h"
 #include "base/profiler/module_cache.h"
 #include "base/profiler/profile_builder.h"
 #include "base/profiler/stack_buffer.h"
@@ -71,10 +72,10 @@
                  TimeTicks* timestamp,
                  RegisterContext* thread_context,
                  Delegate* delegate) override {
-    std::memcpy(stack_buffer->buffer(), &fake_stack_[0],
-                fake_stack_.size() * sizeof(fake_stack_[0]));
+    std::memcpy(stack_buffer->buffer(), &(*fake_stack_)[0],
+                fake_stack_->size() * sizeof((*fake_stack_)[0]));
     *stack_top = reinterpret_cast<uintptr_t>(stack_buffer->buffer() +
-                                             fake_stack_.size());
+                                             fake_stack_->size());
     // Set the stack pointer to be consistent with the copied stack.
     *thread_context = {};
     RegisterContextStackPointer(thread_context) =
@@ -88,7 +89,7 @@
  private:
   // Must be a reference to retain the underlying allocation from the vector
   // passed to the constructor.
-  const std::vector<uintptr_t>& fake_stack_;
+  const raw_ref<const std::vector<uintptr_t>> fake_stack_;
 
   const TimeTicks timestamp_;
 };
diff --git a/base/task/bind_post_task_unittest.cc b/base/task/bind_post_task_unittest.cc
index 33434eb..d05cad8 100644
--- a/base/task/bind_post_task_unittest.cc
+++ b/base/task/bind_post_task_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/memory/raw_ref.h"
 #include "base/sequence_checker_impl.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/test/task_environment.h"
@@ -41,14 +42,14 @@
 
   ~SequenceRestrictionChecker() {
     EXPECT_TRUE(checker_.CalledOnValidSequence());
-    set_on_destroy_ = true;
+    *set_on_destroy_ = true;
   }
 
   void Run() { EXPECT_TRUE(checker_.CalledOnValidSequence()); }
 
  private:
   SequenceCheckerImpl checker_;
-  bool& set_on_destroy_;
+  const raw_ref<bool> set_on_destroy_;
 };
 
 }  // namespace
diff --git a/base/task/common/checked_lock.h b/base/task/common/checked_lock.h
index 4f9bcd72..7d6f75a 100644
--- a/base/task/common/checked_lock.h
+++ b/base/task/common/checked_lock.h
@@ -9,6 +9,7 @@
 
 #include "base/check_op.h"
 #include "base/dcheck_is_on.h"
+#include "base/memory/raw_ref.h"
 #include "base/synchronization/condition_variable.h"
 #include "base/synchronization/lock.h"
 #include "base/task/common/checked_lock_impl.h"
@@ -125,7 +126,7 @@
       EXCLUSIVE_LOCK_FUNCTION(lock_alias)
       : acquired_lock_(acquired_lock) {
     DCHECK_EQ(&acquired_lock, &lock_alias);
-    acquired_lock_.AssertAcquired();
+    acquired_lock_->AssertAcquired();
   }
 
   AnnotateAcquiredLockAlias(const AnnotateAcquiredLockAlias&) = delete;
@@ -133,11 +134,11 @@
       delete;
 
   ~AnnotateAcquiredLockAlias() UNLOCK_FUNCTION() {
-    acquired_lock_.AssertAcquired();
+    acquired_lock_->AssertAcquired();
   }
 
  private:
-  const CheckedLock& acquired_lock_;
+  const raw_ref<const CheckedLock> acquired_lock_;
 };
 
 }  // namespace internal
diff --git a/base/task/common/operations_controller_unittest.cc b/base/task/common/operations_controller_unittest.cc
index 1766dfcb..ce729a49 100644
--- a/base/task/common/operations_controller_unittest.cc
+++ b/base/task/common/operations_controller_unittest.cc
@@ -8,6 +8,7 @@
 #include <cstdint>
 #include <utility>
 
+#include "base/memory/raw_ref.h"
 #include "base/ranges/algorithm.h"
 #include "base/threading/platform_thread.h"
 #include "base/threading/simple_thread.h"
@@ -20,10 +21,10 @@
 class ScopedShutdown {
  public:
   ScopedShutdown(OperationsController* controller) : controller_(*controller) {}
-  ~ScopedShutdown() { controller_.ShutdownAndWaitForZeroOperations(); }
+  ~ScopedShutdown() { controller_->ShutdownAndWaitForZeroOperations(); }
 
  private:
-  OperationsController& controller_;
+  const raw_ref<OperationsController> controller_;
 };
 
 TEST(OperationsControllerTest, CanBeDestroyedWithoutWaiting) {
@@ -115,13 +116,13 @@
         started_(*started),
         thread_counter_(*thread_counter) {}
   void Run() override {
-    thread_counter_.fetch_add(1, std::memory_order_relaxed);
+    thread_counter_->fetch_add(1, std::memory_order_relaxed);
     while (true) {
       PlatformThread::YieldCurrentThread();
-      bool was_started = started_.load(std::memory_order_relaxed);
+      bool was_started = started_->load(std::memory_order_relaxed);
       std::vector<OperationsController::OperationToken> tokens;
       for (int i = 0; i < 100; ++i) {
-        tokens.push_back(controller_.TryBeginOperation());
+        tokens.push_back(controller_->TryBeginOperation());
       }
       if (!was_started)
         continue;
@@ -132,9 +133,9 @@
   }
 
  private:
-  OperationsController& controller_;
-  std::atomic<bool>& started_;
-  std::atomic<int32_t>& thread_counter_;
+  const raw_ref<OperationsController> controller_;
+  const raw_ref<std::atomic<bool>> started_;
+  const raw_ref<std::atomic<int32_t>> thread_counter_;
 };
 
 TEST(OperationsControllerTest, BeginsFromMultipleThreads) {
diff --git a/base/task/sequence_manager/sequenced_task_source.h b/base/task/sequence_manager/sequenced_task_source.h
index e89837e8..0b33f7a 100644
--- a/base/task/sequence_manager/sequenced_task_source.h
+++ b/base/task/sequence_manager/sequenced_task_source.h
@@ -7,6 +7,7 @@
 
 #include "base/base_export.h"
 #include "base/callback_helpers.h"
+#include "base/memory/raw_ref.h"
 #include "base/pending_task.h"
 #include "base/task/common/lazy_now.h"
 #include "base/task/sequence_manager/task_queue.h"
@@ -37,7 +38,7 @@
                  QueueName task_queue_name);
     ~SelectedTask();
 
-    Task& task;
+    const raw_ref<Task> task;
     // Callback to fill trace event arguments associated with the task
     // execution. Can be null
     TaskExecutionTraceLogger task_execution_trace_logger =
diff --git a/base/task/sequence_manager/thread_controller.cc b/base/task/sequence_manager/thread_controller.cc
index cd82149..af9e13f8 100644
--- a/base/task/sequence_manager/thread_controller.cc
+++ b/base/task/sequence_manager/thread_controller.cc
@@ -32,7 +32,7 @@
     : outer_(outer) {}
 
 ThreadController::RunLevelTracker::~RunLevelTracker() {
-  DCHECK_CALLED_ON_VALID_THREAD(outer_.associated_thread_->thread_checker);
+  DCHECK_CALLED_ON_VALID_THREAD(outer_->associated_thread_->thread_checker);
 
   // There shouldn't be any remaining |run_levels_| by the time this unwinds.
   DCHECK_EQ(run_levels_.size(), 0u);
@@ -73,7 +73,7 @@
 
 void ThreadController::RunLevelTracker::OnRunLoopStarted(State initial_state,
                                                          LazyNow& lazy_now) {
-  DCHECK_CALLED_ON_VALID_THREAD(outer_.associated_thread_->thread_checker);
+  DCHECK_CALLED_ON_VALID_THREAD(outer_->associated_thread_->thread_checker);
 
   const bool is_nested = !run_levels_.empty();
   run_levels_.emplace(initial_state, is_nested, time_keeper_, lazy_now);
@@ -84,7 +84,7 @@
 }
 
 void ThreadController::RunLevelTracker::OnRunLoopEnded() {
-  DCHECK_CALLED_ON_VALID_THREAD(outer_.associated_thread_->thread_checker);
+  DCHECK_CALLED_ON_VALID_THREAD(outer_->associated_thread_->thread_checker);
   // Normally this will occur while kIdle or kInBetweenWorkItems but it can also
   // occur while kRunningWorkItem in rare situations where the owning
   // ThreadController is deleted from within a task. Ref.
@@ -92,13 +92,13 @@
   // can't assert anything about the current state other than that it must be
   // exiting an existing RunLevel.
   DCHECK(!run_levels_.empty());
-  LazyNow exit_lazy_now(outer_.time_source_);
+  LazyNow exit_lazy_now(outer_->time_source_);
   run_levels_.top().set_exit_lazy_now(&exit_lazy_now);
   run_levels_.pop();
 }
 
 void ThreadController::RunLevelTracker::OnWorkStarted(LazyNow& lazy_now) {
-  DCHECK_CALLED_ON_VALID_THREAD(outer_.associated_thread_->thread_checker);
+  DCHECK_CALLED_ON_VALID_THREAD(outer_->associated_thread_->thread_checker);
   // Ignore work outside the main run loop.
   // The only practical case where this would happen is if a native loop is spun
   // outside the main runloop (e.g. system dialog during startup). We cannot
@@ -128,7 +128,7 @@
 void ThreadController::RunLevelTracker::OnApplicationTaskSelected(
     TimeTicks queue_time,
     LazyNow& lazy_now) {
-  DCHECK_CALLED_ON_VALID_THREAD(outer_.associated_thread_->thread_checker);
+  DCHECK_CALLED_ON_VALID_THREAD(outer_->associated_thread_->thread_checker);
   // As-in OnWorkStarted. Early native loops can result in
   // ThreadController::DoWork because the lack of a top-level RunLoop means
   // `task_execution_allowed` wasn't consumed.
@@ -142,7 +142,7 @@
 }
 
 void ThreadController::RunLevelTracker::OnWorkEnded(LazyNow& lazy_now) {
-  DCHECK_CALLED_ON_VALID_THREAD(outer_.associated_thread_->thread_checker);
+  DCHECK_CALLED_ON_VALID_THREAD(outer_->associated_thread_->thread_checker);
   if (run_levels_.empty())
     return;
 
@@ -161,7 +161,7 @@
 }
 
 void ThreadController::RunLevelTracker::OnIdle(LazyNow& lazy_now) {
-  DCHECK_CALLED_ON_VALID_THREAD(outer_.associated_thread_->thread_checker);
+  DCHECK_CALLED_ON_VALID_THREAD(outer_->associated_thread_->thread_checker);
   if (run_levels_.empty())
     return;
 
@@ -370,7 +370,7 @@
 bool ThreadController::RunLevelTracker::TimeKeeper::ShouldRecordNow(
     ShouldRecordReqs reqs) {
   DCHECK_CALLED_ON_VALID_THREAD(
-      outer_.outer_.associated_thread_->thread_checker);
+      outer_->outer_->associated_thread_->thread_checker);
   // Recording is technically enabled once `histogram_` is set, however
   // `last_phase_end_` will be null until the next RecordWakeUp in the work
   // cycle in which `histogram_` is enabled. Only start recording from there.
@@ -382,12 +382,12 @@
   switch (reqs) {
     case ShouldRecordReqs::kRegular:
       return histogram_ && !last_phase_end_.is_null() &&
-             outer_.run_levels_.size() == 1;
+             outer_->run_levels_.size() == 1;
     case ShouldRecordReqs::kOnWakeUp:
-      return histogram_ && outer_.run_levels_.size() == 1;
+      return histogram_ && outer_->run_levels_.size() == 1;
     case ShouldRecordReqs::kOnEndNested:
       return histogram_ && !last_phase_end_.is_null() &&
-             outer_.run_levels_.size() <= 2;
+             outer_->run_levels_.size() <= 2;
   }
 }
 
@@ -419,8 +419,8 @@
   if (phase == kIdleWork)
     last_sleep_ = phase_end;
 
-  if (outer_.trace_observer_for_testing_)
-    outer_.trace_observer_for_testing_->OnPhaseRecorded(phase);
+  if (outer_->trace_observer_for_testing_)
+    outer_->trace_observer_for_testing_->OnPhaseRecorded(phase);
 }
 
 // static
diff --git a/base/task/sequence_manager/thread_controller.h b/base/task/sequence_manager/thread_controller.h
index f104385e..e4d4f53 100644
--- a/base/task/sequence_manager/thread_controller.h
+++ b/base/task/sequence_manager/thread_controller.h
@@ -268,7 +268,7 @@
     void OnIdle(LazyNow& lazy_now);
 
     size_t num_run_levels() const {
-      DCHECK_CALLED_ON_VALID_THREAD(outer_.associated_thread_->thread_checker);
+      DCHECK_CALLED_ON_VALID_THREAD(outer_->associated_thread_->thread_checker);
       return run_levels_.size();
     }
 
@@ -364,7 +364,7 @@
       // True if tracing was enabled during the last pass of RecordTimeInPhase.
       bool was_tracing_enabled_;
 #endif
-      const RunLevelTracker& outer_;
+      const raw_ref<const RunLevelTracker> outer_;
     } time_keeper_{*this};
 
     class RunLevel {
@@ -419,10 +419,10 @@
       TruePostMove was_moved_;
     };
 
-    [[maybe_unused]] const ThreadController& outer_;
+    [[maybe_unused]] const raw_ref<const ThreadController> outer_;
 
     std::stack<RunLevel, std::vector<RunLevel>> run_levels_
-        GUARDED_BY_CONTEXT(outer_.associated_thread_->thread_checker);
+        GUARDED_BY_CONTEXT(outer_->associated_thread_->thread_checker);
 
     static TraceObserverForTesting* trace_observer_for_testing_;
   } run_level_tracker_{*this};
diff --git a/base/task/sequence_manager/thread_controller_impl.cc b/base/task/sequence_manager/thread_controller_impl.cc
index 9e56b5f..91f3b523 100644
--- a/base/task/sequence_manager/thread_controller_impl.cc
+++ b/base/task/sequence_manager/thread_controller_impl.cc
@@ -191,8 +191,8 @@
         sequence_->SelectNextTask(lazy_now_select_task);
     LazyNow lazy_now_task_selected(time_source_);
     run_level_tracker_.OnApplicationTaskSelected(
-        (selected_task && selected_task->task.delayed_run_time.is_null())
-            ? selected_task->task.queue_time
+        (selected_task && selected_task->task->delayed_run_time.is_null())
+            ? selected_task->task->queue_time
             : TimeTicks(),
         lazy_now_task_selected);
     if (!selected_task) {
@@ -209,11 +209,11 @@
       // Note: all arguments after task are just passed to a TRACE_EVENT for
       // logging so lambda captures are safe as lambda is executed inline.
       task_annotator_.RunTask(
-          "ThreadControllerImpl::RunTask", selected_task->task,
+          "ThreadControllerImpl::RunTask", *selected_task->task,
           [&selected_task](perfetto::EventContext& ctx) {
             if (selected_task->task_execution_trace_logger)
               selected_task->task_execution_trace_logger.Run(
-                  ctx, selected_task->task);
+                  ctx, *selected_task->task);
             SequenceManagerImpl::MaybeEmitTaskDetails(ctx, *selected_task);
           });
       if (!weak_ptr)
diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc
index f66d130..193da681 100644
--- a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc
+++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc
@@ -12,6 +12,7 @@
 #include "base/feature_list.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
+#include "base/memory/raw_ref.h"
 #include "base/message_loop/message_pump.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/histogram_macros.h"
@@ -420,8 +421,8 @@
                                                        select_task_option);
     LazyNow lazy_now_task_selected(time_source_);
     run_level_tracker_.OnApplicationTaskSelected(
-        (selected_task && selected_task->task.delayed_run_time.is_null())
-            ? selected_task->task.queue_time
+        (selected_task && selected_task->task->delayed_run_time.is_null())
+            ? selected_task->task->queue_time
             : TimeTicks(),
         lazy_now_task_selected);
     if (!selected_task) {
@@ -441,16 +442,16 @@
     {
       // Always track the start of the task, as this is low-overhead.
       TaskAnnotator::LongTaskTracker long_task_tracker(
-          time_source_, selected_task->task, &task_annotator_);
+          time_source_, *selected_task->task, &task_annotator_);
 
       // Note: all arguments after task are just passed to a TRACE_EVENT for
       // logging so lambda captures are safe as lambda is executed inline.
       task_annotator_.RunTask(
-          "ThreadControllerImpl::RunTask", selected_task->task,
+          "ThreadControllerImpl::RunTask", *selected_task->task,
           [&selected_task](perfetto::EventContext& ctx) {
             if (selected_task->task_execution_trace_logger)
               selected_task->task_execution_trace_logger.Run(
-                  ctx, selected_task->task);
+                  ctx, *selected_task->task);
             SequenceManagerImpl::MaybeEmitTaskDetails(ctx,
                                                       selected_task.value());
           });
@@ -504,12 +505,12 @@
 
     // Very last step before going idle, must be fast as this is hidden from the
     // DoIdleWork trace event below.
-    ~OnIdle() { run_level_tracker.OnIdle(lazy_now); }
+    ~OnIdle() { run_level_tracker->OnIdle(lazy_now); }
 
     LazyNow lazy_now;
 
    private:
-    RunLevelTracker& run_level_tracker;
+    const raw_ref<RunLevelTracker> run_level_tracker;
   };
   absl::optional<OnIdle> on_idle;
 
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc
index 01847bd..ff962c1c7 100644
--- a/base/test/launcher/test_launcher.cc
+++ b/base/test/launcher/test_launcher.cc
@@ -31,6 +31,7 @@
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_ref.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/process/kill.h"
 #include "base/process/launch.h"
@@ -185,7 +186,7 @@
   bool WaitWithTimeout(TimeDelta timeout) override;
 
  private:
-  Process& process_;
+  const raw_ref<Process> process_;
   int exit_code_ = -1;
 };
 
@@ -194,7 +195,7 @@
 }
 
 bool ProcessResultWatcher::WaitWithTimeout(TimeDelta timeout) {
-  return process_.WaitForExitWithTimeout(timeout, &exit_code_);
+  return process_->WaitForExitWithTimeout(timeout, &exit_code_);
 }
 
 namespace {
diff --git a/base/test/scoped_feature_list.cc b/base/test/scoped_feature_list.cc
index 0fb2f67..164d005 100644
--- a/base/test/scoped_feature_list.cc
+++ b/base/test/scoped_feature_list.cc
@@ -448,7 +448,7 @@
   if (!enabled_features_and_params.empty()) {
     for (const auto& feature : enabled_features_and_params) {
       std::string trial_name = "scoped_feature_list_trial_for_";
-      trial_name += feature.feature.name;
+      trial_name += feature.feature->name;
 
       // If features.params has 2 params whose values are value1 and value2,
       // |params| will be "param1/value1/param2/value2/".
@@ -463,7 +463,7 @@
       }
 
       merged_features.enabled_feature_list.emplace_back(
-          feature.feature.name, trial_name, kTrialGroup, params);
+          feature.feature->name, trial_name, kTrialGroup, params);
     }
     create_associated_field_trials = true;
   } else {
diff --git a/base/test/scoped_feature_list.h b/base/test/scoped_feature_list.h
index c46006c..3709f1e1 100644
--- a/base/test/scoped_feature_list.h
+++ b/base/test/scoped_feature_list.h
@@ -30,7 +30,7 @@
 
   ~FeatureRefAndParams();
 
-  const Feature& feature;
+  const raw_ref<const Feature> feature;
   const FieldTrialParams params;
 };
 
diff --git a/base/test/task_environment.cc b/base/test/task_environment.cc
index eb2b87f..95b08c11f 100644
--- a/base/test/task_environment.cc
+++ b/base/test/task_environment.cc
@@ -16,6 +16,7 @@
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_ref.h"
 #include "base/message_loop/message_pump.h"
 #include "base/message_loop/message_pump_type.h"
 #include "base/no_destructor.h"
@@ -99,15 +100,15 @@
  public:
   explicit TickClockBasedClock(const TickClock* tick_clock)
       : tick_clock_(*tick_clock),
-        start_ticks_(tick_clock_.NowTicks()),
+        start_ticks_(tick_clock_->NowTicks()),
         start_time_(Time::UnixEpoch()) {}
 
   Time Now() const override {
-    return start_time_ + (tick_clock_.NowTicks() - start_ticks_);
+    return start_time_ + (tick_clock_->NowTicks() - start_ticks_);
   }
 
  private:
-  const TickClock& tick_clock_;
+  const raw_ref<const TickClock> tick_clock_;
   const TimeTicks start_ticks_;
   const Time start_time_;
 };
diff --git a/base/thread_annotations_unittest.cc b/base/thread_annotations_unittest.cc
index b718a24..726da7cf 100644
--- a/base/thread_annotations_unittest.cc
+++ b/base/thread_annotations_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "thread_annotations.h"
 
+#include "base/memory/raw_ref.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
@@ -19,10 +20,10 @@
   AutoLock(Lock& lock) EXCLUSIVE_LOCK_FUNCTION(lock) : lock_(lock) {
     lock.Acquire();
   }
-  ~AutoLock() UNLOCK_FUNCTION() { lock_.Release(); }
+  ~AutoLock() UNLOCK_FUNCTION() { lock_->Release(); }
 
  private:
-  Lock& lock_;
+  const raw_ref<Lock> lock_;
 };
 
 class ThreadSafe {
diff --git a/base/threading/sequence_bound_unittest.cc b/base/threading/sequence_bound_unittest.cc
index 4d0dac8..f377b9f 100644
--- a/base/threading/sequence_bound_unittest.cc
+++ b/base/threading/sequence_bound_unittest.cc
@@ -988,7 +988,7 @@
       : loop_(loop), value_(value) {}
 
   int ConstMethod(int arg) const {
-    value_ = arg;
+    *value_ = arg;
     if (loop_) {
       loop_->Quit();
     }
@@ -996,7 +996,7 @@
   }
 
   int Method(int arg) {
-    value_ = arg;
+    *value_ = arg;
     if (loop_) {
       loop_->Quit();
     }
@@ -1005,7 +1005,7 @@
 
  private:
   const raw_ptr<RunLoop> loop_ = nullptr;
-  int& value_;
+  const raw_ref<int> value_;
 };
 
 TYPED_TEST(SequenceBoundTest, AsyncCallIgnoreResultWithArgs) {
diff --git a/base/values.cc b/base/values.cc
index 1057bec..7484679 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -1497,123 +1497,123 @@
     : dict_(dict.GetDict()) {}
 
 bool DictAdapterForMigration::empty() const {
-  return dict_.empty();
+  return dict_->empty();
 }
 
 size_t DictAdapterForMigration::size() const {
-  return dict_.size();
+  return dict_->size();
 }
 
 DictAdapterForMigration::const_iterator DictAdapterForMigration::begin() const {
-  return dict_.begin();
+  return dict_->begin();
 }
 
 DictAdapterForMigration::const_iterator DictAdapterForMigration::cbegin()
     const {
-  return dict_.cbegin();
+  return dict_->cbegin();
 }
 
 DictAdapterForMigration::const_iterator DictAdapterForMigration::end() const {
-  return dict_.end();
+  return dict_->end();
 }
 
 DictAdapterForMigration::const_iterator DictAdapterForMigration::cend() const {
-  return dict_.cend();
+  return dict_->cend();
 }
 
 bool DictAdapterForMigration::contains(base::StringPiece key) const {
-  return dict_.contains(key);
+  return dict_->contains(key);
 }
 
 Value::Dict DictAdapterForMigration::Clone() const {
-  return dict_.Clone();
+  return dict_->Clone();
 }
 
 const Value* DictAdapterForMigration::Find(StringPiece key) const {
-  return dict_.Find(key);
+  return dict_->Find(key);
 }
 
 absl::optional<bool> DictAdapterForMigration::FindBool(StringPiece key) const {
-  return dict_.FindBool(key);
+  return dict_->FindBool(key);
 }
 
 absl::optional<int> DictAdapterForMigration::FindInt(StringPiece key) const {
-  return dict_.FindInt(key);
+  return dict_->FindInt(key);
 }
 
 absl::optional<double> DictAdapterForMigration::FindDouble(
     StringPiece key) const {
-  return dict_.FindDouble(key);
+  return dict_->FindDouble(key);
 }
 const std::string* DictAdapterForMigration::FindString(StringPiece key) const {
-  return dict_.FindString(key);
+  return dict_->FindString(key);
 }
 
 const Value::BlobStorage* DictAdapterForMigration::FindBlob(
     StringPiece key) const {
-  return dict_.FindBlob(key);
+  return dict_->FindBlob(key);
 }
 
 const Value::Dict* DictAdapterForMigration::FindDict(StringPiece key) const {
-  return dict_.FindDict(key);
+  return dict_->FindDict(key);
 }
 
 const Value::List* DictAdapterForMigration::FindList(StringPiece key) const {
-  return dict_.FindList(key);
+  return dict_->FindList(key);
 }
 
 const Value* DictAdapterForMigration::FindByDottedPath(StringPiece path) const {
-  return dict_.FindByDottedPath(path);
+  return dict_->FindByDottedPath(path);
 }
 
 absl::optional<bool> DictAdapterForMigration::FindBoolByDottedPath(
     StringPiece path) const {
-  return dict_.FindBoolByDottedPath(path);
+  return dict_->FindBoolByDottedPath(path);
 }
 
 absl::optional<int> DictAdapterForMigration::FindIntByDottedPath(
     StringPiece path) const {
-  return dict_.FindIntByDottedPath(path);
+  return dict_->FindIntByDottedPath(path);
 }
 
 absl::optional<double> DictAdapterForMigration::FindDoubleByDottedPath(
     StringPiece path) const {
-  return dict_.FindDoubleByDottedPath(path);
+  return dict_->FindDoubleByDottedPath(path);
 }
 
 const std::string* DictAdapterForMigration::FindStringByDottedPath(
     StringPiece path) const {
-  return dict_.FindStringByDottedPath(path);
+  return dict_->FindStringByDottedPath(path);
 }
 
 const Value::BlobStorage* DictAdapterForMigration::FindBlobByDottedPath(
     StringPiece path) const {
-  return dict_.FindBlobByDottedPath(path);
+  return dict_->FindBlobByDottedPath(path);
 }
 
 const Value::Dict* DictAdapterForMigration::FindDictByDottedPath(
     StringPiece path) const {
-  return dict_.FindDictByDottedPath(path);
+  return dict_->FindDictByDottedPath(path);
 }
 
 const Value::List* DictAdapterForMigration::FindListByDottedPath(
     StringPiece path) const {
-  return dict_.FindListByDottedPath(path);
+  return dict_->FindListByDottedPath(path);
 }
 
 std::string DictAdapterForMigration::DebugString() const {
-  return dict_.DebugString();
+  return dict_->DebugString();
 }
 
 #if BUILDFLAG(ENABLE_BASE_TRACING)
 void DictAdapterForMigration::WriteIntoTrace(
     perfetto::TracedValue context) const {
-  return dict_.WriteIntoTrace(std::move(context));
+  return dict_->WriteIntoTrace(std::move(context));
 }
 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
 
 const Value::Dict& DictAdapterForMigration::dict_for_test() const {
-  return dict_;
+  return *dict_;
 }
 
 ///////////////////// DictionaryValue ////////////////////
diff --git a/base/values.h b/base/values.h
index 0afa836c..dc0f445 100644
--- a/base/values.h
+++ b/base/values.h
@@ -25,6 +25,7 @@
 #include "base/containers/cxx20_erase_vector.h"
 #include "base/containers/flat_map.h"
 #include "base/containers/span.h"
+#include "base/memory/raw_ref.h"
 #include "base/strings/string_piece.h"
 #include "base/trace_event/base_tracing_forward.h"
 #include "base/value_iterators.h"
@@ -1277,7 +1278,7 @@
   const Value::Dict& dict_for_test() const;
 
  private:
-  const Value::Dict& dict_;
+  const raw_ref<const Value::Dict> dict_;
 };
 
 // DictionaryValue provides a key-value dictionary with (optional) "path"
diff --git a/base/win/scoped_handle_verifier.cc b/base/win/scoped_handle_verifier.cc
index edc705e..4b252c67 100644
--- a/base/win/scoped_handle_verifier.cc
+++ b/base/win/scoped_handle_verifier.cc
@@ -14,6 +14,7 @@
 #include "base/compiler_specific.h"
 #include "base/debug/alias.h"
 #include "base/debug/stack_trace.h"
+#include "base/memory/raw_ref.h"
 #include "base/synchronization/lock_impl.h"
 #include "base/trace_event/base_tracing.h"
 #include "base/win/base_win_buildflags.h"
@@ -69,15 +70,15 @@
 // recursive locking.
 class AutoNativeLock {
  public:
-  explicit AutoNativeLock(NativeLock& lock) : lock_(lock) { lock_.Lock(); }
+  explicit AutoNativeLock(NativeLock& lock) : lock_(lock) { lock_->Lock(); }
 
   AutoNativeLock(const AutoNativeLock&) = delete;
   AutoNativeLock& operator=(const AutoNativeLock&) = delete;
 
-  ~AutoNativeLock() { lock_.Unlock(); }
+  ~AutoNativeLock() { lock_->Unlock(); }
 
  private:
-  NativeLock& lock_;
+  const raw_ref<NativeLock> lock_;
 };
 
 ScopedHandleVerifierInfo::ScopedHandleVerifierInfo(
diff --git a/chrome/browser/segmentation_platform/segmentation_platform_config_unittest.cc b/chrome/browser/segmentation_platform/segmentation_platform_config_unittest.cc
index d08dece..aab5f0c 100644
--- a/chrome/browser/segmentation_platform/segmentation_platform_config_unittest.cc
+++ b/chrome/browser/segmentation_platform/segmentation_platform_config_unittest.cc
@@ -31,7 +31,7 @@
     for (const auto& feature : enabled_features) {
       constexpr char kTrialPrefix[] = "scoped_feature_list_trial_for_";
       auto* field_trial = base::FieldTrialList::Find(
-          base::StrCat({kTrialPrefix, feature.feature.name}));
+          base::StrCat({kTrialPrefix, feature.feature->name}));
       ASSERT_TRUE(field_trial);
       field_trial->Activate();
     }
diff --git a/content/public/test/back_forward_cache_util.cc b/content/public/test/back_forward_cache_util.cc
index 37a3ee0..2d5ff91d 100644
--- a/content/public/test/back_forward_cache_util.cc
+++ b/content/public/test/back_forward_cache_util.cc
@@ -77,9 +77,9 @@
   // additional feature as is.
   for (auto feature_and_params : additional_params) {
     auto default_feature_and_param = base::ranges::find(
-        default_features_and_params, feature_and_params.feature.name,
+        default_features_and_params, feature_and_params.feature->name,
         [](const base::test::FeatureRefAndParams default_feature) {
-          return default_feature.feature.name;
+          return default_feature.feature->name;
         });
     if (default_feature_and_param != default_features_and_params.end()) {
       base::FieldTrialParams combined_params;
@@ -88,7 +88,7 @@
       combined_params.insert(feature_and_params.params.begin(),
                              feature_and_params.params.end());
       final_params.emplace_back(base::test::FeatureRefAndParams(
-          feature_and_params.feature, combined_params));
+          *feature_and_params.feature, combined_params));
     } else {
       final_params.emplace_back(feature_and_params);
     }
@@ -96,9 +96,9 @@
   // Add any default features we didn't have additional params for.
   for (auto feature_and_params : default_features_and_params) {
     if (!base::Contains(
-            final_params, feature_and_params.feature.name,
+            final_params, feature_and_params.feature->name,
             [](const base::test::FeatureRefAndParams default_feature) {
-              return default_feature.feature.name;
+              return default_feature.feature->name;
             })) {
       final_params.emplace_back(feature_and_params);
     }