http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56951
Bug #: 56951 Summary: Poor diagnostics for error: invalid abstract return type 'XXX' Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: ppluzhni...@google.com Consider the following test case: #include <vector> using std::vector; using std::iterator_traits; template <typename> struct remove_pointer; template <typename T> struct remove_pointer<T *> { typedef T type; }; template <typename It> class iterator_ptr { typedef typename remove_pointer< typename iterator_traits<It>::value_type>::type value_type; value_type Get(); }; class Table; class F { typedef iterator_ptr<vector<Table *>::iterator> iterator; iterator tables_begin() {} }; class Table { virtual void Fn() = 0; }; This code is accepted by gcc-4.7.x, rejected by current trunk with: g++ -c tt.cc tt.cc:13:14: error: invalid abstract return type ‘Table’ value_type Get(); ^ tt.cc:23:7: note: because the following virtual functions are pure within ‘Table’: class Table { ^ tt.cc:24:16: note: virtual void Table::Fn() virtual void Fn() = 0; ^ I believe the code is in fact invalid. Note that the error tells me the template line (13), but doesn't tell what parameters this template was instantiated with, nor what triggered the instantiation. Compare to much better error produced when I move 'class Table' definition ahead of F: #include <vector> using std::vector; using std::iterator_traits; template <typename> struct remove_pointer; template <typename T> struct remove_pointer<T *> { typedef T type; }; template <typename It> class iterator_ptr { typedef typename remove_pointer< typename iterator_traits<It>::value_type>::type value_type; value_type Get(); }; class Table { virtual void Fn() = 0; }; class F { typedef iterator_ptr<vector<Table *>::iterator> iterator; iterator tables_begin() {} }; g++ -c tt2.cc tt2.cc: In instantiation of ‘class iterator_ptr<__gnu_cxx::__normal_iterator<Table**, std::vector<Table*> > >’: tt2.cc:22:27: required from here tt2.cc:13:14: error: invalid abstract return type ‘Table’ value_type Get(); ^ tt2.cc:16:7: note: because the following virtual functions are pure within ‘Table’: class Table { ^ tt2.cc:17:16: note: virtual void Table::Fn() virtual void Fn() = 0; ^