aboutsummaryrefslogtreecommitdiff
path: root/clang-tools-extra
diff options
context:
space:
mode:
authorAnton Dukeman <antondukeman@fb.com>2023-07-24 19:14:35 +0000
committerPiotr Zegar <me@piotrzegar.pl>2023-07-24 19:42:19 +0000
commit2f0630f8bc91e81fd5948e82164cf82ae595caf2 (patch)
treed1927b9a4a91c3a10d5f9094f05e52490edb631c /clang-tools-extra
parenta6cd1f623dcf6fc443a1b1726d77b36c6b0caa83 (diff)
downloadllvm-2f0630f8bc91e81fd5948e82164cf82ae595caf2.zip
llvm-2f0630f8bc91e81fd5948e82164cf82ae595caf2.tar.gz
llvm-2f0630f8bc91e81fd5948e82164cf82ae595caf2.tar.bz2
[clang-tidy] Add folly::Optional to unchecked-optional-access
The unchecked-optional-access check identifies attempted value unwrapping without checking if the value exists. These changes extend that support to checking folly::Optional. Reviewed By: gribozavr2 Differential Revision: https://reviews.llvm.org/D155890
Diffstat (limited to 'clang-tools-extra')
-rw-r--r--clang-tools-extra/docs/ReleaseNotes.rst2
-rw-r--r--clang-tools-extra/docs/clang-tidy/checks/bugprone/unchecked-optional-access.rst5
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/unchecked-optional-access/folly/types/Optional.h56
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-optional-access.cpp23
4 files changed, 83 insertions, 3 deletions
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index d7a525b..7c4d06b 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -319,7 +319,7 @@ Changes in existing checks
- Improved :doc:`bugprone-unchecked-optional-access
<clang-tidy/checks/bugprone/unchecked-optional-access>` check to properly handle calls
- to ``std::forward``.
+ to ``std::forward`` and support for ``folly::Optional`` were added.
- Extend :doc:`bugprone-unused-return-value
<clang-tidy/checks/bugprone/unused-return-value>` check to check for all functions
diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unchecked-optional-access.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unchecked-optional-access.rst
index 4736518..5a6aaa0 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unchecked-optional-access.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unchecked-optional-access.rst
@@ -8,8 +8,9 @@ results. Therefore, it may be more resource intensive (RAM, CPU) than the
average clang-tidy check.
This check identifies unsafe accesses to values contained in
-``std::optional<T>``, ``absl::optional<T>``, or ``base::Optional<T>``
-objects. Below we will refer to all these types collectively as ``optional<T>``.
+``std::optional<T>``, ``absl::optional<T>``, ``base::Optional<T>``, or
+``folly::Optional<T>`` objects. Below we will refer to all these types
+collectively as ``optional<T>``.
An access to the value of an ``optional<T>`` occurs when one of its ``value``,
``operator*``, or ``operator->`` member functions is invoked. To align with
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/unchecked-optional-access/folly/types/Optional.h b/clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/unchecked-optional-access/folly/types/Optional.h
new file mode 100644
index 0000000..818b066
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/unchecked-optional-access/folly/types/Optional.h
@@ -0,0 +1,56 @@
+#ifndef LLVM_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_BUGPRONE_INPUTS_UNCHECKED_OPTIONAL_ACCESS_FOLLY_TYPES_OPTIONAL_H_
+#define LLVM_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_BUGPRONE_INPUTS_UNCHECKED_OPTIONAL_ACCESS_FOLLY_TYPES_OPTIONAL_H_
+
+/// Mock of `folly::Optional`.
+namespace folly {
+
+struct None {
+ constexpr explicit None() {}
+};
+
+constexpr None none;
+
+template <typename T>
+class Optional {
+public:
+ constexpr Optional() noexcept;
+
+ constexpr Optional(None) noexcept;
+
+ Optional(const Optional &) = default;
+
+ Optional(Optional &&) = default;
+
+ const T &operator*() const &;
+ T &operator*() &;
+ const T &&operator*() const &&;
+ T &&operator*() &&;
+
+ const T *operator->() const;
+ T *operator->();
+
+ const T &value() const &;
+ T &value() &;
+ const T &&value() const &&;
+ T &&value() &&;
+
+ constexpr explicit operator bool() const noexcept;
+ constexpr bool has_value() const noexcept;
+ constexpr bool hasValue() const noexcept;
+
+ template <typename U>
+ constexpr T value_or(U &&v) const &;
+ template <typename U>
+ T value_or(U &&v) &&;
+
+ template <typename... Args>
+ T &emplace(Args &&...args);
+
+ void reset() noexcept;
+
+ void swap(Optional &rhs) noexcept;
+};
+
+} // namespace folly
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_BUGPRONE_INPUTS_UNCHECKED_OPTIONAL_ACCESS_FOLLY_TYPES_OPTIONAL_H_
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-optional-access.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-optional-access.cpp
index c1e731f..1921291 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-optional-access.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-optional-access.cpp
@@ -1,6 +1,7 @@
// RUN: %check_clang_tidy %s bugprone-unchecked-optional-access %t -- -- -I %S/Inputs/unchecked-optional-access
#include "absl/types/optional.h"
+#include "folly/types/Optional.h"
void unchecked_value_access(const absl::optional<int> &opt) {
opt.value();
@@ -21,12 +22,34 @@ void unchecked_arrow_operator_access(const absl::optional<Foo> &opt) {
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: unchecked access to optional value
}
+void folly_check_value_then_reset(folly::Optional<int> opt) {
+ if (opt) {
+ opt.reset();
+ opt.value();
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: unchecked access to optional value
+ }
+}
+
+void folly_value_after_swap(folly::Optional<int> opt1, folly::Optional<int> opt2) {
+ if (opt1) {
+ opt1.swap(opt2);
+ opt1.value();
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: unchecked access to optional value
+ }
+}
+
void checked_access(const absl::optional<int> &opt) {
if (opt.has_value()) {
opt.value();
}
}
+void folly_checked_access(const folly::Optional<int> &opt) {
+ if (opt.hasValue()) {
+ opt.value();
+ }
+}
+
template <typename T>
void function_template_without_user(const absl::optional<T> &opt) {
opt.value(); // no-warning