From 8fcf46ad75cb6b90adb3e3bb211fceaccca6e204 Mon Sep 17 00:00:00 2001 From: Nick Terrell <terrelln@fb.com> Date: Wed, 25 Mar 2020 17:21:33 -0700 Subject: [PATCH] Mark destroyItem() as noexcept Summary: F14Node{Map,Set} doesn't require `is_nothrow_destructible<value_type>`. `clear()` and the destructor are both marked `noexcept`, so they will both terminate if the destructor throws. But `erase()` is not marked `noexcept`, so when the destructor throws during `erase()` the value is left in the map. This could be problematic if the value is half destroyed, or if `eraseInto()` is used. This diff fixes the problem by marking `destroyItem()` as `noexcept`, so `std::terminate` is called whenever the value destructor throws. Reviewed By: nbronson Differential Revision: D20604276 fbshipit-source-id: c52c932d78d6ed61368985a749adf77c27a5a0de --- folly/container/detail/F14Policy.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/folly/container/detail/F14Policy.h b/folly/container/detail/F14Policy.h index 3763609e5..9c6b3bb8a 100644 --- a/folly/container/detail/F14Policy.h +++ b/folly/container/detail/F14Policy.h @@ -640,7 +640,7 @@ class ValueContainerPolicy : public BasePolicy< } } - void destroyItem(Item& item) { + void destroyItem(Item& item) noexcept { Alloc& a = this->alloc(); auto ptr = std::addressof(item); AllocTraits::destroy(a, ptr); @@ -876,7 +876,7 @@ class NodeContainerPolicy prefetchAddr(std::addressof(*item)); } - void destroyItem(Item& item) { + void destroyItem(Item& item) noexcept { if (item != nullptr) { Alloc& a = this->alloc(); AllocTraits::destroy(a, std::addressof(*item)); @@ -1252,7 +1252,7 @@ class VectorContainerPolicy : public BasePolicy< prefetchAddr(std::addressof(values_[item])); } - void destroyItem(Item&) {} + void destroyItem(Item&) noexcept {} template <typename T> std::enable_if_t<std::is_nothrow_move_constructible<T>::value> -- 2.26.2