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

Reply via email to