------- 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