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);
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~

Reply via email to