• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "partition_alloc/pointers/raw_ref.h"
6 
7 #include <functional>
8 #include <type_traits>
9 
10 #include "base/memory/raw_ptr.h"
11 #include "base/test/gtest_util.h"
12 #include "partition_alloc/partition_alloc_base/debug/debugging_buildflags.h"
13 #include "partition_alloc/partition_alloc_buildflags.h"
14 #include "partition_alloc/pointers/raw_ptr_counting_impl_for_test.h"
15 #include "partition_alloc/pointers/raw_ptr_test_support.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #if BUILDFLAG(USE_ASAN_BACKUP_REF_PTR)
18 #include "base/debug/asan_service.h"
19 #include "base/memory/raw_ptr_asan_service.h"
20 #endif  // BUILDFLAG(USE_ASAN_BACKUP_REF_PTR)
21 
22 namespace {
23 
24 class BaseClass {};
25 class SubClass : public BaseClass {};
26 
27 // raw_ref just defers to the superclass for implementations, so it
28 // can't add more data types.
29 static_assert(sizeof(raw_ref<int>) == sizeof(raw_ptr<int>));
30 
31 // Since it can't hold null, raw_ref is not default-constructible.
32 static_assert(!std::is_default_constructible_v<raw_ref<int>>);
33 static_assert(!std::is_default_constructible_v<raw_ref<const int>>);
34 
35 // A mutable reference can only be constructed from a mutable lvalue reference.
36 static_assert(!std::is_constructible_v<raw_ref<int>, const int>);
37 static_assert(!std::is_constructible_v<raw_ref<int>, int>);
38 static_assert(!std::is_constructible_v<raw_ref<int>, const int&>);
39 static_assert(std::is_constructible_v<raw_ref<int>, int&>);
40 static_assert(!std::is_constructible_v<raw_ref<int>, const int*>);
41 static_assert(!std::is_constructible_v<raw_ref<int>, int*>);
42 static_assert(!std::is_constructible_v<raw_ref<int>, const int&&>);
43 static_assert(!std::is_constructible_v<raw_ref<int>, int&&>);
44 // Same for assignment.
45 static_assert(!std::is_assignable_v<raw_ref<int>, const int>);
46 static_assert(!std::is_assignable_v<raw_ref<int>, int>);
47 static_assert(!std::is_assignable_v<raw_ref<int>, const int&>);
48 static_assert(std::is_assignable_v<raw_ref<int>, int&>);
49 static_assert(!std::is_assignable_v<raw_ref<int>, const int*>);
50 static_assert(!std::is_assignable_v<raw_ref<int>, int*>);
51 static_assert(!std::is_assignable_v<raw_ref<int>, const int&&>);
52 static_assert(!std::is_assignable_v<raw_ref<int>, int&&>);
53 
54 // A const reference can be constructed from a const or mutable lvalue
55 // reference.
56 static_assert(!std::is_constructible_v<raw_ref<const int>, const int>);
57 static_assert(!std::is_constructible_v<raw_ref<const int>, int>);
58 static_assert(std::is_constructible_v<raw_ref<const int>, const int&>);
59 static_assert(std::is_constructible_v<raw_ref<const int>, int&>);
60 static_assert(!std::is_constructible_v<raw_ref<const int>, const int*>);
61 static_assert(!std::is_constructible_v<raw_ref<const int>, int*>);
62 static_assert(!std::is_constructible_v<raw_ref<const int>, const int&&>);
63 static_assert(!std::is_constructible_v<raw_ref<const int>, int&&>);
64 // Same for assignment.
65 static_assert(!std::is_assignable_v<raw_ref<const int>, const int>);
66 static_assert(!std::is_assignable_v<raw_ref<const int>, int>);
67 static_assert(std::is_assignable_v<raw_ref<const int>, const int&>);
68 static_assert(std::is_assignable_v<raw_ref<const int>, int&>);
69 static_assert(!std::is_assignable_v<raw_ref<const int>, const int*>);
70 static_assert(!std::is_assignable_v<raw_ref<const int>, int*>);
71 static_assert(!std::is_assignable_v<raw_ref<const int>, const int&&>);
72 static_assert(!std::is_assignable_v<raw_ref<const int>, int&&>);
73 
74 // Same trivial operations (or not) as raw_ptr<T>.
75 static_assert(std::is_trivially_constructible_v<raw_ref<int>, const int&> ==
76               std::is_trivially_constructible_v<raw_ptr<int>, const int&>);
77 static_assert(std::is_trivially_destructible_v<raw_ref<int>> ==
78               std::is_trivially_destructible_v<raw_ptr<int>>);
79 // But constructing from another raw_ref must check if it's internally null
80 // (which indicates use-after-move).
81 static_assert(!std::is_trivially_move_constructible_v<raw_ref<int>>);
82 static_assert(!std::is_trivially_move_assignable_v<raw_ref<int>>);
83 static_assert(!std::is_trivially_copy_constructible_v<raw_ref<int>>);
84 static_assert(!std::is_trivially_copy_assignable_v<raw_ref<int>>);
85 
86 // A raw_ref can be copied or moved.
87 static_assert(std::is_move_constructible_v<raw_ref<int>>);
88 static_assert(std::is_copy_constructible_v<raw_ref<int>>);
89 static_assert(std::is_move_assignable_v<raw_ref<int>>);
90 static_assert(std::is_copy_assignable_v<raw_ref<int>>);
91 
92 // A SubClass can be converted to a BaseClass.
93 static_assert(std::is_constructible_v<raw_ref<BaseClass>, raw_ref<SubClass>>);
94 static_assert(
95     std::is_constructible_v<raw_ref<BaseClass>, const raw_ref<SubClass>&>);
96 static_assert(std::is_constructible_v<raw_ref<BaseClass>, raw_ref<SubClass>&&>);
97 static_assert(std::is_assignable_v<raw_ref<BaseClass>, raw_ref<SubClass>>);
98 static_assert(
99     std::is_assignable_v<raw_ref<BaseClass>, const raw_ref<SubClass>&>);
100 static_assert(std::is_assignable_v<raw_ref<BaseClass>, raw_ref<SubClass>&&>);
101 // A BaseClass can't be implicitly downcasted.
102 static_assert(!std::is_constructible_v<raw_ref<SubClass>, raw_ref<BaseClass>>);
103 static_assert(
104     !std::is_constructible_v<raw_ref<SubClass>, const raw_ref<BaseClass>&>);
105 static_assert(
106     !std::is_constructible_v<raw_ref<SubClass>, raw_ref<BaseClass>&&>);
107 static_assert(!std::is_assignable_v<raw_ref<SubClass>, raw_ref<BaseClass>>);
108 static_assert(
109     !std::is_assignable_v<raw_ref<SubClass>, const raw_ref<BaseClass>&>);
110 static_assert(!std::is_assignable_v<raw_ref<SubClass>, raw_ref<BaseClass>&&>);
111 
112 // A raw_ref<BaseClass> can be constructed directly from a SubClass.
113 static_assert(std::is_constructible_v<raw_ref<BaseClass>, SubClass&>);
114 static_assert(std::is_assignable_v<raw_ref<BaseClass>, SubClass&>);
115 static_assert(std::is_constructible_v<raw_ref<const BaseClass>, SubClass&>);
116 static_assert(std::is_assignable_v<raw_ref<const BaseClass>, SubClass&>);
117 static_assert(
118     std::is_constructible_v<raw_ref<const BaseClass>, const SubClass&>);
119 static_assert(std::is_assignable_v<raw_ref<const BaseClass>, const SubClass&>);
120 // But a raw_ref<SubClass> can't be constructed from an implicit downcast from a
121 // BaseClass.
122 static_assert(!std::is_constructible_v<raw_ref<SubClass>, BaseClass&>);
123 static_assert(!std::is_assignable_v<raw_ref<SubClass>, BaseClass&>);
124 static_assert(!std::is_constructible_v<raw_ref<const SubClass>, BaseClass&>);
125 static_assert(!std::is_assignable_v<raw_ref<const SubClass>, BaseClass&>);
126 static_assert(
127     !std::is_constructible_v<raw_ref<const SubClass>, const BaseClass&>);
128 static_assert(!std::is_assignable_v<raw_ref<const SubClass>, const BaseClass&>);
129 
130 // A mutable reference can be converted to const reference.
131 static_assert(std::is_constructible_v<raw_ref<const int>, raw_ref<int>>);
132 static_assert(std::is_assignable_v<raw_ref<const int>, raw_ref<int>>);
133 // A const reference can't be converted to mutable.
134 static_assert(!std::is_constructible_v<raw_ref<int>, raw_ref<const int>>);
135 static_assert(!std::is_assignable_v<raw_ref<int>, raw_ref<const int>>);
136 
137 // The deref operator gives the internal reference.
138 static_assert(std::is_same_v<int&, decltype(*std::declval<raw_ref<int>>())>);
139 static_assert(
140     std::is_same_v<int&, decltype(*std::declval<const raw_ref<int>>())>);
141 static_assert(std::is_same_v<int&, decltype(*std::declval<raw_ref<int>&>())>);
142 static_assert(
143     std::is_same_v<int&, decltype(*std::declval<const raw_ref<int>&>())>);
144 static_assert(std::is_same_v<int&, decltype(*std::declval<raw_ref<int>&&>())>);
145 static_assert(
146     std::is_same_v<int&, decltype(*std::declval<const raw_ref<int>&&>())>);
147 // A const T is always returned as const.
148 static_assert(
149     std::is_same_v<const int&, decltype(*std::declval<raw_ref<const int>>())>);
150 
151 // The arrow operator gives a (non-null) pointer to the internal reference.
152 static_assert(
153     std::is_same_v<int*, decltype(std::declval<raw_ref<int>>().operator->())>);
154 static_assert(
155     std::is_same_v<const int*,
156                    decltype(std::declval<raw_ref<const int>>().operator->())>);
157 
158 // Verify that raw_ref is a literal type, and its entire interface is constexpr.
159 //
160 // Constexpr destructors were introduced in C++20. PartitionAlloc's minimum
161 // supported C++ version is C++17, so raw_ref is not a literal type in C++17.
162 // Thus we only test for constexpr in C++20.
163 #if defined(__cpp_constexpr) && __cpp_constexpr >= 201907L
__anonf4a252480202() 164 static_assert([]() constexpr {
165   struct IntBase {};
166   struct Int : public IntBase {
167     int i = 0;
168   };
169 
170   Int* i = new Int();
171   {
172     raw_ref<Int> r(*i);              // raw_ref(T&)
173     r = *i;                          // operator=(T&)
174     raw_ref<Int> r2(r);              // raw_ref(const raw_ref&)
175     raw_ref<Int> r3(std::move(r2));  // raw_ref(raw_ref&&)
176     r2 = r;                          // operator=(const raw_ref&)
177     r3 = std::move(r2);              // operator=(raw_ref&&)
178     r2 = r;                          // Reset after move.
179     [[maybe_unused]] raw_ref<IntBase> r5(
180         r2);  // raw_ref(const raw_ref<Convertible>&)
181     [[maybe_unused]] raw_ref<IntBase> r6(
182         std::move(r2));         // raw_ref(raw_ref<Convertible>&&)
183     r2 = r;                     // Reset after move.
184     r5 = r2;                    // operator=(const raw_ref<Convertible>&)
185     r6 = std::move(r2);         // operator=(raw_ref<Convertible>&&)
186     raw_ref<Int>::from_ptr(i);  // from_ptr(T*)
187     (*r).i += 1;                // operator*()
188     r.get().i += 1;             // get()
189     r->i += 1;                  // operator->()
190     r2 = r;                     // Reset after move.
191     swap(r, r2);                // swap()
192   }
193   delete i;
194   return true;
195 }());
196 #endif
197 
198 struct StructWithoutTypeBasedTraits {};
199 struct BaseWithTypeBasedTraits {};
200 struct DerivedWithTypeBasedTraits : BaseWithTypeBasedTraits {};
201 
202 }  // namespace
203 
204 namespace base::raw_ptr_traits {
205 // `BaseWithTypeBasedTraits` and any derived classes have
206 // `RawPtrTraits::kDummyForTest`.
207 template <typename T>
208 constexpr auto kTypeTraits<
209     T,
210     std::enable_if_t<std::is_base_of_v<BaseWithTypeBasedTraits, T>>> =
211     RawPtrTraits::kDummyForTest;
212 }  // namespace base::raw_ptr_traits
213 
214 // `raw_ptr<T>` should have traits based on specialization of `kTypeTraits<T>`.
215 static_assert(!ContainsFlags(raw_ref<StructWithoutTypeBasedTraits>::Traits,
216                              base::RawPtrTraits::kDummyForTest));
217 static_assert(ContainsFlags(raw_ref<BaseWithTypeBasedTraits>::Traits,
218                             base::RawPtrTraits::kDummyForTest));
219 static_assert(ContainsFlags(raw_ref<DerivedWithTypeBasedTraits>::Traits,
220                             base::RawPtrTraits::kDummyForTest));
221 
222 namespace {
223 
TEST(RawRef,Construct)224 TEST(RawRef, Construct) {
225   int i = 1;
226   auto r = raw_ref<int>(i);
227   EXPECT_EQ(&*r, &i);
228   auto cr = raw_ref<const int>(i);
229   EXPECT_EQ(&*cr, &i);
230   const int ci = 1;
231   auto cci = raw_ref<const int>(ci);
232   EXPECT_EQ(&*cci, &ci);
233 }
234 
TEST(RawRef,CopyConstruct)235 TEST(RawRef, CopyConstruct) {
236   {
237     int i = 1;
238     auto r = raw_ref<int>(i);
239     EXPECT_EQ(&*r, &i);
240     auto r2 = raw_ref<int>(r);
241     EXPECT_EQ(&*r2, &i);
242   }
243   {
244     int i = 1;
245     auto r = raw_ref<const int>(i);
246     EXPECT_EQ(&*r, &i);
247     auto r2 = raw_ref<const int>(r);
248     EXPECT_EQ(&*r2, &i);
249   }
250 }
251 
TEST(RawRef,MoveConstruct)252 TEST(RawRef, MoveConstruct) {
253   {
254     int i = 1;
255     auto r = raw_ref<int>(i);
256     EXPECT_EQ(&*r, &i);
257     auto r2 = raw_ref<int>(std::move(r));
258     EXPECT_EQ(&*r2, &i);
259   }
260   {
261     int i = 1;
262     auto r = raw_ref<const int>(i);
263     EXPECT_EQ(&*r, &i);
264     auto r2 = raw_ref<const int>(std::move(r));
265     EXPECT_EQ(&*r2, &i);
266   }
267 }
268 
TEST(RawRef,CopyAssign)269 TEST(RawRef, CopyAssign) {
270   {
271     int i = 1;
272     int j = 2;
273     auto r = raw_ref<int>(i);
274     EXPECT_EQ(&*r, &i);
275     auto rj = raw_ref<int>(j);
276     r = rj;
277     EXPECT_EQ(&*r, &j);
278   }
279   {
280     int i = 1;
281     int j = 2;
282     auto r = raw_ref<const int>(i);
283     EXPECT_EQ(&*r, &i);
284     auto rj = raw_ref<const int>(j);
285     r = rj;
286     EXPECT_EQ(&*r, &j);
287   }
288   {
289     int i = 1;
290     int j = 2;
291     auto r = raw_ref<const int>(i);
292     EXPECT_EQ(&*r, &i);
293     auto rj = raw_ref<int>(j);
294     r = rj;
295     EXPECT_EQ(&*r, &j);
296   }
297 }
298 
TEST(RawRef,CopyReassignAfterMove)299 TEST(RawRef, CopyReassignAfterMove) {
300   int i = 1;
301   int j = 1;
302   auto r = raw_ref<int>(i);
303   auto r2 = std::move(r);
304   r2 = raw_ref<int>(j);
305   // Reassign to the moved-from `r` so it can be used again.
306   r = r2;
307   EXPECT_EQ(&*r, &j);
308 }
309 
TEST(RawRef,MoveAssign)310 TEST(RawRef, MoveAssign) {
311   {
312     int i = 1;
313     int j = 2;
314     auto r = raw_ref<int>(i);
315     EXPECT_EQ(&*r, &i);
316     r = raw_ref<int>(j);
317     EXPECT_EQ(&*r, &j);
318   }
319   {
320     int i = 1;
321     int j = 2;
322     auto r = raw_ref<const int>(i);
323     EXPECT_EQ(&*r, &i);
324     r = raw_ref<const int>(j);
325     EXPECT_EQ(&*r, &j);
326   }
327   {
328     int i = 1;
329     int j = 2;
330     auto r = raw_ref<const int>(i);
331     EXPECT_EQ(&*r, &i);
332     r = raw_ref<int>(j);
333     EXPECT_EQ(&*r, &j);
334   }
335 }
336 
TEST(RawRef,MoveReassignAfterMove)337 TEST(RawRef, MoveReassignAfterMove) {
338   int i = 1;
339   int j = 1;
340   auto r = raw_ref<int>(i);
341   auto r2 = std::move(r);
342   // Reassign to the moved-from `r` so it can be used again.
343   r = raw_ref<int>(j);
344   EXPECT_EQ(&*r, &j);
345 }
346 
TEST(RawRef,CopyConstructUpCast)347 TEST(RawRef, CopyConstructUpCast) {
348   {
349     auto s = SubClass();
350     auto r = raw_ref<SubClass>(s);
351     EXPECT_EQ(&*r, &s);
352     auto r2 = raw_ref<BaseClass>(r);
353     EXPECT_EQ(&*r2, &s);
354   }
355   {
356     auto s = SubClass();
357     auto r = raw_ref<const SubClass>(s);
358     EXPECT_EQ(&*r, &s);
359     auto r2 = raw_ref<const BaseClass>(r);
360     EXPECT_EQ(&*r2, &s);
361   }
362 }
363 
TEST(RawRef,MoveConstructUpCast)364 TEST(RawRef, MoveConstructUpCast) {
365   {
366     auto s = SubClass();
367     auto r = raw_ref<SubClass>(s);
368     EXPECT_EQ(&*r, &s);
369     auto r2 = raw_ref<BaseClass>(std::move(r));
370     EXPECT_EQ(&*r2, &s);
371   }
372   {
373     auto s = SubClass();
374     auto r = raw_ref<const SubClass>(s);
375     EXPECT_EQ(&*r, &s);
376     auto r2 = raw_ref<const BaseClass>(std::move(r));
377     EXPECT_EQ(&*r2, &s);
378   }
379 }
380 
TEST(RawRef,FromPtr)381 TEST(RawRef, FromPtr) {
382   int i = 42;
383   auto ref = raw_ref<int>::from_ptr(&i);
384   EXPECT_EQ(&i, &*ref);
385 }
386 
TEST(RawRef,CopyAssignUpCast)387 TEST(RawRef, CopyAssignUpCast) {
388   {
389     auto s = SubClass();
390     auto r = raw_ref<SubClass>(s);
391     auto t = BaseClass();
392     auto rt = raw_ref<BaseClass>(t);
393     rt = r;
394     EXPECT_EQ(&*rt, &s);
395   }
396   {
397     auto s = SubClass();
398     auto r = raw_ref<const SubClass>(s);
399     auto t = BaseClass();
400     auto rt = raw_ref<const BaseClass>(t);
401     rt = r;
402     EXPECT_EQ(&*rt, &s);
403   }
404   {
405     auto s = SubClass();
406     auto r = raw_ref<SubClass>(s);
407     auto t = BaseClass();
408     auto rt = raw_ref<const BaseClass>(t);
409     rt = r;
410     EXPECT_EQ(&*rt, &s);
411   }
412 }
413 
TEST(RawRef,MoveAssignUpCast)414 TEST(RawRef, MoveAssignUpCast) {
415   {
416     auto s = SubClass();
417     auto r = raw_ref<SubClass>(s);
418     auto t = BaseClass();
419     auto rt = raw_ref<BaseClass>(t);
420     rt = std::move(r);
421     EXPECT_EQ(&*rt, &s);
422   }
423   {
424     auto s = SubClass();
425     auto r = raw_ref<const SubClass>(s);
426     auto t = BaseClass();
427     auto rt = raw_ref<const BaseClass>(t);
428     rt = std::move(r);
429     EXPECT_EQ(&*rt, &s);
430   }
431   {
432     auto s = SubClass();
433     auto r = raw_ref<SubClass>(s);
434     auto t = BaseClass();
435     auto rt = raw_ref<const BaseClass>(t);
436     rt = std::move(r);
437     EXPECT_EQ(&*rt, &s);
438   }
439 }
440 
TEST(RawRef,Deref)441 TEST(RawRef, Deref) {
442   int i;
443   auto r = raw_ref<int>(i);
444   EXPECT_EQ(&*r, &i);
445 }
446 
TEST(RawRef,Arrow)447 TEST(RawRef, Arrow) {
448   int i;
449   auto r = raw_ref<int>(i);
450   EXPECT_EQ(r.operator->(), &i);
451 }
452 
TEST(RawRef,Swap)453 TEST(RawRef, Swap) {
454   int i;
455   int j;
456   auto ri = raw_ref<int>(i);
457   auto rj = raw_ref<int>(j);
458   swap(ri, rj);
459   EXPECT_EQ(&*ri, &j);
460   EXPECT_EQ(&*rj, &i);
461 }
462 
TEST(RawRef,Equals)463 TEST(RawRef, Equals) {
464   int i = 1;
465   auto r1 = raw_ref<int>(i);
466   auto r2 = raw_ref<int>(i);
467   EXPECT_TRUE(r1 == r1);
468   EXPECT_TRUE(r1 == r2);
469   EXPECT_TRUE(r1 == i);
470   EXPECT_TRUE(i == r1);
471   int j = 1;
472   auto r3 = raw_ref<int>(j);
473   EXPECT_FALSE(r1 == r3);
474   EXPECT_FALSE(r1 == j);
475   EXPECT_FALSE(j == r1);
476 }
477 
TEST(RawRef,NotEquals)478 TEST(RawRef, NotEquals) {
479   int i = 1;
480   auto r1 = raw_ref<int>(i);
481   int j = 1;
482   auto r2 = raw_ref<int>(j);
483   EXPECT_TRUE(r1 != r2);
484   EXPECT_TRUE(r1 != j);
485   EXPECT_TRUE(j != r1);
486   EXPECT_FALSE(r1 != r1);
487   EXPECT_FALSE(r2 != j);
488   EXPECT_FALSE(j != r2);
489 }
490 
TEST(RawRef,LessThan)491 TEST(RawRef, LessThan) {
492   int i[] = {1, 1};
493   auto r1 = raw_ref<int>(i[0]);
494   auto r2 = raw_ref<int>(i[1]);
495   EXPECT_TRUE(r1 < r2);
496   EXPECT_TRUE(r1 < i[1]);
497   EXPECT_FALSE(i[1] < r1);
498   EXPECT_FALSE(r2 < r1);
499   EXPECT_FALSE(r2 < i[0]);
500   EXPECT_TRUE(i[0] < r2);
501   EXPECT_FALSE(r1 < r1);
502   EXPECT_FALSE(r1 < i[0]);
503   EXPECT_FALSE(i[0] < r1);
504 }
505 
TEST(RawRef,GreaterThan)506 TEST(RawRef, GreaterThan) {
507   int i[] = {1, 1};
508   auto r1 = raw_ref<int>(i[0]);
509   auto r2 = raw_ref<int>(i[1]);
510   EXPECT_TRUE(r2 > r1);
511   EXPECT_FALSE(r1 > r2);
512   EXPECT_FALSE(r1 > i[1]);
513   EXPECT_TRUE(i[1] > r1);
514   EXPECT_FALSE(r2 > r2);
515   EXPECT_FALSE(r2 > i[1]);
516   EXPECT_FALSE(i[1] > r2);
517 }
518 
TEST(RawRef,LessThanOrEqual)519 TEST(RawRef, LessThanOrEqual) {
520   int i[] = {1, 1};
521   auto r1 = raw_ref<int>(i[0]);
522   auto r2 = raw_ref<int>(i[1]);
523   EXPECT_TRUE(r1 <= r2);
524   EXPECT_TRUE(r1 <= r1);
525   EXPECT_TRUE(r2 <= r2);
526   EXPECT_FALSE(r2 <= r1);
527   EXPECT_TRUE(r1 <= i[1]);
528   EXPECT_TRUE(r1 <= i[0]);
529   EXPECT_TRUE(r2 <= i[1]);
530   EXPECT_FALSE(r2 <= i[0]);
531   EXPECT_FALSE(i[1] <= r1);
532   EXPECT_TRUE(i[0] <= r1);
533   EXPECT_TRUE(i[1] <= r2);
534   EXPECT_TRUE(i[0] <= r2);
535 }
536 
TEST(RawRef,GreaterThanOrEqual)537 TEST(RawRef, GreaterThanOrEqual) {
538   int i[] = {1, 1};
539   auto r1 = raw_ref<int>(i[0]);
540   auto r2 = raw_ref<int>(i[1]);
541   EXPECT_TRUE(r2 >= r1);
542   EXPECT_TRUE(r1 >= r1);
543   EXPECT_TRUE(r2 >= r2);
544   EXPECT_FALSE(r1 >= r2);
545   EXPECT_TRUE(r2 >= i[0]);
546   EXPECT_TRUE(r1 >= i[0]);
547   EXPECT_TRUE(r2 >= i[1]);
548   EXPECT_FALSE(r1 >= i[1]);
549   EXPECT_FALSE(i[0] >= r2);
550   EXPECT_TRUE(i[0] >= r1);
551   EXPECT_TRUE(i[1] >= r2);
552   EXPECT_TRUE(i[1] >= r1);
553 }
554 
555 // Death Tests: If we're only using the no-op version of `raw_ptr` and
556 // have `!BUILDFLAG(PA_DCHECK_IS_ON)`, the `PA_RAW_PTR_CHECK()`s used in
557 // `raw_ref` evaluate to nothing. Therefore, death tests relying on
558 // these CHECKs firing are disabled in their absence.
559 
560 #if BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) || \
561     BUILDFLAG(USE_ASAN_BACKUP_REF_PTR) || BUILDFLAG(PA_DCHECK_IS_ON)
562 
TEST(RawRefDeathTest,CopyConstructAfterMove)563 TEST(RawRefDeathTest, CopyConstructAfterMove) {
564   int i = 1;
565   auto r = raw_ref<int>(i);
566   auto r2 = std::move(r);
567   EXPECT_CHECK_DEATH({ [[maybe_unused]] auto r3 = r; });
568 }
569 
TEST(RawRefDeathTest,MoveConstructAfterMove)570 TEST(RawRefDeathTest, MoveConstructAfterMove) {
571   int i = 1;
572   auto r = raw_ref<int>(i);
573   auto r2 = std::move(r);
574   EXPECT_CHECK_DEATH({ [[maybe_unused]] auto r3 = std::move(r); });
575 }
576 
TEST(RawRefDeathTest,CopyAssignAfterMove)577 TEST(RawRefDeathTest, CopyAssignAfterMove) {
578   int i = 1;
579   auto r = raw_ref<int>(i);
580   auto r2 = std::move(r);
581   EXPECT_CHECK_DEATH({ r2 = r; });
582 }
583 
TEST(RawRefDeathTest,MoveAssignAfterMove)584 TEST(RawRefDeathTest, MoveAssignAfterMove) {
585   int i = 1;
586   auto r = raw_ref<int>(i);
587   auto r2 = std::move(r);
588   EXPECT_CHECK_DEATH({ r2 = std::move(r); });
589 }
590 
TEST(RawRefDeathTest,CopyConstructAfterMoveUpCast)591 TEST(RawRefDeathTest, CopyConstructAfterMoveUpCast) {
592   auto s = SubClass();
593   auto r = raw_ref<SubClass>(s);
594   auto moved = std::move(r);
595   EXPECT_CHECK_DEATH({ [[maybe_unused]] auto r2 = raw_ref<BaseClass>(r); });
596 }
597 
TEST(RawRefDeathTest,MoveConstructAfterMoveUpCast)598 TEST(RawRefDeathTest, MoveConstructAfterMoveUpCast) {
599   auto s = SubClass();
600   auto r = raw_ref<SubClass>(s);
601   auto moved = std::move(r);
602   EXPECT_CHECK_DEATH(
603       { [[maybe_unused]] auto r2 = raw_ref<BaseClass>(std::move(r)); });
604 }
605 
TEST(RawRefDeathTest,FromPtrWithNullptr)606 TEST(RawRefDeathTest, FromPtrWithNullptr) {
607   EXPECT_CHECK_DEATH({ raw_ref<int>::from_ptr(nullptr); });
608 }
609 
TEST(RawRefDeathTest,CopyAssignAfterMoveUpCast)610 TEST(RawRefDeathTest, CopyAssignAfterMoveUpCast) {
611   auto s = SubClass();
612   auto r = raw_ref<const SubClass>(s);
613   auto t = BaseClass();
614   auto rt = raw_ref<const BaseClass>(t);
615   auto moved = std::move(r);
616   EXPECT_CHECK_DEATH({ rt = r; });
617 }
618 
TEST(RawRefDeathTest,MoveAssignAfterMoveUpCast)619 TEST(RawRefDeathTest, MoveAssignAfterMoveUpCast) {
620   auto s = SubClass();
621   auto r = raw_ref<const SubClass>(s);
622   auto t = BaseClass();
623   auto rt = raw_ref<const BaseClass>(t);
624   auto moved = std::move(r);
625   EXPECT_CHECK_DEATH({ rt = std::move(r); });
626 }
627 
TEST(RawRefDeathTest,DerefAfterMove)628 TEST(RawRefDeathTest, DerefAfterMove) {
629   int i;
630   auto r = raw_ref<int>(i);
631   auto moved = std::move(r);
632   EXPECT_CHECK_DEATH({ r.operator*(); });
633 }
634 
TEST(RawRefDeathTest,ArrowAfterMove)635 TEST(RawRefDeathTest, ArrowAfterMove) {
636   int i;
637   auto r = raw_ref<int>(i);
638   auto moved = std::move(r);
639   EXPECT_CHECK_DEATH({ r.operator->(); });
640 }
641 
TEST(RawRefDeathTest,SwapAfterMove)642 TEST(RawRefDeathTest, SwapAfterMove) {
643   {
644     int i;
645     auto ri = raw_ref<int>(i);
646     int j;
647     auto rj = raw_ref<int>(j);
648 
649     auto moved = std::move(ri);
650     EXPECT_CHECK_DEATH({ swap(ri, rj); });
651   }
652   {
653     int i;
654     auto ri = raw_ref<int>(i);
655     int j;
656     auto rj = raw_ref<int>(j);
657 
658     auto moved = std::move(rj);
659     EXPECT_CHECK_DEATH({ swap(ri, rj); });
660   }
661 }
662 
TEST(RawRefDeathTest,EqualsAfterMove)663 TEST(RawRefDeathTest, EqualsAfterMove) {
664   {
665     int i = 1;
666     auto r1 = raw_ref<int>(i);
667     auto r2 = raw_ref<int>(i);
668     auto moved = std::move(r1);
669     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 == r2; });
670   }
671   {
672     int i = 1;
673     auto r1 = raw_ref<int>(i);
674     auto r2 = raw_ref<int>(i);
675     auto moved = std::move(r2);
676     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 == r2; });
677   }
678   {
679     int i = 1;
680     auto r1 = raw_ref<int>(i);
681     auto moved = std::move(r1);
682     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 == r1; });
683   }
684 }
685 
TEST(RawRefDeathTest,NotEqualsAfterMove)686 TEST(RawRefDeathTest, NotEqualsAfterMove) {
687   {
688     int i = 1;
689     auto r1 = raw_ref<int>(i);
690     auto r2 = raw_ref<int>(i);
691     auto moved = std::move(r1);
692     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 != r2; });
693   }
694   {
695     int i = 1;
696     auto r1 = raw_ref<int>(i);
697     auto r2 = raw_ref<int>(i);
698     auto moved = std::move(r2);
699     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 != r2; });
700   }
701   {
702     int i = 1;
703     auto r1 = raw_ref<int>(i);
704     auto moved = std::move(r1);
705     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 != r1; });
706   }
707 }
708 
TEST(RawRefDeathTest,LessThanAfterMove)709 TEST(RawRefDeathTest, LessThanAfterMove) {
710   {
711     int i = 1;
712     auto r1 = raw_ref<int>(i);
713     auto r2 = raw_ref<int>(i);
714     auto moved = std::move(r1);
715     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 < r2; });
716   }
717   {
718     int i = 1;
719     auto r1 = raw_ref<int>(i);
720     auto r2 = raw_ref<int>(i);
721     auto moved = std::move(r2);
722     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 < r2; });
723   }
724   {
725     int i = 1;
726     auto r1 = raw_ref<int>(i);
727     auto moved = std::move(r1);
728     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 < r1; });
729   }
730 }
731 
TEST(RawRefDeathTest,GreaterThanAfterMove)732 TEST(RawRefDeathTest, GreaterThanAfterMove) {
733   {
734     int i = 1;
735     auto r1 = raw_ref<int>(i);
736     auto r2 = raw_ref<int>(i);
737     auto moved = std::move(r1);
738     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 > r2; });
739   }
740   {
741     int i = 1;
742     auto r1 = raw_ref<int>(i);
743     auto r2 = raw_ref<int>(i);
744     auto moved = std::move(r2);
745     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 > r2; });
746   }
747   {
748     int i = 1;
749     auto r1 = raw_ref<int>(i);
750     auto moved = std::move(r1);
751     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 > r1; });
752   }
753 }
754 
TEST(RawRefDeathTest,LessThanOrEqualAfterMove)755 TEST(RawRefDeathTest, LessThanOrEqualAfterMove) {
756   {
757     int i = 1;
758     auto r1 = raw_ref<int>(i);
759     auto r2 = raw_ref<int>(i);
760     auto moved = std::move(r1);
761     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 <= r2; });
762   }
763   {
764     int i = 1;
765     auto r1 = raw_ref<int>(i);
766     auto r2 = raw_ref<int>(i);
767     auto moved = std::move(r2);
768     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 <= r2; });
769   }
770   {
771     int i = 1;
772     auto r1 = raw_ref<int>(i);
773     auto moved = std::move(r1);
774     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 <= r1; });
775   }
776 }
777 
TEST(RawRefDeathTest,GreaterThanOrEqualAfterMove)778 TEST(RawRefDeathTest, GreaterThanOrEqualAfterMove) {
779   {
780     int i = 1;
781     auto r1 = raw_ref<int>(i);
782     auto r2 = raw_ref<int>(i);
783     auto moved = std::move(r1);
784     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 >= r2; });
785   }
786   {
787     int i = 1;
788     auto r1 = raw_ref<int>(i);
789     auto r2 = raw_ref<int>(i);
790     auto moved = std::move(r2);
791     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 >= r2; });
792   }
793   {
794     int i = 1;
795     auto r1 = raw_ref<int>(i);
796     auto moved = std::move(r1);
797     EXPECT_CHECK_DEATH({ [[maybe_unused]] bool b = r1 >= r1; });
798   }
799 }
800 
801 #endif  // BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) ||
802         // BUILDFLAG(USE_ASAN_BACKUP_REF_PTR) ||
803         // BUILDFLAG(PA_DCHECK_IS_ON)
804 
TEST(RawRef,CTAD)805 TEST(RawRef, CTAD) {
806   int i = 1;
807   auto r = raw_ref(i);
808   EXPECT_EQ(&*r, &i);
809 }
810 
TEST(RawRefPtr,CTADWithConst)811 TEST(RawRefPtr, CTADWithConst) {
812   std::string str;
813   struct S {
814     const raw_ref<const std::string> r;
815   };
816   // Deduces as `raw_ref<std::string>`, for which the constructor call is valid
817   // making a mutable reference, and then converts to
818   // `raw_ref<const std::string>`.
819   S s1 = {.r = raw_ref(str)};
820   // Deduces as raw_ref<const std::string>, for which the constructor call is
821   // valid from a const ref.
822   S s2 = {.r = raw_ref(static_cast<const std::string&>(str))};
823   EXPECT_EQ(&*s1.r, &str);
824   EXPECT_EQ(&*s2.r, &str);
825 }
826 
827 // Shorter name for expected test impl.
828 using RawPtrCountingImpl = base::test::RawPtrCountingImplForTest;
829 
830 template <typename T>
831 using CountingRawRef = raw_ref<T, base::RawPtrTraits::kUseCountingImplForTest>;
832 
833 // Ensure that the `kUseCountingImplForTest` flag selects the test impl.
834 static_assert(std::is_same_v<CountingRawRef<int>::Impl, RawPtrCountingImpl>);
835 
836 template <typename T>
837 using CountingRawRefMayDangle =
838     raw_ref<T,
839             base::RawPtrTraits::kMayDangle |
840                 base::RawPtrTraits::kUseCountingImplForTest>;
841 
842 // Ensure that the `kUseCountingImplForTest` flag selects the test impl.
843 static_assert(
844     std::is_same_v<CountingRawRefMayDangle<int>::Impl, RawPtrCountingImpl>);
845 
TEST(RawRef,StdLess)846 TEST(RawRef, StdLess) {
847   int i[] = {1, 1};
848   {
849     RawPtrCountingImpl::ClearCounters();
850     auto r1 = CountingRawRef<int>(i[0]);
851     auto r2 = CountingRawRef<int>(i[1]);
852     EXPECT_TRUE(std::less<CountingRawRef<int>>()(r1, r2));
853     EXPECT_FALSE(std::less<CountingRawRef<int>>()(r2, r1));
854     EXPECT_EQ(2, RawPtrCountingImpl::wrapped_ptr_less_cnt);
855   }
856   {
857     RawPtrCountingImpl::ClearCounters();
858     const auto r1 = CountingRawRef<int>(i[0]);
859     const auto r2 = CountingRawRef<int>(i[1]);
860     EXPECT_TRUE(std::less<CountingRawRef<int>>()(r1, r2));
861     EXPECT_FALSE(std::less<CountingRawRef<int>>()(r2, r1));
862     EXPECT_EQ(2, RawPtrCountingImpl::wrapped_ptr_less_cnt);
863   }
864   {
865     RawPtrCountingImpl::ClearCounters();
866     auto r1 = CountingRawRef<const int>(i[0]);
867     auto r2 = CountingRawRef<const int>(i[1]);
868     EXPECT_TRUE(std::less<CountingRawRef<const int>>()(r1, r2));
869     EXPECT_FALSE(std::less<CountingRawRef<const int>>()(r2, r1));
870     EXPECT_EQ(2, RawPtrCountingImpl::wrapped_ptr_less_cnt);
871   }
872   {
873     RawPtrCountingImpl::ClearCounters();
874     auto r1 = CountingRawRef<int>(i[0]);
875     auto r2 = CountingRawRef<int>(i[1]);
876     EXPECT_TRUE(std::less<CountingRawRef<int>>()(r1, i[1]));
877     EXPECT_FALSE(std::less<CountingRawRef<int>>()(r2, i[0]));
878     EXPECT_EQ(2, RawPtrCountingImpl::wrapped_ptr_less_cnt);
879   }
880   {
881     RawPtrCountingImpl::ClearCounters();
882     const auto r1 = CountingRawRef<int>(i[0]);
883     const auto r2 = CountingRawRef<int>(i[1]);
884     EXPECT_TRUE(std::less<CountingRawRef<int>>()(r1, i[1]));
885     EXPECT_FALSE(std::less<CountingRawRef<int>>()(r2, i[0]));
886     EXPECT_EQ(2, RawPtrCountingImpl::wrapped_ptr_less_cnt);
887   }
888   {
889     RawPtrCountingImpl::ClearCounters();
890     auto r1 = CountingRawRef<const int>(i[0]);
891     auto r2 = CountingRawRef<const int>(i[1]);
892     EXPECT_TRUE(std::less<CountingRawRef<const int>>()(r1, i[1]));
893     EXPECT_FALSE(std::less<CountingRawRef<const int>>()(r2, i[0]));
894     EXPECT_EQ(2, RawPtrCountingImpl::wrapped_ptr_less_cnt);
895   }
896 }
897 
898 // Verifies that comparing `raw_ref`s with different underlying Traits
899 // is a valid utterance and primarily uses the `GetForComparison()` methods.
TEST(RawRef,OperatorsUseGetForComparison)900 TEST(RawRef, OperatorsUseGetForComparison) {
901   int x = 123;
902   CountingRawRef<int> ref1(x);
903   CountingRawRefMayDangle<int> ref2(x);
904 
905   RawPtrCountingImpl::ClearCounters();
906 
907   EXPECT_TRUE(ref1 == ref2);
908   EXPECT_FALSE(ref1 != ref2);
909   // The use of `PA_RAW_PTR_CHECK()`s to catch dangling references means
910   // that we can't actually readily specify whether there are 0
911   // extractions (`CHECK()`s compiled out) or 2 extractions.
912   EXPECT_THAT((CountingRawPtrExpectations{.get_for_comparison_cnt = 4}),
913               CountersMatch());
914 
915   EXPECT_FALSE(ref1 < ref2);
916   EXPECT_FALSE(ref1 > ref2);
917   EXPECT_TRUE(ref1 <= ref2);
918   EXPECT_TRUE(ref1 >= ref2);
919   EXPECT_THAT((CountingRawPtrExpectations{
920                   .get_for_comparison_cnt = 12,
921               }),
922               CountersMatch());
923 }
924 
TEST(RawRef,CrossKindConversion)925 TEST(RawRef, CrossKindConversion) {
926   int x = 123;
927   CountingRawRef<int> ref1(x);
928 
929   RawPtrCountingImpl::ClearCounters();
930 
931   CountingRawRefMayDangle<int> ref2(ref1);
932   CountingRawRefMayDangle<int> ref3(std::move(ref1));  // Falls back to copy.
933 
934   EXPECT_THAT((CountingRawPtrExpectations{.wrap_raw_ptr_cnt = 0,
935                                           .get_for_dereference_cnt = 0,
936                                           .get_for_extraction_cnt = 0,
937                                           .wrap_raw_ptr_for_dup_cnt = 2,
938                                           .get_for_duplication_cnt = 2}),
939               CountersMatch());
940 }
941 
TEST(RawRef,CrossKindAssignment)942 TEST(RawRef, CrossKindAssignment) {
943   int x = 123;
944   CountingRawRef<int> ref1(x);
945 
946   CountingRawRefMayDangle<int> ref2(x);
947   CountingRawRefMayDangle<int> ref3(x);
948 
949   RawPtrCountingImpl::ClearCounters();
950   ref2 = ref1;
951   ref3 = std::move(ref1);  // Falls back to copy.
952 
953   EXPECT_THAT((CountingRawPtrExpectations{.wrap_raw_ptr_cnt = 0,
954                                           .get_for_dereference_cnt = 0,
955                                           .get_for_extraction_cnt = 0,
956                                           .wrap_raw_ptr_for_dup_cnt = 2,
957                                           .get_for_duplication_cnt = 2}),
958               CountersMatch());
959 }
960 
961 #if BUILDFLAG(USE_ASAN_BACKUP_REF_PTR)
962 
TEST(AsanBackupRefPtrImpl,RawRefGet)963 TEST(AsanBackupRefPtrImpl, RawRefGet) {
964   base::debug::AsanService::GetInstance()->Initialize();
965 
966   if (!base::RawPtrAsanService::GetInstance().IsEnabled()) {
967     base::RawPtrAsanService::GetInstance().Configure(
968         base::EnableDereferenceCheck(true), base::EnableExtractionCheck(true),
969         base::EnableInstantiationCheck(true));
970   } else {
971     ASSERT_TRUE(
972         base::RawPtrAsanService::GetInstance().is_dereference_check_enabled());
973     ASSERT_TRUE(
974         base::RawPtrAsanService::GetInstance().is_extraction_check_enabled());
975     ASSERT_TRUE(base::RawPtrAsanService::GetInstance()
976                     .is_instantiation_check_enabled());
977   }
978 
979   auto ptr = ::std::make_unique<int>();
980   raw_ref<int> safe_ref(*ptr);
981   ptr.reset();
982 
983   // This test is specifically to ensure that raw_ref.get() does not cause a
984   // dereference of the memory referred to by the reference. If there is a
985   // dereference, then this test will crash.
986   [[maybe_unused]] volatile int& ref = safe_ref.get();
987 }
988 
TEST(AsanBackupRefPtrImpl,RawRefOperatorStar)989 TEST(AsanBackupRefPtrImpl, RawRefOperatorStar) {
990   base::debug::AsanService::GetInstance()->Initialize();
991 
992   if (!base::RawPtrAsanService::GetInstance().IsEnabled()) {
993     base::RawPtrAsanService::GetInstance().Configure(
994         base::EnableDereferenceCheck(true), base::EnableExtractionCheck(true),
995         base::EnableInstantiationCheck(true));
996   } else {
997     ASSERT_TRUE(
998         base::RawPtrAsanService::GetInstance().is_dereference_check_enabled());
999     ASSERT_TRUE(
1000         base::RawPtrAsanService::GetInstance().is_extraction_check_enabled());
1001     ASSERT_TRUE(base::RawPtrAsanService::GetInstance()
1002                     .is_instantiation_check_enabled());
1003   }
1004 
1005   auto ptr = ::std::make_unique<int>();
1006   raw_ref<int> safe_ref(*ptr);
1007   ptr.reset();
1008 
1009   // This test is specifically to ensure that &*raw_ref does not cause a
1010   // dereference of the memory referred to by the reference. If there is a
1011   // dereference, then this test will crash.
1012   [[maybe_unused]] volatile int& ref = *safe_ref;
1013 }
1014 
1015 #endif  // BUILDFLAG(USE_ASAN_BACKUP_REF_PTR)
1016 
1017 }  // namespace
1018