https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93085
--- Comment #3 from Arthur O'Dwyer <arthur.j.odwyer at gmail dot com> --- Re comment 2: My original test code was "invalid-code", but here's one I believe to be "valid-code" in C++20. // https://godbolt.org/z/dqcWeq template<template<class> class A> struct G { template<class T> using B = A<T>; template<B> static int foo(); template<int> static int foo(); int x = foo<42>(); // OK }; test.cc:7:21: internal compiler error: in get_class_binding_direct, at cp/name-lookup.c:1238 7 | int x = foo<42>(); // OK | ^ ==== If you change the `<B>` to an `<A>`, the ICE disappears, but GCC still gives a bogus error at template-definition time: // https://godbolt.org/z/Tjrnzv template<template<class> class A> struct G { template<class T> using B = A<T>; template<A> static int foo(); // #1 template<int> static int foo(); // #2 int x = foo<42>(); // OK }; test.cc:7:21: error: call of overloaded 'foo()' is ambiguous 7 | int x = foo<42>(); // OK | ^ GCC shouldn't even be trying to resolve `foo<42>()` until `G` has been instantiated; and once `G` has been instantiated with some specific `A`, this call may or may not be ambiguous (depending on whether it's possible to deduce the template arguments to foo #1 or not).