Skip to content

Commit 03e885a

Browse files
authored
Do not throw from ~AllocatedTensor (#30291)
### Details: - Do not throw from ~AllocatedTensor - fix coverity 1506561 ### Tickets: - CVS-165950
1 parent 7380190 commit 03e885a

File tree

3 files changed

+47
-12
lines changed

3 files changed

+47
-12
lines changed

src/core/include/openvino/runtime/allocator.hpp

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class OPENVINO_API Allocator {
4444
}
4545
virtual const std::type_info& type_info() const = 0;
4646
virtual void* allocate(const size_t bytes, const size_t alignment = alignof(max_align_t)) = 0;
47-
virtual void deallocate(void* handle, const size_t bytes, size_t alignment = alignof(max_align_t)) = 0;
47+
virtual void deallocate(void* handle, const size_t bytes, size_t alignment = alignof(max_align_t)) noexcept = 0;
4848
virtual bool is_equal(const Base& other) const = 0;
4949

5050
protected:
@@ -64,7 +64,7 @@ class OPENVINO_API Allocator {
6464
void* allocate(const size_t bytes, const size_t alignment = alignof(max_align_t)) override {
6565
return a.allocate(bytes, alignment);
6666
}
67-
void deallocate(void* handle, const size_t bytes, size_t alignment = alignof(max_align_t)) override {
67+
void deallocate(void* handle, const size_t bytes, size_t alignment = alignof(max_align_t)) noexcept override {
6868
a.deallocate(handle, bytes, alignment);
6969
}
7070
bool is_equal(const Base& other) const override {
@@ -76,6 +76,22 @@ class OPENVINO_API Allocator {
7676
A a;
7777
};
7878

79+
template <typename T, typename = void>
80+
struct HasNoexceptDeallocate : std::false_type {};
81+
82+
template <typename T>
83+
struct HasNoexceptDeallocate<
84+
T,
85+
std::void_t<decltype(std::declval<std::decay_t<T>>().deallocate(std::declval<void*>(),
86+
std::declval<const size_t>(),
87+
std::declval<const size_t>()))>>
88+
: std::bool_constant<noexcept(std::declval<std::decay_t<T>>().deallocate(std::declval<void*>(),
89+
std::declval<const size_t>(),
90+
std::declval<const size_t>()))> {};
91+
92+
template <typename T>
93+
static constexpr auto has_noexcept_deallocate_v = HasNoexceptDeallocate<T>::value;
94+
7995
std::shared_ptr<Base> _impl;
8096
std::shared_ptr<void> _so;
8197

@@ -113,11 +129,22 @@ class OPENVINO_API Allocator {
113129
*/
114130
template <
115131
typename A,
116-
typename std::enable_if<!std::is_same<typename std::decay<A>::type, Allocator>::value &&
117-
!std::is_abstract<typename std::decay<A>::type>::value &&
118-
!std::is_convertible<typename std::decay<A>::type, std::shared_ptr<Base>>::value,
119-
bool>::type = true>
120-
Allocator(A&& a) : _impl{std::make_shared<Impl<typename std::decay<A>::type>>(std::forward<A>(a))} {}
132+
typename std::enable_if_t<
133+
!std::is_same_v<typename std::decay_t<A>, Allocator> && !std::is_abstract_v<typename std::decay_t<A>> &&
134+
!std::is_convertible_v<typename std::decay_t<A>, std::shared_ptr<Base>> && has_noexcept_deallocate_v<A>,
135+
bool> = true>
136+
Allocator(A&& a) : _impl{std::make_shared<Impl<typename std::decay_t<A>>>(std::forward<A>(a))} {}
137+
138+
template <typename A,
139+
typename std::enable_if_t<!std::is_same_v<typename std::decay_t<A>, Allocator> &&
140+
!std::is_abstract_v<typename std::decay_t<A>> &&
141+
!std::is_convertible_v<typename std::decay_t<A>, std::shared_ptr<Base>> &&
142+
!has_noexcept_deallocate_v<A>,
143+
bool> = true>
144+
OPENVINO_DEPRECATED("Please annotate your allocator's deallocate method with noexcept. This method will be "
145+
"removed in 2026.0.0 release")
146+
Allocator(A&& a)
147+
: _impl{std::make_shared<Impl<typename std::decay_t<A>>>(std::forward<A>(a))} {}
121148

122149
/**
123150
* @brief Allocates memory
@@ -135,7 +162,7 @@ class OPENVINO_API Allocator {
135162
* @param bytes The size in bytes that was passed into allocate() method
136163
* @param alignment The alignment of storage that was passed into allocate() method
137164
*/
138-
void deallocate(void* ptr, const size_t bytes = 0, const size_t alignment = alignof(max_align_t));
165+
void deallocate(void* ptr, const size_t bytes = 0, const size_t alignment = alignof(max_align_t)) noexcept;
139166

140167
/**
141168
* @brief Compares with other Allocator

src/core/src/runtime/allocator.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ struct DefaultAllocator {
2828
}
2929
}
3030

31-
void deallocate(void* handle, const size_t bytes, const size_t alignment) {
31+
void deallocate(void* handle, const size_t bytes, const size_t alignment) noexcept {
3232
if (alignment == alignof(max_align_t)) {
3333
::operator delete(handle);
3434
} else {
@@ -67,11 +67,19 @@ Allocator::Allocator(const Allocator& other, const std::shared_ptr<void>& so) :
6767
OPENVINO_ASSERT(false, "Unexpected exception"); \
6868
}
6969

70+
#define OV_ALLOCATOR_NO_THROW_STATEMENT(...) \
71+
try { \
72+
if (_impl) { \
73+
__VA_ARGS__; \
74+
} \
75+
} catch (...) { \
76+
}
77+
7078
void* Allocator::allocate(const size_t bytes, const size_t alignment) {
7179
OV_ALLOCATOR_STATEMENT(return _impl->allocate(bytes, alignment));
7280
}
73-
void Allocator::deallocate(void* handle, const size_t bytes, const size_t alignment) {
74-
OV_ALLOCATOR_STATEMENT(_impl->deallocate(handle, bytes, alignment));
81+
void Allocator::deallocate(void* handle, const size_t bytes, const size_t alignment) noexcept {
82+
OV_ALLOCATOR_NO_THROW_STATEMENT(_impl->deallocate(handle, bytes, alignment));
7583
}
7684
bool Allocator::operator==(const Allocator& other) const {
7785
OV_ALLOCATOR_STATEMENT({

src/core/tests/ov_tensor_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ struct OVMockAllocator {
199199
return impl->allocate(b, a);
200200
}
201201

202-
void deallocate(void* ptr, size_t b, size_t a) {
202+
void deallocate(void* ptr, size_t b, size_t a) noexcept {
203203
impl->deallocate(ptr, b, a);
204204
}
205205
bool is_equal(const OVMockAllocator& other) const {

0 commit comments

Comments
 (0)