https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80521
Bug ID: 80521 Summary: Wrong line reported in error for missing template argument in friend class declaration. Product: gcc Version: 7.0.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: carlo at gcc dot gnu.org Target Milestone: --- Although similar to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=8570 from 2002, I guess I'll report it again now, for version 7.0.1. When compiling the following snippet: ------------------------------- template<typename T> struct RingBuffer { private: unsigned long m_capacity; // Number of objects of type T in the buffer. union { T* m_start; // Start of buffer. char* m_storage; }; T* m_head; // Next write position. T* m_tail; // Next read position. protected: friend class ProducerAccess; friend class ConsumerAccess; public: RingBuffer() : m_storage(nullptr), m_head(nullptr), m_tail(nullptr) { } RingBuffer(int objects) : m_storage(nullptr), m_head(nullptr), m_tail(nullptr) { allocate_(objects); } ~RingBuffer() { delete [] m_storage; } private: void allocate_(int objects) { m_capacity = objects * sizeof(T); // Allocate storage aligned to at least 32 bytes. //m_storage = new decltype(*m_storage) [m_capacity]; m_tail = m_head = m_start; } public: void reallocate(int objects) { if (m_storage) delete [] m_storage; allocate_(objects); } }; template<typename T> struct ProducerAccess { private: RingBuffer<T>& m_buffer; public: ProducerAccess(RingBuffer<T>& buffer) : m_buffer(buffer) { } ~ProducerAccess() { } }; template<typename T> struct ConsumerAccess { private: RingBuffer<T>& m_buffer; public: ConsumerAccess(RingBuffer<T>& buffer) : m_buffer(buffer) { } ~ConsumerAccess() { } }; int main() { // Construct an empty buffer. RingBuffer<long> fifo_buffer; // Allocate 100 std::function<void()> objects in it. fifo_buffer.reallocate(100); ProducerAccess<long> pa(fifo_buffer); ConsumerAccess<long> ca(fifo_buffer); } ------------------------------------------ You get an almost random location for where the problem is: >g++-svn-7 -c bug.cxx bug.cxx: In instantiation of ‘struct RingBuffer<long int>’: bug.cxx:60:20: required from here bug.cxx:10:6: error: template argument required for ‘class ProducerAccess’ T* m_tail; // Next read position. ^~~~~~ bug.cxx:10:6: error: template argument required for ‘class ConsumerAccess’ The real problem is here: friend class ProducerAccess; friend class ConsumerAccess; Sorry for not minimizing the snippet further, Carlo