brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.9 KiB · 8d70a9d Raw
319 lines · cpp
1// RUN: %check_clang_tidy %s bugprone-unchecked-optional-access %t -- -- -I %S/Inputs/unchecked-optional-access2 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 value16}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 value25}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 value32  }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 value40  }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 value84  }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 value141  }142}143 144void nullable_value_make_value(BloombergLP::bdlb::NullableValue<int> &opt1, BloombergLP::bdlb::NullableValue<int> &opt2) {145  if (opt1.isNull()) {146    opt1.makeValue(42);147  }148 149  opt1.value();150 151  if (opt2.isNull()) {152    opt2.makeValueInplace(42);153  }154 155  opt2.value();156}157 158void assertion_handler() __attribute__((analyzer_noreturn));159 160void function_calling_analyzer_noreturn(const bsl::optional<int>& opt)161{162  if (!opt) {163      assertion_handler();164  }165 166  *opt; // no-warning: The previous condition guards this dereference.167}168 169template <typename T>170void function_template_without_user(const absl::optional<T> &opt) {171  opt.value(); // no-warning172}173 174template <typename T>175void function_template_with_user(const absl::optional<T> &opt) {176  opt.value();177  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value178}179 180void function_template_user(const absl::optional<int> &opt) {181  // Instantiate the f3 function template so that it gets matched by the check.182  function_template_with_user(opt);183}184 185template <typename T>186void function_template_with_specialization(const absl::optional<int> &opt) {187  opt.value(); // no-warning188}189 190template <>191void function_template_with_specialization<int>(192    const absl::optional<int> &opt) {193  opt.value();194  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value195}196 197template <typename T>198class ClassTemplateWithSpecializations {199  void f(const absl::optional<int> &opt) {200    opt.value(); // no-warning201  }202};203 204template <typename T>205class ClassTemplateWithSpecializations<T *> {206  void f(const absl::optional<int> &opt) {207    opt.value(); // no-warning208  }209};210 211template <>212class ClassTemplateWithSpecializations<int> {213  void f(const absl::optional<int> &opt) {214    opt.value();215    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: unchecked access to optional216  }217};218 219// The templates below are not instantiated and CFGs can not be properly built220// for them. They are here to make sure that the checker does not crash, but221// instead ignores non-instantiated templates.222 223template <typename T>224struct C1 {};225 226template <typename T>227struct C2 : public C1<T> {228  ~C2() {}229};230 231template <typename T, template <class> class B>232struct C3 : public B<T> {233  ~C3() {}234};235 236void multiple_unchecked_accesses(absl::optional<int> opt1,237                                 absl::optional<int> opt2) {238  for (int i = 0; i < 10; i++) {239    opt1.value();240    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: unchecked access to optional241  }242  opt2.value();243  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value244}245 246class C4 {247  explicit C4(absl::optional<int> opt) : foo_(opt.value()) {248    // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: unchecked access to optional249  }250  int foo_;251};252 253// llvm#59705254namespace std255{256  template <typename T>257  constexpr T&& forward(T& type) noexcept {258    return static_cast<T&&>(type);259  }260 261  template <typename T>262  constexpr T&& forward(T&& type) noexcept {263    return static_cast<T&&>(type);264  }265}266 267void std_forward_copy(absl::optional<int> opt) {268  std::forward<absl::optional<int>>(opt).value();269  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional270}271 272void std_forward_copy_safe(absl::optional<int> opt) {273  if (!opt) return;274 275  std::forward<absl::optional<int>>(opt).value();276}277 278void std_forward_copy(absl::optional<int>& opt) {279  std::forward<absl::optional<int>>(opt).value();280  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional281}282 283void std_forward_lvalue_ref_safe(absl::optional<int>& opt) {284  if (!opt) return;285 286  std::forward<absl::optional<int>>(opt).value();287}288 289void std_forward_copy(absl::optional<int>&& opt) {290  std::forward<absl::optional<int>>(opt).value();291  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional292}293 294void std_forward_rvalue_ref_safe(absl::optional<int>&& opt) {295  if (!opt) return;296 297  std::forward<absl::optional<int>>(opt).value();298}299 300namespace std {301 302template <typename T> class vector {303public:304  T &operator[](unsigned long index);305  bool empty();306};307 308} // namespace std309 310struct S {311  absl::optional<float> x;312};313std::vector<S> vec;314 315void foo() {316  if (!vec.empty())317    vec[0].x = 0;318}319