https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89947

            Bug ID: 89947
           Summary: Resolution of base classes fail for some automatic
                    types in template struct functions
           Product: gcc
           Version: 8.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: paolo at luccalug dot it
  Target Milestone: ---

Created attachment 46081
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46081&action=edit
A minimal testcase

I'm using G++ 8.2.1 installed with the Arch Linux package `gcc
8.2.1+20181127-1`.

```
$ g++ -v
g++ (GCC) 8.2.1 20181127
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
```

A minimal source file that triggers the problem is the following:

```
namespace ns {
        struct A { void f(){} };
}

template<typename C> struct B { void f(){} };
struct C : public ns::A, B<C> {};

template<typename T> struct X { // NOTE: no error if X were not a template
        C getC() { return C(); } // NOTE: no error if `getC` were outside of
this class
        void f() {
                // NOTE: no error if we're running this code from outside of
this class: `x.getC().A...`

                getC().A::f(); // ‘A’ has not been declared
                auto c4 = getC(); c4.A::f(); // ‘A’ has not been declared
                decltype(getC()) c5 = getC(); c5.A::f(); // ‘A’ has not been
declared
                C c6 = getC(); c6.A::f(); // this one works

                getC().B::f(); // ‘template<class C> struct B’ used without
template parameters
                auto c1 = getC(); c1.B::f(); // ‘template<class C> struct B’
used without template parameters
                decltype(getC()) c2 = getC(); c1.B::f(); // ‘template<class C>
struct B’ used without template parameters
                C c3 = getC(); c3.B::f(); // this one works
        }
};

int main() {
        X<void> x;
        x.f();
        return 0;
}
```

G++ fails to build it with default options (and any options I tried):

```
$ g++ test.cpp 
test.cpp: In member function ‘void X<T>::f()’:
test.cpp:14:10: error: ‘A’ has not been declared
   getC().A::f(); // ‘A’ has not been declared
          ^
test.cpp:15:24: error: ‘A’ has not been declared
   auto c4 = getC(); c4.A::f(); // ‘A’ has not been declared
                        ^
test.cpp:16:36: error: ‘A’ has not been declared
   decltype(getC()) c5 = getC(); c5.A::f(); // ‘A’ has not been declared
                                    ^
test.cpp:19:10: error: ‘template<class C> struct B’ used without template
parameters
   getC().B::f(); // ‘template<class C> struct B’ used without template
parameters
          ^
test.cpp:20:24: error: ‘template<class C> struct B’ used without template
parameters
   auto c1 = getC(); c1.B::f(); // ‘template<class C> struct B’ used without
template parameters
                        ^
test.cpp:21:36: error: ‘template<class C> struct B’ used without template
parameters
   decltype(getC()) c2 = getC(); c1.B::f(); // ‘template<class C> struct B’
used without template parameters
```

Clang (8.0.0) gives no error, and I believe that's the expected behavior.

Reply via email to