[libcxx] r284333 - Make any_cast<void()>(nullptr) compile

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Sun Oct 16 04:56:39 PDT 2016


Author: ericwf
Date: Sun Oct 16 06:56:38 2016
New Revision: 284333

URL: http://llvm.org/viewvc/llvm-project?rev=284333&view=rev
Log:
Make any_cast<void()>(nullptr) compile

Modified:
    libcxx/trunk/include/any
    libcxx/trunk/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp

Modified: libcxx/trunk/include/any
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/any?rev=284333&r1=284332&r2=284333&view=diff
==============================================================================
--- libcxx/trunk/include/any (original)
+++ libcxx/trunk/include/any Sun Oct 16 06:56:38 2016
@@ -622,6 +622,18 @@ any_cast(any const * __any) _NOEXCEPT
     return _VSTD::any_cast<_ValueType>(const_cast<any *>(__any));
 }
 
+template <class _RetType>
+inline _LIBCPP_INLINE_VISIBILITY
+_RetType __pointer_or_func_cast(void* __p, /*IsFunction*/false_type) noexcept {
+  return static_cast<_RetType>(__p);
+}
+
+template <class _RetType>
+inline _LIBCPP_INLINE_VISIBILITY
+_RetType __pointer_or_func_cast(void*, /*IsFunction*/true_type) noexcept {
+  return nullptr;
+}
+
 template <class _ValueType>
 add_pointer_t<_ValueType>
 any_cast(any * __any) _NOEXCEPT
@@ -631,15 +643,15 @@ any_cast(any * __any) _NOEXCEPT
                   "_ValueType may not be a reference.");
     typedef typename add_pointer<_ValueType>::type _ReturnType;
     if (__any && __any->__h) {
-        return static_cast<_ReturnType>(
-            __any->__call(_Action::_Get, nullptr,
+      void *__p = __any->__call(_Action::_Get, nullptr,
 #if !defined(_LIBCPP_NO_RTTI)
                           &typeid(_ValueType),
 #else
                           nullptr,
 #endif
-                          __any_imp::__get_fallback_typeid<_ValueType>()
-        ));
+                          __any_imp::__get_fallback_typeid<_ValueType>());
+        return _VSTD::__pointer_or_func_cast<_ReturnType>(
+            __p, is_function<_ValueType>{});
     }
     return nullptr;
 }

Modified: libcxx/trunk/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp?rev=284333&r1=284332&r2=284333&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp Sun Oct 16 06:56:38 2016
@@ -147,6 +147,18 @@ void test_cast_non_copyable_type()
     assert(std::any_cast<NoCopy>(&ca) == nullptr);
 }
 
+void test_fn() {}
+
+void test_cast_function_pointer() {
+    using T = void(*)();
+    std::any a(test_fn);
+    // An any can never store a function type, but we should at least be able
+    // to ask.
+    assert(std::any_cast<void()>(&a) == nullptr);
+    T fn_ptr = std::any_cast<T>(a);
+    assert(fn_ptr == test_fn);
+}
+
 int main() {
     test_cast_is_noexcept();
     test_cast_return_type();
@@ -155,4 +167,5 @@ int main() {
     test_cast<small>();
     test_cast<large>();
     test_cast_non_copyable_type();
+    test_cast_function_pointer();
 }




More information about the cfe-commits mailing list