[Bug c++/39405] std::shared_ptr barfs on incomplete template class that boost::shared_ptr accepts

d dot frey at gmx dot de gcc-bugzilla@gcc.gnu.org
Fri Mar 13 14:53:00 GMT 2009



------- Comment #12 from d dot frey at gmx dot de  2009-03-13 14:53 -------
(In reply to comment #11)
> I understand. Too bad that we can't make it to work for 4.3.x without
> regressing on libstdc++/35637 :( I'm puzzled by the fact that the tr1 version
> works, only is_reference is really different in that case... If you can spot
> something please let me know... Otherwise I will just add the testcase.

I think I might have a solution, thanks to the hint to the difference of std::
vs. std::tr1:: you found.

In tr1, shared_ptr uses std::tr1::add_reference instead of
std::add_lvalue_reference. This seems to trigger it, here's a reduced testcase:

#include <type_traits>
#include <tr1/type_traits>

template<typename T>
struct ptr
{
   // this works:
   // typename std::tr1::add_reference<T>::type dummy() const;

   // this fails:
   typename std::add_lvalue_reference<T>::type dummy() const;
};

template<typename T>
struct foo
{
   ptr< foo > p;
};

int main()
{
   (void)std::is_abstract< foo<int> >::value;
}

The error message shows the following loop:

from main: std::is_abstract<T>
      instantiates T (here: foo<int>)
which instantiates ptr<T>
which instantiates std::add_lvalue_reference<T>
which instantiates std::is_function<T>
which instantiates std::is_abstract<T>
which fails because this is what the compiler is trying to do in the first
place.

To break this loop, the following works:

In /usr/include/c++/4.3.2/tr1_impl/type_traits, change is_function from

  /// is_function
  template<typename _Tp>
    struct is_function
    : public integral_constant<bool, !(__in_array<_Tp>::__value
                                       || is_abstract<_Tp>::value
                                       || is_reference<_Tp>::value
                                       || is_void<_Tp>::value)>
    { };

to

  /// is_function
  template<typename _Tp>
    struct is_function
    : public integral_constant<bool, !(__in_array<_Tp>::__value
                                       || __is_abstract(_Tp)
                                       || is_reference<_Tp>::value
                                       || is_void<_Tp>::value)>
    { };


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39405



More information about the Gcc-bugs mailing list