[libcxx] r212070 - Fix libc++ bug #20039: 'Constructing std::function from empty compatible std::function results in half-empty state' Thanks to Agustin Berge for the report, and for his and Eric Fiselier's work on a fix.
Marshall Clow
mclow.lists at gmail.com
Mon Jun 30 14:27:51 PDT 2014
Author: marshall
Date: Mon Jun 30 16:27:51 2014
New Revision: 212070
URL: http://llvm.org/viewvc/llvm-project?rev=212070&view=rev
Log:
Fix libc++ bug #20039: 'Constructing std::function from empty compatible std::function results in half-empty state' Thanks to Agustin Berge for the report, and for his and Eric Fiselier's work on a fix.
Added:
libcxx/trunk/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/no-variadics.pass.cpp
Modified:
libcxx/trunk/include/__functional_03
libcxx/trunk/include/functional
libcxx/trunk/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp
Modified: libcxx/trunk/include/__functional_03
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__functional_03?rev=212070&r1=212069&r2=212070&view=diff
==============================================================================
--- libcxx/trunk/include/__functional_03 (original)
+++ libcxx/trunk/include/__functional_03 Mon Jun 30 16:27:51 2014
@@ -651,9 +651,14 @@ class _LIBCPP_TYPE_VIS_ONLY function<_Rp
__base* __f_;
template <class _Fp>
+ _LIBCPP_INLINE_VISIBILITY
static bool __not_null(const _Fp&) {return true;}
template <class _R2>
- static bool __not_null(const function<_Rp()>& __p) {return __p;}
+ _LIBCPP_INLINE_VISIBILITY
+ static bool __not_null(_R2 (*__p)()) {return __p;}
+ template <class _R2>
+ _LIBCPP_INLINE_VISIBILITY
+ static bool __not_null(const function<_R2()>& __p) {return __p;}
public:
typedef _Rp result_type;
@@ -955,7 +960,7 @@ class _LIBCPP_TYPE_VIS_ONLY function<_Rp
static bool __not_null(_R2 (_Cp::*__p)() const volatile) {return __p;}
template <class _R2, class _B0>
_LIBCPP_INLINE_VISIBILITY
- static bool __not_null(const function<_Rp(_B0)>& __p) {return __p;}
+ static bool __not_null(const function<_R2(_B0)>& __p) {return __p;}
public:
typedef _Rp result_type;
@@ -1257,7 +1262,7 @@ class _LIBCPP_TYPE_VIS_ONLY function<_Rp
static bool __not_null(_R2 (_Cp::*__p)(_B1) const volatile) {return __p;}
template <class _R2, class _B0, class _B1>
_LIBCPP_INLINE_VISIBILITY
- static bool __not_null(const function<_Rp(_B0, _B1)>& __p) {return __p;}
+ static bool __not_null(const function<_R2(_B0, _B1)>& __p) {return __p;}
public:
typedef _Rp result_type;
@@ -1558,7 +1563,7 @@ class _LIBCPP_TYPE_VIS_ONLY function<_Rp
static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) const volatile) {return __p;}
template <class _R2, class _B0, class _B1, class _B2>
_LIBCPP_INLINE_VISIBILITY
- static bool __not_null(const function<_Rp(_B0, _B1, _B2)>& __p) {return __p;}
+ static bool __not_null(const function<_R2(_B0, _B1, _B2)>& __p) {return __p;}
public:
typedef _Rp result_type;
Modified: libcxx/trunk/include/functional
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/functional?rev=212070&r1=212069&r2=212070&view=diff
==============================================================================
--- libcxx/trunk/include/functional (original)
+++ libcxx/trunk/include/functional Mon Jun 30 16:27:51 2014
@@ -1421,7 +1421,7 @@ class _LIBCPP_TYPE_VIS_ONLY function<_Rp
static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const volatile) {return __p;}
template <class _R2, class ..._Ap>
_LIBCPP_INLINE_VISIBILITY
- static bool __not_null(const function<_Rp(_Ap...)>& __p) {return __p;}
+ static bool __not_null(const function<_R2(_Ap...)>& __p) {return !!__p;}
template <class _Fp, bool = !is_same<_Fp, function>::value &&
__invokable<_Fp&, _ArgTypes...>::value>
Modified: libcxx/trunk/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp?rev=212070&r1=212069&r2=212070&view=diff
==============================================================================
--- libcxx/trunk/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp (original)
+++ libcxx/trunk/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp Mon Jun 30 16:27:51 2014
@@ -99,6 +99,18 @@ int main()
assert(f2.target<int(*)(int)>() == 0);
assert(f2.target<A>() == 0);
}
+ {
+ std::function<int(int)> f;
+ assert(new_called == 0);
+ assert(f.target<int(*)(int)>() == 0);
+ assert(f.target<A>() == 0);
+ assert(!f);
+ std::function<long(int)> g = f;
+ assert(new_called == 0);
+ assert(g.target<long(*)(int)>() == 0);
+ assert(g.target<A>() == 0);
+ assert(!g);
+ }
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
assert(new_called == 0);
{
Added: libcxx/trunk/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/no-variadics.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/no-variadics.pass.cpp?rev=212070&view=auto
==============================================================================
--- libcxx/trunk/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/no-variadics.pass.cpp (added)
+++ libcxx/trunk/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/no-variadics.pass.cpp Mon Jun 30 16:27:51 2014
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// class function<R()>
+
+// template<class F> function(F);
+
+#define _LIBCPP_HAS_NO_VARIADICS
+#include <functional>
+#include <cassert>
+
+int main()
+{
+ std::function<void()> f(static_cast<void(*)()>(0));
+ assert(!f);
+}
More information about the cfe-commits
mailing list