1// RUN: %check_clang_tidy %s bugprone-unchecked-optional-access %t -- -- -I %S/Inputs/unchecked-optional-access
2
3#include "absl/types/optional.h"
4#include "folly/types/Optional.h"
5#include "bde/types/bsl_optional.h"
6#include "bde/types/bdlb_nullablevalue.h"
7
8void unchecked_value_access(const absl::optional<int> &opt) {
9 opt.value();
10 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value [bugprone-unchecked-optional-access]
11}
12
13void unchecked_deref_operator_access(const absl::optional<int> &opt) {
14 *opt;
15 // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: unchecked access to optional value
16}
17
18struct Foo {
19 void foo() const {}
20};
21
22void unchecked_arrow_operator_access(const absl::optional<Foo> &opt) {
23 opt->foo();
24 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value
25}
26
27void folly_check_value_then_reset(folly::Optional<int> opt) {
28 if (opt) {
29 opt.reset();
30 opt.value();
31 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: unchecked access to optional value
32 }
33}
34
35void folly_value_after_swap(folly::Optional<int> opt1, folly::Optional<int> opt2) {
36 if (opt1) {
37 opt1.swap(opt2);
38 opt1.value();
39 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: unchecked access to optional value
40 }
41}
42
43void checked_access(const absl::optional<int> &opt) {
44 if (opt.has_value()) {
45 opt.value();
46 }
47}
48
49void folly_checked_access(const folly::Optional<int> &opt) {
50 if (opt.hasValue()) {
51 opt.value();
52 }
53}
54
55void bsl_optional_unchecked_value_access(const bsl::optional<int> &opt) {
56 opt.value();
57 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value [bugprone-unchecked-optional-access]
58
59 int x = *opt;
60 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: unchecked access to optional value [bugprone-unchecked-optional-access]
61
62 if (!opt) {
63 return;
64 }
65
66 opt.value();
67 x = *opt;
68}
69
70void bsl_optional_checked_access(const bsl::optional<int> &opt) {
71 if (opt.has_value()) {
72 opt.value();
73 }
74 if (opt) {
75 opt.value();
76 }
77}
78
79void bsl_optional_value_after_swap(bsl::optional<int> &opt1, bsl::optional<int> &opt2) {
80 if (opt1) {
81 opt1.swap(opt2);
82 opt1.value();
83 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: unchecked access to optional value
84 }
85}
86
87void nullable_value_unchecked_value_access(const BloombergLP::bdlb::NullableValue<int> &opt) {
88 opt.value();
89 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value [bugprone-unchecked-optional-access]
90
91 int x = *opt;
92 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: unchecked access to optional value [bugprone-unchecked-optional-access]
93
94 if (opt.isNull()) {
95 opt.value();
96 }
97 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: unchecked access to optional value [bugprone-unchecked-optional-access]
98
99 if (!opt) {
100 opt.value();
101 }
102 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: unchecked access to optional value [bugprone-unchecked-optional-access]
103
104 if (!opt) {
105 return;
106 }
107
108 opt.value();
109 x = *opt;
110}
111
112void nullable_value_optional_checked_access(const BloombergLP::bdlb::NullableValue<int> &opt) {
113 if (opt.has_value()) {
114 opt.value();
115 }
116 if (opt) {
117 opt.value();
118 }
119 if (!opt.isNull()) {
120 opt.value();
121 }
122}
123
124void nullable_value_emplaced(BloombergLP::bdlb::NullableValue<int> &opt) {
125 opt.value();
126 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value [bugprone-unchecked-optional-access]
127
128 opt.emplace(1);
129 opt.value();
130
131 opt.reset();
132 opt.value();
133 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value [bugprone-unchecked-optional-access]
134}
135
136void nullable_value_after_swap(BloombergLP::bdlb::NullableValue<int> &opt1, BloombergLP::bdlb::NullableValue<int> &opt2) {
137 if (opt1) {
138 opt1.swap(opt2);
139 opt1.value();
140 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: unchecked access to optional value
141 }
142}
143
144template <typename T>
145void function_template_without_user(const absl::optional<T> &opt) {
146 opt.value(); // no-warning
147}
148
149template <typename T>
150void function_template_with_user(const absl::optional<T> &opt) {
151 opt.value();
152 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value
153}
154
155void function_template_user(const absl::optional<int> &opt) {
156 // Instantiate the f3 function template so that it gets matched by the check.
157 function_template_with_user(opt);
158}
159
160template <typename T>
161void function_template_with_specialization(const absl::optional<int> &opt) {
162 opt.value(); // no-warning
163}
164
165template <>
166void function_template_with_specialization<int>(
167 const absl::optional<int> &opt) {
168 opt.value();
169 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value
170}
171
172template <typename T>
173class ClassTemplateWithSpecializations {
174 void f(const absl::optional<int> &opt) {
175 opt.value(); // no-warning
176 }
177};
178
179template <typename T>
180class ClassTemplateWithSpecializations<T *> {
181 void f(const absl::optional<int> &opt) {
182 opt.value(); // no-warning
183 }
184};
185
186template <>
187class ClassTemplateWithSpecializations<int> {
188 void f(const absl::optional<int> &opt) {
189 opt.value();
190 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: unchecked access to optional
191 }
192};
193
194// The templates below are not instantiated and CFGs can not be properly built
195// for them. They are here to make sure that the checker does not crash, but
196// instead ignores non-instantiated templates.
197
198template <typename T>
199struct C1 {};
200
201template <typename T>
202struct C2 : public C1<T> {
203 ~C2() {}
204};
205
206template <typename T, template <class> class B>
207struct C3 : public B<T> {
208 ~C3() {}
209};
210
211void multiple_unchecked_accesses(absl::optional<int> opt1,
212 absl::optional<int> opt2) {
213 for (int i = 0; i < 10; i++) {
214 opt1.value();
215 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: unchecked access to optional
216 }
217 opt2.value();
218 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value
219}
220
221class C4 {
222 explicit C4(absl::optional<int> opt) : foo_(opt.value()) {
223 // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: unchecked access to optional
224 }
225 int foo_;
226};
227
228// llvm#59705
229namespace std
230{
231 template <typename T>
232 constexpr T&& forward(T& type) noexcept {
233 return static_cast<T&&>(type);
234 }
235
236 template <typename T>
237 constexpr T&& forward(T&& type) noexcept {
238 return static_cast<T&&>(type);
239 }
240}
241
242void std_forward_copy(absl::optional<int> opt) {
243 std::forward<absl::optional<int>>(opt).value();
244 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional
245}
246
247void std_forward_copy_safe(absl::optional<int> opt) {
248 if (!opt) return;
249
250 std::forward<absl::optional<int>>(opt).value();
251}
252
253void std_forward_copy(absl::optional<int>& opt) {
254 std::forward<absl::optional<int>>(opt).value();
255 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional
256}
257
258void std_forward_lvalue_ref_safe(absl::optional<int>& opt) {
259 if (!opt) return;
260
261 std::forward<absl::optional<int>>(opt).value();
262}
263
264void std_forward_copy(absl::optional<int>&& opt) {
265 std::forward<absl::optional<int>>(opt).value();
266 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional
267}
268
269void std_forward_rvalue_ref_safe(absl::optional<int>&& opt) {
270 if (!opt) return;
271
272 std::forward<absl::optional<int>>(opt).value();
273}
274
275namespace std {
276
277template <typename T> class vector {
278public:
279 T &operator[](unsigned long index);
280 bool empty();
281};
282
283} // namespace std
284
285struct S {
286 absl::optional<float> x;
287};
288std::vector<S> vec;
289
290void foo() {
291 if (!vec.empty())
292 vec[0].x = 0;
293}
294

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-optional-access.cpp