> I'll need a more surgical fix to this, but I'm having trouble creating
> a small test case that demonstrates the problem I'm seeing in the
> pathological test case I have, so it's been a real pain to analyze.

OK, I think I have a reasonably small test case that illustrates the
problem. Here we have a base class B that contains a class S. Add to
that a class template D derived from B, that contains a class SS
derived from S. Now add a function template in B whose template
parameter is one of the various SS subclasses:

$ cat t1.cc
class B {
 public:
  B();
  virtual ~B();
  virtual void set(int) = 0;
  struct S {
    int s1;
  };
  virtual S* new_s() = 0;
  template <typename T>
  T* get()
  { return static_cast<T*>(new_s()); }
  S* s_;
};

template <int a, int b>
class D : public B {
 public:
  const int a_ = a;
  const int b_ = b;
  D() : B() { }
  virtual ~D();
  int val() { return get<SS>()->s2; }
  virtual void set(int) { }
  struct SS : public S {
    int s2;
  };
  virtual SS* new_s() { return new SS; }
};

int foo()
{
  D<1, 1> d1;
  D<1, 2> d2;
  return d1.val() + d2.val();
}
$ g++ --std=c++11 -c -g -fdebug-types-sections t1.cc
$ readelf -wi t1.o

In the type unit for each of the instantiations of D, we'll find a
copy of the declaration for class B with all the instantiated member
functions -- B::get<D<1, 1>::SS> and B::get<D<1, 2>::SS> -- in each
copy. Scale this up to a base class with many such member functions,
and a derived class template instantiated many times across four
template value parameters, and GCC explodes.

I think the problem is that when copying the declaration for B into
the type units for D<1, 1> and D<1, 2>, we're also copying B's
children. I don't think we need to do that -- it should be sufficient
to have a single DW_TAG_class_type DIE for B with DW_AT_declaration
set, and no children. If the type unit for D<x, x> needs to reference
any of B's children, copy_decls_walk will find those and install them
under the declaration for B as needed.

I'm testing a patch now.

-cary

Reply via email to