[JITLink][LoongArch] Support R_LARCH_ALIGN relaxation (#122259)
[llvm-project.git] / clang-tools-extra / docs / clang-tidy / checks / bugprone / unchecked-optional-access.rst
blob815b5cdeeebe241c7962645a7c718662d1ca547a
1 .. title:: clang-tidy - bugprone-unchecked-optional-access
3 bugprone-unchecked-optional-access
4 ==================================
6 *Note*: This check uses a flow-sensitive static analysis to produce its
7 results. Therefore, it may be more resource intensive (RAM, CPU) than the
8 average clang-tidy check.
10 This check identifies unsafe accesses to values contained in
11 ``std::optional<T>``, ``absl::optional<T>``, ``base::Optional<T>``,
12 ``folly::Optional<T>``, ``bsl::optional``, or
13 ``BloombergLP::bdlb::NullableValue`` objects. Below we will refer to all these
14 types collectively as ``optional<T>``.
16 An access to the value of an ``optional<T>`` occurs when one of its ``value``,
17 ``operator*``, or ``operator->`` member functions is invoked.  To align with
18 common misconceptions, the check considers these member functions as equivalent,
19 even though there are subtle differences related to exceptions versus undefined
20 behavior. See *Additional notes*, below, for more information on this topic.
22 An access to the value of an ``optional<T>`` is considered safe if and only if
23 code in the local scope (for example, a function body) ensures that the
24 ``optional<T>`` has a value in all possible execution paths that can reach the
25 access. That should happen either through an explicit check, using the
26 ``optional<T>::has_value`` member function, or by constructing the
27 ``optional<T>`` in a way that shows that it unambiguously holds a value (e.g
28 using ``std::make_optional`` which always returns a populated
29 ``std::optional<T>``).
31 Below we list some examples, starting with unsafe optional access patterns,
32 followed by safe access patterns.
34 Unsafe access patterns
35 ~~~~~~~~~~~~~~~~~~~~~~
37 Access the value without checking if it exists
38 ----------------------------------------------
40 The check flags accesses to the value that are not locally guarded by
41 existence check:
43 .. code-block:: c++
45    void f(std::optional<int> opt) {
46      use(*opt); // unsafe: it is unclear whether `opt` has a value.
47    }
49 Access the value in the wrong branch
50 ------------------------------------
52 The check is aware of the state of an optional object in different
53 branches of the code. For example:
55 .. code-block:: c++
57    void f(std::optional<int> opt) {
58      if (opt.has_value()) {
59      } else {
60        use(opt.value()); // unsafe: it is clear that `opt` does *not* have a value.
61      }
62    }
64 Assume a function result to be stable
65 -------------------------------------
67 The check is aware that function results might not be stable. That is,
68 consecutive calls to the same function might return different values.
69 For example:
71 .. code-block:: c++
73    void f(Foo foo) {
74      if (foo.opt().has_value()) {
75        use(*foo.opt()); // unsafe: it is unclear whether `foo.opt()` has a value.
76      }
77    }
79 Exception: accessor methods
80 ```````````````````````````
82 The check assumes *accessor* methods of a class are stable, with a heuristic to
83 determine which methods are accessors. Specifically, parameter-free ``const``
84 methods are treated as accessors. Note that this is not guaranteed to be safe
85 -- but, it is widely used (safely) in practice, and so we have chosen to treat
86 it as generally safe. Calls to non ``const`` methods are assumed to modify
87 the state of the object and affect the stability of earlier accessor calls.
89 Rely on invariants of uncommon APIs
90 -----------------------------------
92 The check is unaware of invariants of uncommon APIs. For example:
94 .. code-block:: c++
96    void f(Foo foo) {
97      if (foo.HasProperty("bar")) {
98        use(*foo.GetProperty("bar")); // unsafe: it is unclear whether `foo.GetProperty("bar")` has a value.
99      }
100    }
102 Check if a value exists, then pass the optional to another function
103 -------------------------------------------------------------------
105 The check relies on local reasoning. The check and value access must
106 both happen in the same function. An access is considered unsafe even if
107 the caller of the function performing the access ensures that the
108 optional has a value. For example:
110 .. code-block:: c++
112    void g(std::optional<int> opt) {
113      use(*opt); // unsafe: it is unclear whether `opt` has a value.
114    }
116    void f(std::optional<int> opt) {
117      if (opt.has_value()) {
118        g(opt);
119      }
120    }
122 Safe access patterns
123 ~~~~~~~~~~~~~~~~~~~~
125 Check if a value exists, then access the value
126 ----------------------------------------------
128 The check recognizes all straightforward ways for checking if a value
129 exists and accessing the value contained in an optional object. For
130 example:
132 .. code-block:: c++
134    void f(std::optional<int> opt) {
135      if (opt.has_value()) {
136        use(*opt);
137      }
138    }
141 Check if a value exists, then access the value from a copy
142 ----------------------------------------------------------
144 The criteria that the check uses is semantic, not syntactic. It
145 recognizes when a copy of the optional object being accessed is known to
146 have a value. For example:
148 .. code-block:: c++
150    void f(std::optional<int> opt1) {
151      if (opt1.has_value()) {
152        std::optional<int> opt2 = opt1;
153        use(*opt2);
154      }
155    }
158 Ensure that a value exists using common macros
159 ----------------------------------------------
161 The check is aware of common macros like ``CHECK`` and ``DCHECK``. Those can be
162 used to ensure that an optional object has a value. For example:
164 .. code-block:: c++
166    void f(std::optional<int> opt) {
167      DCHECK(opt.has_value());
168      use(*opt);
169    }
171 Ensure that a value exists, then access the value in a correlated branch
172 ------------------------------------------------------------------------
174 The check is aware of correlated branches in the code and can figure out
175 when an optional object is ensured to have a value on all execution
176 paths that lead to an access. For example:
178 .. code-block:: c++
180    void f(std::optional<int> opt) {
181      bool safe = false;
182      if (opt.has_value() && SomeOtherCondition()) {
183        safe = true;
184      }
185      // ... more code...
186      if (safe) {
187        use(*opt);
188      }
189    }
191 Stabilize function results
192 ~~~~~~~~~~~~~~~~~~~~~~~~~~
194 Since function results are not assumed to be stable across calls, it is best to
195 store the result of the function call in a local variable and use that variable
196 to access the value. For example:
198 .. code-block:: c++
200    void f(Foo foo) {
201      if (const auto& foo_opt = foo.opt(); foo_opt.has_value()) {
202        use(*foo_opt);
203      }
204    }
206 Do not rely on uncommon-API invariants
207 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
209 When uncommon APIs guarantee that an optional has contents, do not rely on it --
210 instead, check explicitly that the optional object has a value. For example:
212 .. code-block:: c++
214    void f(Foo foo) {
215      if (const auto& property = foo.GetProperty("bar")) {
216        use(*property);
217      }
218    }
220 instead of the `HasProperty`, `GetProperty` pairing we saw above.
222 Do not rely on caller-performed checks
223 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
225 If you know that all of a function's callers have checked that an optional
226 argument has a value, either change the function to take the value directly or
227 check the optional again in the local scope of the callee. For example:
229 .. code-block:: c++
231    void g(int val) {
232      use(val);
233    }
235    void f(std::optional<int> opt) {
236      if (opt.has_value()) {
237        g(*opt);
238      }
239    }
243 .. code-block:: c++
245    struct S {
246      std::optional<int> opt;
247      int x;
248    };
250    void g(const S &s) {
251      if (s.opt.has_value() && s.x > 10) {
252        use(*s.opt);
253    }
255    void f(S s) {
256      if (s.opt.has_value()) {
257        g(s);
258      }
259    }
261 Additional notes
262 ~~~~~~~~~~~~~~~~
264 Aliases created via ``using`` declarations
265 ------------------------------------------
267 The check is aware of aliases of optional types that are created via
268 ``using`` declarations. For example:
270 .. code-block:: c++
272    using OptionalInt = std::optional<int>;
274    void f(OptionalInt opt) {
275      use(opt.value()); // unsafe: it is unclear whether `opt` has a value.
276    }
278 Lambdas
279 -------
281 The check does not currently report unsafe optional accesses in lambdas.
282 A future version will expand the scope to lambdas, following the rules
283 outlined above. It is best to follow the same principles when using
284 optionals in lambdas.
286 Access with ``operator*()`` vs. ``value()``
287 -------------------------------------------
289 Given that ``value()`` has well-defined behavior (either throwing an exception
290 or terminating the program), why treat it the same as ``operator*()`` which
291 causes undefined behavior (UB)? That is, why is it considered unsafe to access
292 an optional with ``value()``, if it's not provably populated with a value?  For
293 that matter, why is ``CHECK()`` followed by ``operator*()`` any better than
294 ``value()``, given that they are semantically equivalent (on configurations that
295 disable exceptions)?
297 The answer is that we assume most users do not realize the difference between
298 ``value()`` and ``operator*()``. Shifting to ``operator*()`` and some form of
299 explicit value-presence check or explicit program termination has two
300 advantages:
302   * Readability. The check, and any potential side effects like program
303     shutdown, are very clear in the code. Separating access from checks can
304     actually make the checks more obvious.
306   * Performance. A single check can cover many or even all accesses within
307     scope. This gives the user the best of both worlds -- the safety of a
308     dynamic check, but without incurring redundant costs.