1/* { dg-do compile } */
2template <typename _Tp> _Tp *__addressof(_Tp &) {}
3template <typename _Tp> class A {
4public:
5  typedef _Tp *pointer;
6};
7template <typename _Tp> class M : public A<_Tp> {
8public:
9  typedef M other;
10  ~M();
11};
12class B {
13public:
14  B(int *);
15};
16class C {
17public:
18  void GetNext();
19  C *GetChildren();
20};
21template <typename _Tp> void _Destroy(_Tp *p1) { p1->~_Tp(); }
22struct D {
23  template <typename _ForwardIterator>
24  static void __destroy(_ForwardIterator p1, _ForwardIterator p2) {
25    for (; p1 != p2; ++p1)
26      _Destroy(__addressof(*p1));
27  }
28};
29template <typename _ForwardIterator>
30void _Destroy(_ForwardIterator p1, _ForwardIterator p2) {
31  D::__destroy(p1, p2);
32}
33template <typename _ForwardIterator, typename _Tp>
34void _Destroy(_ForwardIterator p1, _ForwardIterator p2, M<_Tp> &) {
35  _Destroy(p1, p2);
36}
37template <typename _Alloc> struct F {
38  typedef _Alloc _Tp_alloc_type;
39  typedef typename _Tp_alloc_type::pointer pointer;
40  struct N : _Tp_alloc_type {
41    pointer _M_start;
42    pointer _M_finish;
43  };
44  _Tp_alloc_type &_M_get_Tp_allocator();
45  N _M_impl;
46};
47template <typename _Tp, typename _Alloc = M<_Tp> > class O : F<_Alloc> {
48using  F<_Alloc>::_M_get_Tp_allocator;
49public:
50  ~O() {
51    _Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
52             _M_get_Tp_allocator());
53  }
54};
55template <class T> void checked_delete(T *p1) { delete p1; }
56template <class> class I;
57template <class T> struct J {
58  typedef T *type;
59};
60class K;
61class L {
62public:
63  virtual ~L();
64};
65class P : L {
66  O<I<int> > databasesM;
67  O<I<K> > usersM;
68public:
69  I<int> addDatabase();
70};
71C a;
72C *b;
73int atomic_exchange_and_add();
74class G {
75public:
76  virtual void dispose() = 0;
77  void release() {
78    if (atomic_exchange_and_add() == 1)
79      dispose();
80  }
81};
82class Q : G {
83  P *px_;
84  Q() {}
85  void dispose() { checked_delete(px_); }
86};
87class H {
88  G *pi_;
89public:
90  H();
91  H(P *);
92  ~H() {
93    if (pi_)
94      pi_->release();
95  }
96};
97template <class T, class Y> void sp_pointer_construct(I<T> *, Y, H);
98template <class T> class I {
99public:
100  typedef T element_type;
101  template <class Y> I(Y *p1) { sp_pointer_construct(this, 0, 0); }
102  typename J<T>::type operator->();
103  H pn;
104};
105void getNodeContent(const B &) {
106  for (C *n = a.GetChildren(); n; n->GetNext())
107    ;
108}
109void parseDatabase(I<P> p1) {
110  I<int> c = p1->addDatabase();
111  for (; b;)
112    getNodeContent(0);
113}
114void addServer() { I<int>(new P); }
115