xref: /aosp_15_r20/external/cronet/third_party/abseil-cpp/absl/base/nullability_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2023 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "absl/base/nullability.h"
16 
17 #include <cassert>
18 #include <memory>
19 #include <utility>
20 
21 #include "gtest/gtest.h"
22 #include "absl/base/attributes.h"
23 
24 namespace {
25 using ::absl::Nonnull;
26 using ::absl::NullabilityUnknown;
27 using ::absl::Nullable;
28 
funcWithNonnullArg(Nonnull<int * >)29 void funcWithNonnullArg(Nonnull<int*> /*arg*/) {}
30 template <typename T>
funcWithDeducedNonnullArg(Nonnull<T * >)31 void funcWithDeducedNonnullArg(Nonnull<T*> /*arg*/) {}
32 
TEST(NonnullTest,NonnullArgument)33 TEST(NonnullTest, NonnullArgument) {
34   int var = 0;
35   funcWithNonnullArg(&var);
36   funcWithDeducedNonnullArg(&var);
37 }
38 
funcWithNonnullReturn()39 Nonnull<int*> funcWithNonnullReturn() {
40   static int var = 0;
41   return &var;
42 }
43 
TEST(NonnullTest,NonnullReturn)44 TEST(NonnullTest, NonnullReturn) {
45   auto var = funcWithNonnullReturn();
46   (void)var;
47 }
48 
TEST(PassThroughTest,PassesThroughRawPointerToInt)49 TEST(PassThroughTest, PassesThroughRawPointerToInt) {
50   EXPECT_TRUE((std::is_same<Nonnull<int*>, int*>::value));
51   EXPECT_TRUE((std::is_same<Nullable<int*>, int*>::value));
52   EXPECT_TRUE((std::is_same<NullabilityUnknown<int*>, int*>::value));
53 }
54 
TEST(PassThroughTest,PassesThroughRawPointerToVoid)55 TEST(PassThroughTest, PassesThroughRawPointerToVoid) {
56   EXPECT_TRUE((std::is_same<Nonnull<void*>, void*>::value));
57   EXPECT_TRUE((std::is_same<Nullable<void*>, void*>::value));
58   EXPECT_TRUE((std::is_same<NullabilityUnknown<void*>, void*>::value));
59 }
60 
TEST(PassThroughTest,PassesThroughUniquePointerToInt)61 TEST(PassThroughTest, PassesThroughUniquePointerToInt) {
62   using T = std::unique_ptr<int>;
63   EXPECT_TRUE((std::is_same<Nonnull<T>, T>::value));
64   EXPECT_TRUE((std::is_same<Nullable<T>, T>::value));
65   EXPECT_TRUE((std::is_same<NullabilityUnknown<T>, T>::value));
66 }
67 
TEST(PassThroughTest,PassesThroughSharedPointerToInt)68 TEST(PassThroughTest, PassesThroughSharedPointerToInt) {
69   using T = std::shared_ptr<int>;
70   EXPECT_TRUE((std::is_same<Nonnull<T>, T>::value));
71   EXPECT_TRUE((std::is_same<Nullable<T>, T>::value));
72   EXPECT_TRUE((std::is_same<NullabilityUnknown<T>, T>::value));
73 }
74 
TEST(PassThroughTest,PassesThroughSharedPointerToVoid)75 TEST(PassThroughTest, PassesThroughSharedPointerToVoid) {
76   using T = std::shared_ptr<void>;
77   EXPECT_TRUE((std::is_same<Nonnull<T>, T>::value));
78   EXPECT_TRUE((std::is_same<Nullable<T>, T>::value));
79   EXPECT_TRUE((std::is_same<NullabilityUnknown<T>, T>::value));
80 }
81 
TEST(PassThroughTest,PassesThroughPointerToMemberObject)82 TEST(PassThroughTest, PassesThroughPointerToMemberObject) {
83   using T = decltype(&std::pair<int, int>::first);
84   EXPECT_TRUE((std::is_same<Nonnull<T>, T>::value));
85   EXPECT_TRUE((std::is_same<Nullable<T>, T>::value));
86   EXPECT_TRUE((std::is_same<NullabilityUnknown<T>, T>::value));
87 }
88 
TEST(PassThroughTest,PassesThroughPointerToMemberFunction)89 TEST(PassThroughTest, PassesThroughPointerToMemberFunction) {
90   using T = decltype(&std::unique_ptr<int>::reset);
91   EXPECT_TRUE((std::is_same<Nonnull<T>, T>::value));
92   EXPECT_TRUE((std::is_same<Nullable<T>, T>::value));
93   EXPECT_TRUE((std::is_same<NullabilityUnknown<T>, T>::value));
94 }
95 
96 }  // namespace
97 
98 // Nullable ADL lookup test
99 namespace util {
100 // Helper for NullableAdlTest.  Returns true, denoting that argument-dependent
101 // lookup found this implementation of DidAdlWin.  Must be in namespace
102 // util itself, not a nested anonymous namespace.
103 template <typename T>
DidAdlWin(T *)104 bool DidAdlWin(T*) {
105   return true;
106 }
107 
108 // Because this type is defined in namespace util, an unqualified call to
109 // DidAdlWin with a pointer to MakeAdlWin will find the above implementation.
110 struct MakeAdlWin {};
111 }  // namespace util
112 
113 namespace {
114 // Returns false, denoting that ADL did not inspect namespace util.  If it
115 // had, the better match (T*) above would have won out over the (...) here.
DidAdlWin(...)116 bool DidAdlWin(...) { return false; }
117 
TEST(NullableAdlTest,NullableAddsNothingToArgumentDependentLookup)118 TEST(NullableAdlTest, NullableAddsNothingToArgumentDependentLookup) {
119   // Treatment: util::Nullable<int*> contributes nothing to ADL because
120   // int* itself doesn't.
121   EXPECT_FALSE(DidAdlWin((int*)nullptr));
122   EXPECT_FALSE(DidAdlWin((Nullable<int*>)nullptr));
123 
124   // Control: Argument-dependent lookup does find the implementation in
125   // namespace util when the underlying pointee type resides there.
126   EXPECT_TRUE(DidAdlWin((util::MakeAdlWin*)nullptr));
127   EXPECT_TRUE(DidAdlWin((Nullable<util::MakeAdlWin*>)nullptr));
128 }
129 }  // namespace
130