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

Reply via email to