1 // RUN: %check_clang_tidy %s bugprone-unchecked-optional-access %t -- \
2 // RUN:   -config="{CheckOptions:  \
3 // RUN:     {bugprone-unchecked-optional-access.IgnoreSmartPointerDereference: true}}" -- \
4 // RUN:   -I %S/Inputs/unchecked-optional-access
5 
6 #include "absl/types/optional.h"
7 
8 // Include some basic cases to ensure that IgnoreSmartPointerDereference doesn't
9 // disable everything. Then check the relevant smart-pointer cases.
10 
unchecked_deref_operator_access(const absl::optional<int> & opt)11 void unchecked_deref_operator_access(const absl::optional<int> &opt) {
12   *opt;
13   // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: unchecked access to optional value
14 }
15 
unchecked_value_access(const absl::optional<int> & opt)16 void unchecked_value_access(const absl::optional<int> &opt) {
17   opt.value();
18   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value [bugprone-unchecked-optional-access]
19 }
20 
21 struct Foo {
fooFoo22   void foo() const {}
23 };
24 
unchecked_arrow_operator_access(const absl::optional<Foo> & opt)25 void unchecked_arrow_operator_access(const absl::optional<Foo> &opt) {
26   opt->foo();
27   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value
28 }
29 
30 template <typename T>
31 struct SmartPtr {
32   T& operator*() &;
33   T* operator->();
34 };
35 
36 struct Bar {
37   absl::optional<int> opt;
38 };
39 
40 
unchecked_value_access_through_smart_ptr(SmartPtr<absl::optional<int>> s)41 void unchecked_value_access_through_smart_ptr(SmartPtr<absl::optional<int>> s) {
42   s->value();
43   (*s).value();
44 
45 }
46 
unchecked_value_access_through_smart_ptr_field(SmartPtr<Bar> s)47 void unchecked_value_access_through_smart_ptr_field(SmartPtr<Bar> s) {
48   s->opt.value();
49   (*s).opt.value();
50 
51 }
52