From cbce88dd3a9ea7161da3c57749cf03873dc7ea79 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Fri, 27 Mar 2020 16:28:35 -0700 Subject: [PATCH] FunctionRef: Strip cv qualifiers in the converting constructor Without this some instances of copy construction would use the converting constructor & lead to the destination function_ref referring to the source function_ref instead of the underlying functor. Discovered in feedback from 857bf5da35af8e1f9425e1865dab5f5fce5e38f2 Thanks to Johannes Doerfert, Arthur O'Dwyer, and Richard Smith for the discussion and debugging. --- llvm/include/llvm/ADT/STLExtras.h | 8 +++++--- llvm/unittests/ADT/FunctionRefTest.cpp | 10 ++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h index ad1150b..e5620be 100644 --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -114,9 +114,11 @@ public: function_ref(std::nullptr_t) {} template - function_ref(Callable &&callable, - std::enable_if_t, - function_ref>::value> * = nullptr) + function_ref( + Callable &&callable, + std::enable_if_t< + !std::is_same>, + function_ref>::value> * = nullptr) : callback(callback_fn::type>), callable(reinterpret_cast(&callable)) {} diff --git a/llvm/unittests/ADT/FunctionRefTest.cpp b/llvm/unittests/ADT/FunctionRefTest.cpp index 0f744c1..669b87d 100644 --- a/llvm/unittests/ADT/FunctionRefTest.cpp +++ b/llvm/unittests/ADT/FunctionRefTest.cpp @@ -38,4 +38,14 @@ TEST(FunctionRefTest, Copy) { EXPECT_EQ(1, Y()); } +TEST(FunctionRefTest, BadCopy) { + auto A = [] { return 1; }; + function_ref X; + function_ref Y = A; + function_ref Z = static_cast &&>(Y); + X = Z; + Y = nullptr; + ASSERT_EQ(1, X()); } + +} // namespace -- 2.7.4