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