[llvm] e8ca306 - [ADT] Add a missing call to a unique_function destructor after move (#98747)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 19 12:38:10 PDT 2024
Author: Dmitry Yanovsky
Date: 2024-08-19T12:38:06-07:00
New Revision: e8ca306fbefdb8385c53d6cc029251d1d5be7049
URL: https://github.com/llvm/llvm-project/commit/e8ca306fbefdb8385c53d6cc029251d1d5be7049
DIFF: https://github.com/llvm/llvm-project/commit/e8ca306fbefdb8385c53d6cc029251d1d5be7049.diff
LOG: [ADT] Add a missing call to a unique_function destructor after move (#98747)
Right now immediately after moving the captured state, we 'disarm' the
moved-from object's destructor by resetting the
`RHS.CallbackAndInlineFlag`. This means that we never properly destroy
the RHS object's captured state.
Added:
Modified:
llvm/include/llvm/ADT/FunctionExtras.h
llvm/unittests/ADT/CountCopyAndMove.cpp
llvm/unittests/ADT/CountCopyAndMove.h
llvm/unittests/ADT/FunctionExtrasTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ADT/FunctionExtras.h b/llvm/include/llvm/ADT/FunctionExtras.h
index ad5c89cbc8bda7..d92868e3715f40 100644
--- a/llvm/include/llvm/ADT/FunctionExtras.h
+++ b/llvm/include/llvm/ADT/FunctionExtras.h
@@ -314,6 +314,7 @@ template <typename ReturnT, typename... ParamTs> class UniqueFunctionBase {
// Non-trivial move, so dispatch to a type-erased implementation.
getNonTrivialCallbacks()->MovePtr(getInlineStorage(),
RHS.getInlineStorage());
+ getNonTrivialCallbacks()->DestroyPtr(RHS.getInlineStorage());
}
// Clear the old callback and inline flag to get back to as-if-null.
diff --git a/llvm/unittests/ADT/CountCopyAndMove.cpp b/llvm/unittests/ADT/CountCopyAndMove.cpp
index fe1e2f4a5b89fd..022dbee40dc6f1 100644
--- a/llvm/unittests/ADT/CountCopyAndMove.cpp
+++ b/llvm/unittests/ADT/CountCopyAndMove.cpp
@@ -10,6 +10,8 @@
using namespace llvm;
+int CountCopyAndMove::DefaultConstructions = 0;
+int CountCopyAndMove::ValueConstructions = 0;
int CountCopyAndMove::CopyConstructions = 0;
int CountCopyAndMove::CopyAssignments = 0;
int CountCopyAndMove::MoveConstructions = 0;
diff --git a/llvm/unittests/ADT/CountCopyAndMove.h b/llvm/unittests/ADT/CountCopyAndMove.h
index 126054427b81a3..c91d34bd8ebb50 100644
--- a/llvm/unittests/ADT/CountCopyAndMove.h
+++ b/llvm/unittests/ADT/CountCopyAndMove.h
@@ -12,6 +12,8 @@
namespace llvm {
struct CountCopyAndMove {
+ static int DefaultConstructions;
+ static int ValueConstructions;
static int CopyConstructions;
static int CopyAssignments;
static int MoveConstructions;
@@ -19,8 +21,8 @@ struct CountCopyAndMove {
static int Destructions;
int val;
- CountCopyAndMove() = default;
- explicit CountCopyAndMove(int val) : val(val) {}
+ CountCopyAndMove() { ++DefaultConstructions; }
+ explicit CountCopyAndMove(int val) : val(val) { ++ValueConstructions; }
CountCopyAndMove(const CountCopyAndMove &other) : val(other.val) {
++CopyConstructions;
}
@@ -40,6 +42,8 @@ struct CountCopyAndMove {
~CountCopyAndMove() { ++Destructions; }
static void ResetCounts() {
+ DefaultConstructions = 0;
+ ValueConstructions = 0;
CopyConstructions = 0;
CopyAssignments = 0;
MoveConstructions = 0;
@@ -47,6 +51,11 @@ struct CountCopyAndMove {
Destructions = 0;
}
+ static int TotalConstructions() {
+ return DefaultConstructions + ValueConstructions + MoveConstructions +
+ CopyConstructions;
+ }
+
static int TotalCopies() { return CopyConstructions + CopyAssignments; }
static int TotalMoves() { return MoveConstructions + MoveAssignments; }
diff --git a/llvm/unittests/ADT/FunctionExtrasTest.cpp b/llvm/unittests/ADT/FunctionExtrasTest.cpp
index 7abdc8b77e0595..f64b888dbe1591 100644
--- a/llvm/unittests/ADT/FunctionExtrasTest.cpp
+++ b/llvm/unittests/ADT/FunctionExtrasTest.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/FunctionExtras.h"
+#include "CountCopyAndMove.h"
#include "gtest/gtest.h"
#include <memory>
@@ -329,4 +330,18 @@ TEST(UniqueFunctionTest, InlineStorageWorks) {
UniqueFunctionWithInlineStorage(&UniqueFunctionWithInlineStorage);
}
+// Check that the moved-from captured state is properly destroyed during
+// move construction/assignment.
+TEST(UniqueFunctionTest, MovedFromStateIsDestroyedCorrectly) {
+ CountCopyAndMove::ResetCounts();
+ {
+ unique_function<void()> CapturingFunction{
+ [Counter = CountCopyAndMove{}] {}};
+ unique_function<void()> CapturingFunctionMoved{
+ std::move(CapturingFunction)};
+ }
+ EXPECT_EQ(CountCopyAndMove::TotalConstructions(),
+ CountCopyAndMove::Destructions);
+}
+
} // anonymous namespace
More information about the llvm-commits
mailing list