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