http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59144
Bug ID: 59144 Summary: weird behavior when dealing with too complicated templates and class hierarchy Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: tmmikolajczyk at gmail dot com gcc 4.8.2 linux x86_64 Please consider the following code: class Base { public: virtual ~Base() {} protected: void foo() const {} }; template<typename T> class CRTP : protected virtual T {}; template<typename T, typename U> class X : protected virtual CRTP<U> { public: virtual void bar(const Base& inst) const { inst.foo(); } }; template<typename T> class Y: protected virtual CRTP<T> {}; class Z : private Y<Base>, public X<Z, Base> {}; int main(int, char**) { Z z; return 0; } Both gcc and clang rejects this code complaining that: $ g++ main.cpp main.cpp: In instantiation of 'void X<T, U>::bar(const Base&) const [with T = Z; U = Base]': main.cpp:32:1: required from here main.cpp:7:10: error: 'void Base::foo() const' is protected void foo() const {} ^ main.cpp:19:18: error: within this context inst.foo(); ^ However when making the "X::bar" method non-virtual: void bar(const Base& inst) const The compilation passes (on gcc and clang). It's quite weird that the virtualism of the "X::bar" method has such an impact. Please also consider the following sligthly modified "X::bar" method: virtual void bar(const T& inst) const Gcc silently accepts such code. but clang rejects it: $ clang++ main.cpp main.cpp:19:14: error: 'foo' is a private member of 'Base' inst.foo(); ^ main.cpp:26:7: note: in instantiation of member function 'X<Z, Base>::bar' requested here class Z : private Y<Base>, public X<Z, Base> {}; ^ main.cpp:26:11: note: constrained by private inheritance here class Z : private Y<Base>, public X<Z, Base> {}; ^~~~~~~~~~~~~~~ main.cpp:7:10: note: member is declared here void foo() const {} ^ main.cpp:19:9: error: cannot cast 'const Z' to its private base class 'const Base' inst.foo(); ^ main.cpp:26:11: note: constrained by private inheritance here class Z : private Y<Base>, public X<Z, Base> {}; ^~~~~~~~~~~~~~~ 2 errors generated. $