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

Reply via email to