diff --git a/orc-rt/include/orc-rt/move_only_function.h b/orc-rt/include/orc-rt/move_only_function.h index 9a483a4b405e..71c25d334efc 100644 --- a/orc-rt/include/orc-rt/move_only_function.h +++ b/orc-rt/include/orc-rt/move_only_function.h @@ -41,7 +41,9 @@ public: template class GenericCallableImpl : public GenericCallable { public: - GenericCallableImpl(CallableT &&Callable) : Callable(std::move(Callable)) {} + template + GenericCallableImpl(CallableInitT &&Callable) + : Callable(std::forward(Callable)) {} RetT call(ArgTs &&...Args) override { return Callable(std::forward(Args)...); } @@ -59,8 +61,9 @@ public: template class GenericConstCallableImpl : public GenericConstCallable { public: - GenericConstCallableImpl(CallableT &&Callable) - : Callable(std::move(Callable)) {} + template + GenericConstCallableImpl(CallableInitT &&Callable) + : Callable(std::forward(Callable)) {} RetT call(ArgTs &&...Args) const override { return Callable(std::forward(Args)...); } @@ -93,7 +96,7 @@ public: template move_only_function(CallableT &&Callable) : C(std::make_unique>>( - std::move(Callable))) {} + std::forward(Callable))) {} RetT operator()(ArgTs... Params) const { return C->call(std::forward(Params)...); @@ -126,7 +129,7 @@ public: template move_only_function(CallableT &&Callable) : C(std::make_unique>>( - std::move(Callable))) {} + std::forward(Callable))) {} RetT operator()(ArgTs... Params) const { return C->call(std::forward(Params)...); diff --git a/orc-rt/unittests/move_only_function-test.cpp b/orc-rt/unittests/move_only_function-test.cpp index 334c65505784..adec65475e3c 100644 --- a/orc-rt/unittests/move_only_function-test.cpp +++ b/orc-rt/unittests/move_only_function-test.cpp @@ -228,3 +228,21 @@ TEST(MoveOnlyFunctionTest, Constness) { EXPECT_EQ(Const, 1U); } } + +TEST(MoveOnlyFunctionTest, ShouldCopyInitialize) { + // Check that we don't accidentally move-initialize move_only_functions. + class ShouldCopy { + public: + ShouldCopy(bool &Moved) : Moved(Moved) {} + ShouldCopy(const ShouldCopy &) = default; + ShouldCopy(ShouldCopy &&Other) : Moved(Other.Moved) { Moved = true; } + void operator()() {} + + private: + bool &Moved; + }; + bool DidMove = false; + ShouldCopy SC(DidMove); + move_only_function F(SC); + EXPECT_FALSE(DidMove); +}