[llvm] cbce88d - FunctionRef: Strip cv qualifiers in the converting constructor

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 27 16:34:33 PDT 2020


Author: David Blaikie
Date: 2020-03-27T16:31:58-07:00
New Revision: cbce88dd3a9ea7161da3c57749cf03873dc7ea79

URL: https://github.com/llvm/llvm-project/commit/cbce88dd3a9ea7161da3c57749cf03873dc7ea79
DIFF: https://github.com/llvm/llvm-project/commit/cbce88dd3a9ea7161da3c57749cf03873dc7ea79.diff

LOG: 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.

Added: 
    

Modified: 
    llvm/include/llvm/ADT/STLExtras.h
    llvm/unittests/ADT/FunctionRefTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h
index ad1150b6251b..e5620bedb0cd 100644
--- a/llvm/include/llvm/ADT/STLExtras.h
+++ b/llvm/include/llvm/ADT/STLExtras.h
@@ -114,9 +114,11 @@ class function_ref<Ret(Params...)> {
   function_ref(std::nullptr_t) {}
 
   template <typename Callable>
-  function_ref(Callable &&callable,
-               std::enable_if_t<!std::is_same<std::remove_reference_t<Callable>,
-                                              function_ref>::value> * = nullptr)
+  function_ref(
+      Callable &&callable,
+      std::enable_if_t<
+          !std::is_same<std::remove_cv_t<std::remove_reference_t<Callable>>,
+                        function_ref>::value> * = nullptr)
       : callback(callback_fn<typename std::remove_reference<Callable>::type>),
         callable(reinterpret_cast<intptr_t>(&callable)) {}
 

diff  --git a/llvm/unittests/ADT/FunctionRefTest.cpp b/llvm/unittests/ADT/FunctionRefTest.cpp
index 0f744c1032e9..669b87dbf8e4 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<int()> X;
+  function_ref<int()> Y = A;
+  function_ref<int()> Z = static_cast<const function_ref<int()> &&>(Y);
+  X = Z;
+  Y = nullptr;
+  ASSERT_EQ(1, X());
 }
+
+} // namespace


        


More information about the llvm-commits mailing list