------- Comment #8 from jakub at gcc dot gnu dot org 2007-12-13 10:10 ------- Simplified testcase: template <typename T> struct A { struct C { template <typename U> struct D {}; }; template <typename U> friend C::D<U> operator* (U const &); };
struct E {}; int main () { A<E> a; E e; *e; } A<E>::C wasn't instantiated, because during cp_parser_nested_name_specifier_opt where it normally would be instantiated it was dependent type: /* If it is a class scope, try to complete it; we are about to be looking up names inside the class. */ if (TYPE_P (new_scope) /* Since checking types for dependency can be expensive, avoid doing it if the type is already complete. */ && !COMPLETE_TYPE_P (new_scope) /* Do not try to complete dependent types. */ && !dependent_type_p (new_scope)) { new_scope = complete_type (new_scope); and then just build_x_indirect_ref -> build_new_op -> build_{over,cxx}_call -> require_complete_type ... -> instantiate_class_template instantiates the return type without completing the scopes. Another testcase that fails similarly is template <typename T> struct A { struct C { template <typename U> struct D {}; }; template <typename S> static C::D<S> bar (S const &); }; struct E {}; int main () { E e; A<E>::bar (e); } so it is not just friend related. One fix would be just remove the assertion and instead call complete_type_or_else on the scope. -- jakub at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |mmitchel at gcc dot gnu dot | |org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33959