1 // PR c++/87539
2 // { dg-do compile { target c++11 } }
3 // { dg-options "-Os" }
4 
5 namespace a {
6 template <typename b, typename = b, typename = int> class c;
7 class exception {};
8 template <typename d> struct e { d f; };
9 struct g { g(); g(const g &); };
10 }
11 template <class, class, class = int> class h;
12 template <typename, typename> struct i;
13 template <int j> struct aa { static const int k = j; };
14 struct ac { typedef a::e<int> l; };
15 struct ad;
16 template <int, typename m, typename> struct ae { typedef m l; };
17 template <typename m, typename n> struct ae<false, m, n> { typedef n l; };
18 template <typename m, typename n, typename p> struct o {
19   typedef typename ae<m::k, n, p>::l l;
20 };
21 struct af { af(char *); };
22 template <typename> struct ag { ag(a::g = a::g()) {} };
23 template <typename ah, typename ai, typename aj, typename al>
24 struct i<a::c<ah, ai, aj>, al> { typedef ag<al> l; };
25 namespace ak {
26 template <typename am, typename an, typename ao> struct ap {
27   typedef typename o<am, an, ao>::l ::l l;
28 };
29 template <typename = ad> struct aq { typedef ad l; };
30 }
31 template <typename ar> struct as {
32   typedef char at;
33   template <typename au, typename> static decltype(au(), at()) av(int);
34   template <typename, typename> static int av(...);
35   static const bool k = sizeof(av<ar, int>(0)) == 1;
36 };
37 template <typename ar> struct aw { static const bool k = as<ar>::k; };
38 template <class ar> struct ax { typedef aw<ar> l; };
39 template <typename ar> struct ay { typedef typename ax<ar>::l l; };
40 template <typename ar> struct az : ay<ar>::l {};
41 template <class ar, class> struct ba : aa<az<ar>::k> {};
42 template <class> struct bb : ak::ap<ba<int, int>, ak::aq<>, int> {};
43 template <typename> struct q : ba<bb<int>::l, int> {};
44 template <class, class, bool> class r;
45 template <class s, class t> struct r<s, t, false> {
46   s operator*();
47   s operator++();
48 };
49 template <class, class, class, class, class>
50 class bc : public r<a::e<h<int, int>>, int, q<int>::k> {};
51 template <class bd, class be, class bf, class u, class v, class bg, class w,
52           class x, class bh, class bi>
53 int operator!=(bc<bd, be, bf, u, v>, bc<bg, w, x, bh, bi>);
54 template <class, class, class> struct h {
55   typedef af bl;
56   bc<int, int, int, ak::ap<aa<false>, int, ac>::l, int> begin();
57   bc<int, int, int, ak::ap<aa<false>, int, ac>::l, int> end();
58   template <class bm> bm bn() const;
59   template <class> int bo() const;
60   template <class bm> int bx(const bl &, const bm &) const;
61   template <class> int bp(const bl &) const;
62 };
63 template <class bq, class br, class am>
64 template <class bm>
65 bm h<bq, br, am>::bn() const { typename i<a::c<int>, bm>::l(); return bm(); }
66 template <class bq, class br, class am>
67 template <class>
68 int h<bq, br, am>::bo() const { i<a::c<int>, int>::l(); bn<int>(); return 0; }
69 template <class bq, class br, class am>
70 template <class bm>
71 int h<bq, br, am>::bx(const bl &bs, const bm &) const { bp<int>(bs); return 0; }
72 template <class bq, class br, class am>
73 template <class>
74 int h<bq, br, am>::bp(const bl &) const { bo<int>(); return 0; }
75 char bt[] = "";
76 void
77 d()
78 {
79   h<int, int> bu;
80   for (auto bv : bu)
81     try {
82       bv.f.bx(bt, 0);
83     } catch (a::exception) {
84     }
85 }
86