[libcxx-commits] [libcxx] [libc++] Crash when dereferencing an empty std::optional (PR #116394)
via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Nov 15 22:28:23 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Andrej Shadura (andrewshadura)
<details>
<summary>Changes</summary>
Dereferencing a std::optional that does not contain a value is undefined behaviour. It is better to crash when this happens to prevent potential abuse or a crash further down the line.
[reworded the commit message]
Co-Authored-By: Andrej Shadura <andrew.shadura@<!-- -->collabora.co.uk>
---
Full diff: https://github.com/llvm/llvm-project/pull/116394.diff
1 Files Affected:
- (modified) libcxx/include/optional (+32-6)
``````````diff
diff --git a/libcxx/include/optional b/libcxx/include/optional
index 7ad6a9e116941f..71c0eabed446dc 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -177,6 +177,8 @@ namespace std {
*/
+#include <stdio.h>
+
#include <__assert>
#include <__compare/compare_three_way_result.h>
#include <__compare/ordering.h>
@@ -791,33 +793,57 @@ public:
}
}
- _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type const> operator->() const noexcept {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr add_pointer_t<value_type const> operator->() const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
+ if (!this->has_value()) {
+ fprintf(stderr, "optional operator-> called on a disengaged value\n");
+ __builtin_trap();
+ }
return std::addressof(this->__get());
}
- _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type> operator->() noexcept {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr add_pointer_t<value_type> operator->() noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
+ if (!this->has_value()) {
+ fprintf(stderr, "optional operator-> called on a disengaged value\n");
+ __builtin_trap();
+ }
return std::addressof(this->__get());
}
- _LIBCPP_HIDE_FROM_ABI constexpr const value_type& operator*() const& noexcept {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr const value_type& operator*() const& noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
+ if (!this->has_value()) {
+ fprintf(stderr, "optional operator-> called on a disengaged value\n");
+ __builtin_trap();
+ }
return this->__get();
}
- _LIBCPP_HIDE_FROM_ABI constexpr value_type& operator*() & noexcept {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type& operator*() & noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
+ if (!this->has_value()) {
+ fprintf(stderr, "optional operator-> called on a disengaged value\n");
+ __builtin_trap();
+ }
return this->__get();
}
- _LIBCPP_HIDE_FROM_ABI constexpr value_type&& operator*() && noexcept {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type&& operator*() && noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
+ if (!this->has_value()) {
+ fprintf(stderr, "optional operator-> called on a disengaged value\n");
+ __builtin_trap();
+ }
return std::move(this->__get());
}
- _LIBCPP_HIDE_FROM_ABI constexpr const value_type&& operator*() const&& noexcept {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr const value_type&& operator*() const&& noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
+ if (!this->has_value()) {
+ fprintf(stderr, "optional operator-> called on a disengaged value\n");
+ __builtin_trap();
+ }
return std::move(this->__get());
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/116394
More information about the libcxx-commits
mailing list