https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80229
Bug ID: 80229 Summary: [7 Regression] shared_ptr<T> gives an error when is_function<T> is true Product: gcc Version: 7.0.1 Status: UNCONFIRMED Keywords: rejects-valid Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- #include <memory> struct Foo {}; using FooFn = Foo (); using FooFnPtr = Foo (*)(); using FooDel = void (*)(FooFnPtr); static_assert(std::is_same<FooFn*, FooFnPtr>::value, ""); void del(FooFnPtr) {} Foo fun() { return {}; } int main() { std::shared_ptr<FooFn>(&fun, &del); } This compiled with previous versions, but since the enable_shared_from_this refactoring on trunk it results in an error. I don't see anything in the standard that says it shouldn't work. The _M_enable_shared_from_this overloads both take const _Yp* and when _Yp is a function type there's no conversion from _Yp* to const _Yp*. In file included from /home/jwakely/gcc/7/include/c++/7.0.1/bits/shared_ptr.h:52:0, from /home/jwakely/gcc/7/include/c++/7.0.1/memory:81, from sp.cc:1: /home/jwakely/gcc/7/include/c++/7.0.1/bits/shared_ptr_base.h: In instantiation of ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Yp*, _Deleter) [with _Yp = Foo(); _Deleter = void (*)(Foo (*)()); <template-parameter-2-3> = void; _Tp = Foo(); __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’: /home/jwakely/gcc/7/include/c++/7.0.1/bits/shared_ptr.h:147:37: required from ‘std::shared_ptr<_Tp>::shared_ptr(_Yp*, _Deleter) [with _Yp = Foo(); _Deleter = void (*)(Foo (*)()); <template-parameter-2-3> = void; _Tp = Foo()]’ sp.cc:13:38: required from here /home/jwakely/gcc/7/include/c++/7.0.1/bits/shared_ptr_base.h:1090:35: error: no matching function for call to ‘std::__shared_ptr<Foo(), (__gnu_cxx::_Lock_policy)2>::_M_enable_shared_from_this_with(Foo (*&)())’ _M_enable_shared_from_this_with(__p); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~ /home/jwakely/gcc/7/include/c++/7.0.1/bits/shared_ptr_base.h:1368:2: note: candidate: template<class _Yp> typename std::enable_if<std::__shared_ptr<_Tp, _Lp>::__has_esft_base<_Yp>::value>::type std::__shared_ptr<_Tp, _Lp>::_M_enable_shared_from_this_with(const _Yp*) [with _Yp = _Yp; _Tp = Foo(); __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2] _M_enable_shared_from_this_with(const _Yp* __p) noexcept ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/jwakely/gcc/7/include/c++/7.0.1/bits/shared_ptr_base.h:1368:2: note: template argument deduction/substitution failed: /home/jwakely/gcc/7/include/c++/7.0.1/bits/shared_ptr_base.h:1090:35: note: types ‘const _Yp’ and ‘Foo()’ have incompatible cv-qualifiers _M_enable_shared_from_this_with(__p); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~ /home/jwakely/gcc/7/include/c++/7.0.1/bits/shared_ptr_base.h:1376:2: note: candidate: template<class _Yp> typename std::enable_if<(! std::__shared_ptr<_Tp, _Lp>::__has_esft_base<_Yp>::value)>::type std::__shared_ptr<_Tp, _Lp>::_M_enable_shared_from_this_with(const _Yp*) [with _Yp = _Yp; _Tp = Foo(); __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2] _M_enable_shared_from_this_with(const _Yp*) noexcept ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/jwakely/gcc/7/include/c++/7.0.1/bits/shared_ptr_base.h:1376:2: note: template argument deduction/substitution failed: /home/jwakely/gcc/7/include/c++/7.0.1/bits/shared_ptr_base.h:1090:35: note: types ‘const _Yp’ and ‘Foo()’ have incompatible cv-qualifiers _M_enable_shared_from_this_with(__p); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~