tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nullability.h (15078B)


      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 annotations for designating the expected
     20 // nullability of pointers. These annotations allow you to designate pointers in
     21 // one of three classification states:
     22 //
     23 //  * "Non-null" (for pointers annotated `absl_nonnull`), indicating that it is
     24 //    invalid for the given pointer to ever be null.
     25 //  * "Nullable" (for pointers annotated `absl_nullable`), indicating that it is
     26 //    valid for the given pointer to be null.
     27 //  * "Unknown" (for pointers annotated `absl_nullability_unknown`), indicating
     28 //    that the given pointer has not yet been 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 // `absl_nullability_unknown`; you should rarely, if ever, see this annotation
     33 // used 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 // Annotation Syntax
     68 // -----------------------------------------------------------------------------
     69 //
     70 // The annotations should be positioned as a qualifier for the pointer type. For
     71 // example, the position of `const` when declaring a const pointer (not a
     72 // pointer to a const type) is the position you should also use for these
     73 // annotations.
     74 //
     75 // Example:
     76 //
     77 // // A const non-null pointer to an `Employee`.
     78 // Employee* absl_nonnull const e;
     79 //
     80 // // A non-null pointer to a const `Employee`.
     81 // const Employee* absl_nonnull e;
     82 //
     83 // // A non-null pointer to a const nullable pointer to an `Employee`.
     84 // Employee* absl_nullable const* absl_nonnull e = nullptr;
     85 //
     86 // // A non-null function pointer.
     87 // void (*absl_nonnull func)(int, double);
     88 //
     89 // // A non-null std::unique_ptr to an `Employee`.
     90 // // As with `const`, it is possible to place the annotation on either side of
     91 // // a named type not ending in `*`, but placing it before the type it
     92 // // describes is preferred, unless inconsistent with surrounding code.
     93 // absl_nonnull std::unique_ptr<Employee> employee;
     94 //
     95 // // Invalid annotation usage – this attempts to declare a pointer to a
     96 // // nullable `Employee`, which is meaningless.
     97 // absl_nullable Employee* e;
     98 //
     99 // -----------------------------------------------------------------------------
    100 // Using Nullability Annotations
    101 // -----------------------------------------------------------------------------
    102 //
    103 // Each annotation acts as a form of documentation about the contract for the
    104 // given pointer. Each annotation requires providers or consumers of these
    105 // pointers across API boundaries to take appropriate steps when setting or
    106 // using these pointers:
    107 //
    108 // * "Non-null" pointers should never be null. It is the responsibility of the
    109 //   provider of this pointer to ensure that the pointer may never be set to
    110 //   null. Consumers of such pointers can treat such pointers as non-null.
    111 // * "Nullable" pointers may or may not be null. Consumers of such pointers
    112 //   should precede any usage of that pointer (e.g. a dereference operation)
    113 //   with a a `nullptr` check.
    114 // * "Unknown" pointers may be either "non-null" or "nullable" but have not been
    115 //   definitively determined to be in either classification state. Providers of
    116 //   such pointers across API boundaries should determine --  over time -- to
    117 //   annotate the pointer in either of the above two states. Consumers of such
    118 //   pointers across an API boundary should continue to treat such pointers as
    119 //   they currently do.
    120 //
    121 // Example:
    122 //
    123 // // PaySalary() requires the passed pointer to an `Employee` to be non-null.
    124 // void PaySalary(Employee* absl_nonnull e) {
    125 //   pay(e->salary);  // OK to dereference
    126 // }
    127 //
    128 // // CompleteTransaction() guarantees the returned pointer to an `Account` to
    129 // // be non-null.
    130 // Account* absl_nonnull balance CompleteTransaction(double fee) {
    131 // ...
    132 // }
    133 //
    134 // // Note that specifying a nullability annotation does not prevent someone
    135 // // from violating the contract:
    136 //
    137 // Employee* absl_nullable find(Map& employees, std::string_view name);
    138 //
    139 // void g(Map& employees) {
    140 //   Employee *e = find(employees, "Pat");
    141 //   // `e` can now be null.
    142 //   PaySalary(e); // Violates contract, but compiles!
    143 // }
    144 //
    145 // Nullability annotations, in other words, are useful for defining and
    146 // narrowing contracts; *enforcement* of those contracts depends on use and any
    147 // additional (static or dynamic analysis) tooling.
    148 //
    149 // NOTE: The "unknown" annotation state indicates that a pointer's contract has
    150 // not yet been positively identified. The unknown state therefore acts as a
    151 // form of documentation of your technical debt, and a codebase that adopts
    152 // nullability annotations should aspire to annotate every pointer as either
    153 // "non-null" or "nullable".
    154 //
    155 // -----------------------------------------------------------------------------
    156 // Applicability of Nullability Annotations
    157 // -----------------------------------------------------------------------------
    158 //
    159 // By default, nullability annotations are applicable to raw and smart
    160 // pointers. User-defined types can indicate compatibility with nullability
    161 // annotations by adding the ABSL_NULLABILITY_COMPATIBLE attribute.
    162 //
    163 // // Example:
    164 // struct ABSL_NULLABILITY_COMPATIBLE MyPtr {
    165 //   ...
    166 // };
    167 //
    168 // Note: Compilers that don't support the `nullability_on_classes` feature will
    169 // allow nullability annotations to be applied to any type, not just ones
    170 // marked with `ABSL_NULLABILITY_COMPATIBLE`.
    171 //
    172 // DISCLAIMER:
    173 // ===========================================================================
    174 // These nullability annotations are primarily a human readable signal about the
    175 // intended contract of the pointer. They are not *types* and do not currently
    176 // provide any correctness guarantees. For example, a pointer annotated as
    177 // `absl_nonnull` is *not guaranteed* to be non-null, and the compiler won't
    178 // alert or prevent assignment of a `T* absl_nullable` to a `T* absl_nonnull`.
    179 // ===========================================================================
    180 #ifndef ABSL_BASE_NULLABILITY_H_
    181 #define ABSL_BASE_NULLABILITY_H_
    182 
    183 #include "absl/base/config.h"
    184 #include "absl/base/internal/nullability_impl.h"
    185 
    186 // ABSL_POINTERS_DEFAULT_NONNULL
    187 //
    188 // This macro specifies that all unannotated pointer types within the given
    189 // file are designated as nonnull (instead of the default "unknown"). This macro
    190 // exists as a standalone statement and applies default nonnull behavior to all
    191 // subsequent pointers; as a result, place this macro as the first non-comment,
    192 // non-`#include` line in a file.
    193 //
    194 // Example:
    195 //
    196 //     #include "absl/base/nullability.h"
    197 //
    198 //     ABSL_POINTERS_DEFAULT_NONNULL
    199 //
    200 //     void FillMessage(Message *m);                  // implicitly non-null
    201 //     T* absl_nullable GetNullablePtr();           // explicitly nullable
    202 //     T* absl_nullability_unknown GetUnknownPtr();  // explicitly unknown
    203 //
    204 // The macro can be safely used in header files – it will not affect any files
    205 // that include it.
    206 //
    207 // In files with the macro, plain `T*` syntax means `T* absl_nonnull`, and the
    208 // exceptions (`absl_nullable` and `absl_nullability_unknown`) must be marked
    209 // explicitly. The same holds, correspondingly, for smart pointer types.
    210 //
    211 // For comparison, without the macro, all unannotated pointers would default to
    212 // unknown, and otherwise require explicit annotations to change this behavior:
    213 //
    214 //     #include "absl/base/nullability.h"
    215 //
    216 //     void FillMessage(Message* absl_nonnull m);  // explicitly non-null
    217 //     T* absl_nullable GetNullablePtr();          // explicitly nullable
    218 //     T* GetUnknownPtr();                           // implicitly unknown
    219 //
    220 // No-op except for being a human readable signal.
    221 #define ABSL_POINTERS_DEFAULT_NONNULL
    222 
    223 #if defined(__clang__) && !defined(__OBJC__) && \
    224    ABSL_HAVE_FEATURE(nullability_on_classes) && \
    225    0 // mozilla - stop warnings in libwebrtc for "missing a nullability type specifier"
    226 // absl_nonnull (default with `ABSL_POINTERS_DEFAULT_NONNULL`)
    227 //
    228 // The indicated pointer is never null. It is the responsibility of the provider
    229 // of this pointer across an API boundary to ensure that the pointer is never
    230 // set to null. Consumers of this pointer across an API boundary may safely
    231 // dereference the pointer.
    232 //
    233 // Example:
    234 //
    235 // // `employee` is designated as not null.
    236 // void PaySalary(Employee* absl_nonnull employee) {
    237 //   pay(*employee);  // OK to dereference
    238 // }
    239 #define absl_nonnull _Nonnull
    240 
    241 // absl_nullable
    242 //
    243 // The indicated pointer may, by design, be either null or non-null. Consumers
    244 // of this pointer across an API boundary should perform a `nullptr` check
    245 // before performing any operation using the pointer.
    246 //
    247 // Example:
    248 //
    249 // // `employee` may  be null.
    250 // void PaySalary(Employee* absl_nullable employee) {
    251 //   if (employee != nullptr) {
    252 //     Pay(*employee);  // OK to dereference
    253 //   }
    254 // }
    255 #define absl_nullable _Nullable
    256 
    257 // absl_nullability_unknown  (default without `ABSL_POINTERS_DEFAULT_NONNULL`)
    258 //
    259 // The indicated pointer has not yet been determined to be definitively
    260 // "non-null" or "nullable." Providers of such pointers across API boundaries
    261 // should, over time, annotate such pointers as either "non-null" or "nullable."
    262 // Consumers of these pointers across an API boundary should treat such pointers
    263 // with the same caution they treat currently unannotated pointers. Most
    264 // existing code will have "unknown"  pointers, which should eventually be
    265 // migrated into one of the above two nullability states: `absl_nonnull` or
    266 //  `absl_nullable`.
    267 //
    268 // NOTE: For files that do not specify `ABSL_POINTERS_DEFAULT_NONNULL`,
    269 // because this annotation is the global default state, unannotated pointers are
    270 // are assumed to have "unknown" semantics. This assumption is designed to
    271 // minimize churn and reduce clutter within the codebase.
    272 //
    273 // Example:
    274 //
    275 // // `employee`s nullability state is unknown.
    276 // void PaySalary(Employee* absl_nullability_unknown employee) {
    277 //   Pay(*employee); // Potentially dangerous. API provider should investigate.
    278 // }
    279 //
    280 // Note that a pointer without an annotation, by default, is assumed to have the
    281 // annotation `NullabilityUnknown`.
    282 //
    283 // // `employee`s nullability state is unknown.
    284 // void PaySalary(Employee* employee) {
    285 //   Pay(*employee); // Potentially dangerous. API provider should investigate.
    286 // }
    287 #define absl_nullability_unknown _Null_unspecified
    288 #else
    289 // No-op for non-Clang compilers or Objective-C.
    290 #define absl_nonnull
    291 // No-op for non-Clang compilers or Objective-C.
    292 #define absl_nullable
    293 // No-op for non-Clang compilers or Objective-C.
    294 #define absl_nullability_unknown
    295 #endif
    296 
    297 // ABSL_NULLABILITY_COMPATIBLE
    298 //
    299 // Indicates that a class is compatible with nullability annotations.
    300 //
    301 // For example:
    302 //
    303 // struct ABSL_NULLABILITY_COMPATIBLE MyPtr {
    304 //   ...
    305 // };
    306 //
    307 // Note: Compilers that don't support the `nullability_on_classes` feature will
    308 // allow nullability annotations to be applied to any type, not just ones marked
    309 // with `ABSL_NULLABILITY_COMPATIBLE`.
    310 #if ABSL_HAVE_FEATURE(nullability_on_classes)
    311 #define ABSL_NULLABILITY_COMPATIBLE _Nullable
    312 #else
    313 #define ABSL_NULLABILITY_COMPATIBLE
    314 #endif
    315 
    316 namespace absl {
    317 ABSL_NAMESPACE_BEGIN
    318 
    319 // The following template aliases are alternate forms of the macro annotations
    320 // above. They have some limitations, for example, an incompatibility with
    321 // `auto*` pointers, as `auto` cannot be used in a template argument.
    322 //
    323 // It is important to note that these annotations are not distinct strong
    324 // *types*. They are alias templates defined to be equal to the underlying
    325 // pointer type. A pointer annotated `Nonnull<T*>`, for example, is simply a
    326 // pointer of type `T*`.
    327 
    328 // absl::Nonnull, analogous to absl_nonnull
    329 //
    330 // Example:
    331 // absl::Nonnull<int*> foo;
    332 // Is equivalent to:
    333 // int* absl_nonnull foo;
    334 template <typename T>
    335 using Nonnull = nullability_internal::NonnullImpl<T>;
    336 
    337 // absl::Nullable, analogous to absl_nullable
    338 //
    339 // Example:
    340 // absl::Nullable<int*> foo;
    341 // Is equivalent to:
    342 // int* absl_nullable foo;
    343 template <typename T>
    344 using Nullable = nullability_internal::NullableImpl<T>;
    345 
    346 // absl::NullabilityUnknown, analogous to absl_nullability_unknown
    347 //
    348 // Example:
    349 // absl::NullabilityUnknown<int*> foo;
    350 // Is equivalent to:
    351 // int* absl_nullability_unknown foo;
    352 template <typename T>
    353 using NullabilityUnknown = nullability_internal::NullabilityUnknownImpl<T>;
    354 
    355 ABSL_NAMESPACE_END
    356 }  // namespace absl
    357 
    358 #endif  // ABSL_BASE_NULLABILITY_H_