xref: /aosp_15_r20/external/angle/third_party/abseil-cpp/absl/base/nullability.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 // -----------------------------------------------------------------------------
16 // File: nullability.h
17 // -----------------------------------------------------------------------------
18 //
19 // This header file defines a set of "templated annotations" for designating the
20 // expected nullability of pointers. These annotations allow you to designate
21 // pointers in one of three classification states:
22 //
23 //  * "Non-null" (for pointers annotated `Nonnull<T>`), indicating that it is
24 //    invalid for the given pointer to ever be null.
25 //  * "Nullable" (for pointers annotated `Nullable<T>`), indicating that it is
26 //    valid for the given pointer to be null.
27 //  * "Unknown" (for pointers annotated `NullabilityUnknown<T>`), indicating
28 //    that the given pointer has not been yet classified as either nullable or
29 //    non-null. This is the default state of unannotated pointers.
30 //
31 // NOTE: unannotated pointers implicitly bear the annotation
32 // `NullabilityUnknown<T>`; you should rarely, if ever, see this annotation used
33 // in the codebase explicitly.
34 //
35 // -----------------------------------------------------------------------------
36 // Nullability and Contracts
37 // -----------------------------------------------------------------------------
38 //
39 // These nullability annotations allow you to more clearly specify contracts on
40 // software components by narrowing the *preconditions*, *postconditions*, and
41 // *invariants* of pointer state(s) in any given interface. It then depends on
42 // context who is responsible for fulfilling the annotation's requirements.
43 //
44 // For example, a function may receive a pointer argument. Designating that
45 // pointer argument as "non-null" tightens the precondition of the contract of
46 // that function. It is then the responsibility of anyone calling such a
47 // function to ensure that the passed pointer is not null.
48 //
49 // Similarly, a function may have a pointer as a return value. Designating that
50 // return value as "non-null" tightens the postcondition of the contract of that
51 // function. In this case, however, it is the responsibility of the function
52 // itself to ensure that the returned pointer is not null.
53 //
54 // Clearly defining these contracts allows providers (and consumers) of such
55 // pointers to have more confidence in their null state. If a function declares
56 // a return value as "non-null", for example, the caller should not need to
57 // check whether the returned value is `nullptr`; it can simply assume the
58 // pointer is valid.
59 //
60 // Of course most interfaces already have expectations on the nullability state
61 // of pointers, and these expectations are, in effect, a contract; often,
62 // however, those contracts are either poorly or partially specified, assumed,
63 // or misunderstood. These nullability annotations are designed to allow you to
64 // formalize those contracts within the codebase.
65 //
66 // -----------------------------------------------------------------------------
67 // Using Nullability Annotations
68 // -----------------------------------------------------------------------------
69 //
70 // It is important to note that these annotations are not distinct strong
71 // *types*. They are alias templates defined to be equal to the underlying
72 // pointer type. A pointer annotated `Nonnull<T*>`, for example, is simply a
73 // pointer of type `T*`. Each annotation acts as a form of documentation about
74 // the contract for the given pointer. Each annotation requires providers or
75 // consumers of these pointers across API boundaries to take appropriate steps
76 // when setting or using these pointers:
77 //
78 // * "Non-null" pointers should never be null. It is the responsibility of the
79 //   provider of this pointer to ensure that the pointer may never be set to
80 //   null. Consumers of such pointers can treat such pointers as non-null.
81 // * "Nullable" pointers may or may not be null. Consumers of such pointers
82 //   should precede any usage of that pointer (e.g. a dereference operation)
83 //   with a a `nullptr` check.
84 // * "Unknown" pointers may be either "non-null" or "nullable" but have not been
85 //   definitively determined to be in either classification state. Providers of
86 //   such pointers across API boundaries should determine --  over time -- to
87 //   annotate the pointer in either of the above two states. Consumers of such
88 //   pointers across an API boundary should continue to treat such pointers as
89 //   they currently do.
90 //
91 // Example:
92 //
93 // // PaySalary() requires the passed pointer to an `Employee` to be non-null.
94 // void PaySalary(absl::Nonnull<Employee *> e) {
95 //   pay(e->salary);  // OK to dereference
96 // }
97 //
98 // // CompleteTransaction() guarantees the returned pointer to an `Account` to
99 // // be non-null.
100 // absl::Nonnull<Account *> balance CompleteTransaction(double fee) {
101 // ...
102 // }
103 //
104 // // Note that specifying a nullability annotation does not prevent someone
105 // // from violating the contract:
106 //
107 // Nullable<Employee *> find(Map& employees, std::string_view name);
108 //
109 // void g(Map& employees) {
110 //   Employee *e = find(employees, "Pat");
111 //   // `e` can now be null.
112 //   PaySalary(e); // Violates contract, but compiles!
113 // }
114 //
115 // Nullability annotations, in other words, are useful for defining and
116 // narrowing contracts; *enforcement* of those contracts depends on use and any
117 // additional (static or dynamic analysis) tooling.
118 //
119 // NOTE: The "unknown" annotation state indicates that a pointer's contract has
120 // not yet been positively identified. The unknown state therefore acts as a
121 // form of documentation of your technical debt, and a codebase that adopts
122 // nullability annotations should aspire to annotate every pointer as either
123 // "non-null" or "nullable".
124 //
125 // -----------------------------------------------------------------------------
126 // Applicability of Nullability Annotations
127 // -----------------------------------------------------------------------------
128 //
129 // By default, nullability annotations are applicable to raw and smart
130 // pointers. User-defined types can indicate compatibility with nullability
131 // annotations by adding the ABSL_NULLABILITY_COMPATIBLE attribute.
132 //
133 // // Example:
134 // struct ABSL_NULLABILITY_COMPATIBLE MyPtr {
135 //   ...
136 // };
137 //
138 // Note: Compilers that don't support the `nullability_on_classes` feature will
139 // allow nullability annotations to be applied to any type, not just ones
140 // marked with `ABSL_NULLABILITY_COMPATIBLE`.
141 //
142 // DISCLAIMER:
143 // ===========================================================================
144 // These nullability annotations are primarily a human readable signal about the
145 // intended contract of the pointer. They are not *types* and do not currently
146 // provide any correctness guarantees. For example, a pointer annotated as
147 // `Nonnull<T*>` is *not guaranteed* to be non-null, and the compiler won't
148 // alert or prevent assignment of a `Nullable<T*>` to a `Nonnull<T*>`.
149 // ===========================================================================
150 #ifndef ABSL_BASE_NULLABILITY_H_
151 #define ABSL_BASE_NULLABILITY_H_
152 
153 #include "absl/base/config.h"
154 #include "absl/base/internal/nullability_impl.h"
155 
156 // ABSL_POINTERS_DEFAULT_NONNULL
157 //
158 // This macro specifies that all unannotated pointer types within the given
159 // file are designated as nonnull (instead of the default "unknown"). This macro
160 // exists as a standalone statement and applies default nonnull behavior to all
161 // subsequent pointers; as a result, place this macro as the first non-comment,
162 // non-`#include` line in a file.
163 //
164 // Example:
165 //
166 //     #include "absl/base/nullability.h"
167 //
168 //     ABSL_POINTERS_DEFAULT_NONNULL
169 //
170 //     void FillMessage(Message *m);                  // implicitly non-null
171 //     absl::Nullable<T*> GetNullablePtr();           // explicitly nullable
172 //     absl::NullabilityUnknown<T*> GetUnknownPtr();  // explicitly unknown
173 //
174 // The macro can be safely used in header files -- it will not affect any files
175 // that include it.
176 //
177 // In files with the macro, plain `T*` syntax means `absl::Nonnull<T*>`, and the
178 // exceptions (`Nullable` and `NullabilityUnknown`) must be marked
179 // explicitly. The same holds, correspondingly, for smart pointer types.
180 //
181 // For comparison, without the macro, all unannotated pointers would default to
182 // unknown, and otherwise require explicit annotations to change this behavior:
183 //
184 //     #include "absl/base/nullability.h"
185 //
186 //     void FillMessage(absl::Nonnull<Message*> m);  // explicitly non-null
187 //     absl::Nullable<T*> GetNullablePtr();          // explicitly nullable
188 //     T* GetUnknownPtr();                           // implicitly unknown
189 //
190 // No-op except for being a human readable signal.
191 #define ABSL_POINTERS_DEFAULT_NONNULL
192 
193 namespace absl {
194 ABSL_NAMESPACE_BEGIN
195 
196 // absl::Nonnull (default with `ABSL_POINTERS_DEFAULT_NONNULL`)
197 //
198 // The indicated pointer is never null. It is the responsibility of the provider
199 // of this pointer across an API boundary to ensure that the pointer is never
200 // set to null. Consumers of this pointer across an API boundary may safely
201 // dereference the pointer.
202 //
203 // Example:
204 //
205 // // `employee` is designated as not null.
206 // void PaySalary(absl::Nonnull<Employee *> employee) {
207 //   pay(*employee);  // OK to dereference
208 // }
209 template <typename T>
210 using Nonnull = nullability_internal::NonnullImpl<T>;
211 
212 // absl::Nullable
213 //
214 // The indicated pointer may, by design, be either null or non-null. Consumers
215 // of this pointer across an API boundary should perform a `nullptr` check
216 // before performing any operation using the pointer.
217 //
218 // Example:
219 //
220 // // `employee` may  be null.
221 // void PaySalary(absl::Nullable<Employee *> employee) {
222 //   if (employee != nullptr) {
223 //     Pay(*employee);  // OK to dereference
224 //   }
225 // }
226 template <typename T>
227 using Nullable = nullability_internal::NullableImpl<T>;
228 
229 // absl::NullabilityUnknown (default without `ABSL_POINTERS_DEFAULT_NONNULL`)
230 //
231 // The indicated pointer has not yet been determined to be definitively
232 // "non-null" or "nullable." Providers of such pointers across API boundaries
233 // should, over time, annotate such pointers as either "non-null" or "nullable."
234 // Consumers of these pointers across an API boundary should treat such pointers
235 // with the same caution they treat currently unannotated pointers. Most
236 // existing code will have "unknown"  pointers, which should eventually be
237 // migrated into one of the above two nullability states: `Nonnull<T>` or
238 //  `Nullable<T>`.
239 //
240 // NOTE: For files that do not specify `ABSL_POINTERS_DEFAULT_NONNULL`,
241 // because this annotation is the global default state, unannotated pointers are
242 // are assumed to have "unknown" semantics. This assumption is designed to
243 // minimize churn and reduce clutter within the codebase.
244 //
245 // Example:
246 //
247 // // `employee`s nullability state is unknown.
248 // void PaySalary(absl::NullabilityUnknown<Employee *> employee) {
249 //   Pay(*employee); // Potentially dangerous. API provider should investigate.
250 // }
251 //
252 // Note that a pointer without an annotation, by default, is assumed to have the
253 // annotation `NullabilityUnknown`.
254 //
255 // // `employee`s nullability state is unknown.
256 // void PaySalary(Employee* employee) {
257 //   Pay(*employee); // Potentially dangerous. API provider should investigate.
258 // }
259 template <typename T>
260 using NullabilityUnknown = nullability_internal::NullabilityUnknownImpl<T>;
261 
262 ABSL_NAMESPACE_END
263 }  // namespace absl
264 
265 // ABSL_NULLABILITY_COMPATIBLE
266 //
267 // Indicates that a class is compatible with nullability annotations.
268 //
269 // For example:
270 //
271 // struct ABSL_NULLABILITY_COMPATIBLE MyPtr {
272 //   ...
273 // };
274 //
275 // Note: Compilers that don't support the `nullability_on_classes` feature will
276 // allow nullability annotations to be applied to any type, not just ones marked
277 // with `ABSL_NULLABILITY_COMPATIBLE`.
278 #if ABSL_HAVE_FEATURE(nullability_on_classes)
279 #define ABSL_NULLABILITY_COMPATIBLE _Nullable
280 #else
281 #define ABSL_NULLABILITY_COMPATIBLE
282 #endif
283 
284 #endif  // ABSL_BASE_NULLABILITY_H_
285