aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkmekhovich <kmekhovich@yandex-team.com>2024-06-07 10:37:24 +0300
committerkmekhovich <kmekhovich@yandex-team.com>2024-06-07 10:50:16 +0300
commitaeb63e173f199ef0c8dccc4a81d545881d072506 (patch)
treee8f1792d420cb3cb71b2fea3e4ea404ddff1cb5f
parenta7b5aef2daa5510cf5dd2766cb49be4e389b2945 (diff)
downloadydb-aeb63e173f199ef0c8dccc4a81d545881d072506.tar.gz
YT: Fix UB in const auto& x = WaitFor(..).ValueOrThrow()
previous version lead to UB https://godbolt.org/z/vEohf9aG3 8e9cbd9115bf6eaeff554aff381dab130a24332d
-rw-r--r--yt/yt/core/misc/error-inl.h16
-rw-r--r--yt/yt/core/misc/error.h17
2 files changed, 17 insertions, 16 deletions
diff --git a/yt/yt/core/misc/error-inl.h b/yt/yt/core/misc/error-inl.h
index 8585ee8890..d147a3dd9a 100644
--- a/yt/yt/core/misc/error-inl.h
+++ b/yt/yt/core/misc/error-inl.h
@@ -231,7 +231,7 @@ TErrorOr<T>& TErrorOr<T>::operator = (TErrorOr<T>&& other) noexcept
template <class T>
template <class... TArgs>
-T&& TErrorOr<T>::ValueOrThrow(TArgs&&... args) &&
+T&& TErrorOr<T>::ValueOrThrow(TArgs&&... args) && Y_LIFETIME_BOUND
{
if (!IsOK()) {
THROW_ERROR std::move(*this).Wrap(std::forward<TArgs>(args)...);
@@ -241,7 +241,7 @@ T&& TErrorOr<T>::ValueOrThrow(TArgs&&... args) &&
template <class T>
template <class... TArgs>
-T& TErrorOr<T>::ValueOrThrow(TArgs&&... args) &
+T& TErrorOr<T>::ValueOrThrow(TArgs&&... args) & Y_LIFETIME_BOUND
{
if (!IsOK()) {
THROW_ERROR Wrap(std::forward<TArgs>(args)...);
@@ -251,7 +251,7 @@ T& TErrorOr<T>::ValueOrThrow(TArgs&&... args) &
template <class T>
template <class... TArgs>
-const T& TErrorOr<T>::ValueOrThrow(TArgs&&... args) const &
+const T& TErrorOr<T>::ValueOrThrow(TArgs&&... args) const & Y_LIFETIME_BOUND
{
if (!IsOK()) {
THROW_ERROR Wrap(std::forward<TArgs>(args)...);
@@ -260,34 +260,34 @@ const T& TErrorOr<T>::ValueOrThrow(TArgs&&... args) const &
}
template <class T>
-T&& TErrorOr<T>::Value() &&
+T&& TErrorOr<T>::Value() && Y_LIFETIME_BOUND
{
YT_ASSERT(IsOK());
return std::move(*Value_);
}
template <class T>
-T& TErrorOr<T>::Value() &
+T& TErrorOr<T>::Value() & Y_LIFETIME_BOUND
{
YT_ASSERT(IsOK());
return *Value_;
}
template <class T>
-const T& TErrorOr<T>::Value() const &
+const T& TErrorOr<T>::Value() const & Y_LIFETIME_BOUND
{
YT_ASSERT(IsOK());
return *Value_;
}
template <class T>
-const T& TErrorOr<T>::ValueOrDefault(const T& defaultValue) const &
+const T& TErrorOr<T>::ValueOrDefault(const T& defaultValue Y_LIFETIME_BOUND) const & Y_LIFETIME_BOUND
{
return IsOK() ? *Value_ : defaultValue;
}
template <class T>
-T& TErrorOr<T>::ValueOrDefault(T& defaultValue) &
+T& TErrorOr<T>::ValueOrDefault(T& defaultValue Y_LIFETIME_BOUND) & Y_LIFETIME_BOUND
{
return IsOK() ? *Value_ : defaultValue;
}
diff --git a/yt/yt/core/misc/error.h b/yt/yt/core/misc/error.h
index 8e60e5de5d..8d69a120ac 100644
--- a/yt/yt/core/misc/error.h
+++ b/yt/yt/core/misc/error.h
@@ -19,6 +19,7 @@
#include <library/cpp/yt/misc/property.h>
+#include <util/system/compiler.h>
#include <util/system/getpid.h>
#include <util/generic/size_literals.h>
@@ -402,21 +403,21 @@ public:
TErrorOr<T>& operator = (TErrorOr<T>&& other) noexcept
requires std::is_nothrow_move_assignable_v<T>;
- const T& Value() const &;
- T& Value() &;
- T&& Value() &&;
+ const T& Value() const & Y_LIFETIME_BOUND;
+ T& Value() & Y_LIFETIME_BOUND;
+ T&& Value() && Y_LIFETIME_BOUND;
template <class... TArgs>
- const T& ValueOrThrow(TArgs&&... args) const &;
+ const T& ValueOrThrow(TArgs&&... args) const & Y_LIFETIME_BOUND;
template <class... TArgs>
- T& ValueOrThrow(TArgs&&... args) &;
+ T& ValueOrThrow(TArgs&&... args) & Y_LIFETIME_BOUND;
template <class... TArgs>
- T&& ValueOrThrow(TArgs&&... args) &&;
+ T&& ValueOrThrow(TArgs&&... args) && Y_LIFETIME_BOUND;
- const T& ValueOrDefault(const T& defaultValue) const &;
- T& ValueOrDefault(T& defaultValue) &;
+ const T& ValueOrDefault(const T& defaultValue Y_LIFETIME_BOUND) const & Y_LIFETIME_BOUND;
+ T& ValueOrDefault(T& defaultValue Y_LIFETIME_BOUND) & Y_LIFETIME_BOUND;
constexpr T ValueOrDefault(T&& defaultValue) const &;
constexpr T ValueOrDefault(T&& defaultValue) &&;