Skip to content

Commit ffc2512

Browse files
[SYCL] Add copy/move ctors and assignment operators to sycl::detail::optional (#19775)
Currently, those are implicitly defined and perform bitwise copy of Storage, that is incorrect if T has non-trivial copy ctors etc.
1 parent 967ed8e commit ffc2512

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

devops/compat_ci_exclude.sycl-rel-6_2

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,6 @@ AsyncAlloc/device/ooo_queue_async_alloc_from_pool.cpp
4949

5050
# Need more investigation by the author:
5151

52-
# https://github.com/intel/llvm/pull/18314
53-
Assert/assert_in_kernels.cpp
54-
Assert/assert_in_multiple_tus.cpp
55-
Assert/assert_in_multiple_tus_one_ndebug.cpp
56-
Assert/assert_in_one_kernel.cpp
57-
Assert/assert_in_simultaneous_kernels.cpp
58-
Assert/assert_in_simultaneously_multiple_tus.cpp
59-
Assert/assert_in_simultaneously_multiple_tus_one_ndebug.cpp
60-
6152
# https://github.com/intel/llvm/pull/18403 (pulldown, so probably offload-tools
6253
# team should be looking into this)
6354
DeviceImageDependencies/NewOffloadDriver/dynamic.cpp

sycl/include/sycl/detail/optional.hpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ template <typename T> class optional {
2222
public:
2323
constexpr optional() noexcept {}
2424
constexpr optional(std::nullopt_t) noexcept : optional() {}
25+
constexpr optional(const optional &Other)
26+
: ContainsValue{Other.ContainsValue} {
27+
if (Other.ContainsValue)
28+
new (Storage) T(Other.value());
29+
}
30+
constexpr optional(optional &&Other) : ContainsValue{Other.ContainsValue} {
31+
new (Storage) T(std::move(Other.value()));
32+
Other.ContainsValue = false;
33+
}
2534

2635
template <typename U>
2736
constexpr optional(const optional<U> &Other)
@@ -60,6 +69,21 @@ template <typename T> class optional {
6069
return *this;
6170
}
6271

72+
optional &operator=(const optional<T> &Other) {
73+
if (has_value())
74+
reinterpret_cast<T *>(Storage)->~T();
75+
ContainsValue = Other.has_value();
76+
new (Storage) T(Other.value());
77+
return *this;
78+
}
79+
optional &operator=(optional<T> &&Other) noexcept {
80+
if (has_value())
81+
reinterpret_cast<T *>(Storage)->~T();
82+
ContainsValue = Other.has_value();
83+
new (Storage) T(std::move(Other.value()));
84+
return *this;
85+
}
86+
6387
template <typename U> optional &operator=(const optional<U> &Other) {
6488
if (has_value())
6589
reinterpret_cast<T *>(Storage)->~T();

0 commit comments

Comments
 (0)