1e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregor// RUN: %clang_cc1 -fsyntax-only -verify %s
2e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregor
3e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregor// PR5868
4e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregorstruct T0 {
5e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregor  int x;
6e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregor  union {
7e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregor    void *m0;
8e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregor  };
9e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregor};
10e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregortemplate <typename T>
110e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesstruct T1 : public T0, public T { //expected-warning{{direct base 'T0' is inaccessible due to ambiguity:\n    struct T1<struct A> -> struct T0\n    struct T1<struct A> -> struct A -> struct T0}}
12e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregor  void f0() {
13e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregor    m0 = 0; // expected-error{{ambiguous conversion}}
14e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregor  }
15e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregor};
16e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregor
17e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregorstruct A : public T0 { };
18e94eec54f4ccb4c16b908e4b00e3eb5f93b723efDouglas Gregor
190e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid f1(T1<A> *S) { S->f0(); } // expected-note{{instantiation of member function}} expected-note{{in instantiation of template class 'T1<A>' requested here}}
201a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor
211a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregornamespace rdar8635664 {
221a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor  template<typename T>
231a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor  struct X {
241a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor    struct inner;
251a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor
261a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor    struct inner {
271a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor      union {
281a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor        int x;
291a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor        float y;
301a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor      };
311a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor
321a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor      typedef T type;
331a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor    };
341a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor  };
351a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor
361a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor  void test() {
371a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor    X<int>::inner i;
381a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor    i.x = 0;
391a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor  }
401a81a11dffa46da43843083ba93a1b9f150fa30aDouglas Gregor}
41