Skip to content

Instantly share code, notes, and snippets.

@EricWF
Created April 13, 2017 05:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EricWF/c4a5fd77b4a4ff6c176a74c7cbdf5482 to your computer and use it in GitHub Desktop.
Save EricWF/c4a5fd77b4a4ff6c176a74c7cbdf5482 to your computer and use it in GitHub Desktop.
diff --git a/include/memory b/include/memory
index c809942d8..5957dc860 100644
--- a/include/memory
+++ b/include/memory
@@ -2274,6 +2274,8 @@ struct __same_or_less_cv_qualified<_Ptr1, _Ptr2, false>
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS default_delete
{
+ static_assert(!is_function<_Tp>::value,
+ "default_delete cannot be instantiated for function types");
#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT = default;
#else
diff --git a/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp b/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp
new file mode 100644
index 000000000..f50ced09b
--- /dev/null
+++ b/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp
@@ -0,0 +1,40 @@
+#include <memory>
+
+template <int> struct Tag {};
+
+template <int ID>
+using SPtr = std::shared_ptr<void(Tag<ID>)>;
+
+template <int ID>
+using FnType = void(Tag<ID>);
+
+template <int ID>
+void TestFn(Tag<ID>) {}
+
+template <int ID>
+FnType<ID>* getFn() {
+ return &TestFn<ID>;
+}
+
+struct Deleter {
+ template <class Tp>
+ void operator()(Tp) const {
+ using RawT = typename std::remove_pointer<Tp>::type;
+ static_assert(std::is_function<RawT>::value ||
+ std::is_null_pointer<RawT>::value, "");
+ }
+};
+
+int main() {
+ {
+ SPtr<0> s; // OK
+ SPtr<1> s1(nullptr); // OK
+ SPtr<2> s2(getFn<2>(), Deleter{}); // OK
+ SPtr<3> s3(nullptr, Deleter{}); // OK
+ }
+ // expected-error@memory:* 2 {{static_assert failed "default_delete cannot be instantiated for function types"}}
+ {
+ SPtr<4> s4(getFn<4>()); // expected-note {{requested here}}
+ SPtr<5> s5(getFn<5>(), std::default_delete<FnType<5>>{}); // expected-note {{requested here}}
+ }
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment