https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111463
Bug ID: 111463 Summary: Access error in instantiation of template class, incorrectly using inherited constructor of wrong type Product: gcc Version: 11.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: bckempa at iastate dot edu Target Milestone: --- Version: 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04) [replicated in 11.2 - Trunk] System: x86_64-linux-gnu Ubuntu 22.04 Flags: -std=c++14 Given the case of a derived class inheriting from a base where both inherent a templated manager class with different template arguments: ``` class EventA {}; class EventB {}; template <class Event> class Manager {}; class Base : Manager<EventA> {}; template <class T> class Derived : Base, Manager<T> { using Foo = Manager<T>; }; int main() { Derived<EventB> foo; } ``` GCC 11.2 and above gives the following error: ``` test.cpp: In instantiation of ‘class Derived<EventB>’: test.cpp:14:21: required from here test.cpp:10:17: error: ‘class Manager<EventA> Manager<EventA>::Manager’ is private within this context 10 | using Foo = Manager<T>; | ^~~~~~~~~~ test.cpp:7:7: note: declared private here 7 | class Base : private Manager<EventA> {}; | ^~~~ ``` It appears that gcc is attempting to use the constructor from the base class's inherited Manager<EventB>, which doesn't match the specified Manager<EventB>, rather than the derived class's templated Manager<EventB> parent. This can be worked around by adding a scope resolution operator like this: `using Foo = ::Manager<T>;` This was initially observed on 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04) and I've confirmed the behavior appeared in gcc 11.2 and persists though all versions to trunk, while gcc 4.9.0 (the first to recognize the `-std=c++14` flag) up though gcc 11.1 all select the correct constructor and compile. Adding the `-fno-new-ttp-matching` flag, changing the order of the inheritance list, and replacing `Manager<T>` with an explicit `Manager<EventB>` in the using statement all had no effect. Replacing the template argument with an explicit `Manager<EventB>` in the inheritance list of the derived class does fix the behavior, but then the derived class is no longer templated defeating the purpose.