| // RUN: %clang_cc1 -fsyntax-only -verify %s | 
 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s | 
 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s | 
 |  | 
 | // PR4607 | 
 | template <class T> struct X {}; | 
 |  | 
 | template <> struct X<char> | 
 | { | 
 |   static char* g(); | 
 | }; | 
 |  | 
 | template <class T> struct X2 {}; | 
 |  | 
 | template <class U> | 
 | struct X2<U*> { | 
 |   static void f() { | 
 |     X<U>::g(); | 
 |   } | 
 | }; | 
 |  | 
 | void a(char *a, char *b) {X2<char*>::f();} | 
 |  | 
 | namespace WonkyAccess { | 
 |   template<typename T> | 
 |   struct X { | 
 |     int m; | 
 |   }; | 
 |  | 
 |   template<typename U> | 
 |   class Y; | 
 |  | 
 |   template<typename U> | 
 |   struct Y<U*> : X<U> { }; | 
 |  | 
 |   template<> | 
 |   struct Y<float*> : X<float> { }; | 
 |  | 
 |   int f(Y<int*> y, Y<float*> y2) { | 
 |     return y.m + y2.m; | 
 |   } | 
 | } | 
 |  | 
 | // <rdar://problem/9169404> | 
 | namespace rdar9169404 { | 
 |   template<typename T, T N> struct X { }; | 
 |   template<bool C> struct X<bool, C> { | 
 |     typedef int type; | 
 |   }; | 
 |  | 
 |   X<bool, -1>::type value; | 
 | #if __cplusplus >= 201103L | 
 |   // expected-error@-2 {{non-type template argument evaluates to -1, which cannot be narrowed to type 'bool'}} | 
 | #else | 
 |   // expected-no-diagnostics | 
 | #endif | 
 | } | 
 |  | 
 | // rdar://problem/39524996 | 
 | namespace rdar39524996 { | 
 |   template <typename T, typename U> | 
 |   struct enable_if_not_same | 
 |   { | 
 |     typedef void type; | 
 |   }; | 
 |   template <typename T> | 
 |   struct enable_if_not_same<T, T>; | 
 |  | 
 |   template <typename T> | 
 |   struct Wrapper { | 
 |     // Assertion triggered on trying to set twice the same partial specialization | 
 |     // enable_if_not_same<int, int> | 
 |     template <class U> | 
 |     Wrapper(const Wrapper<U>& other, | 
 |             typename enable_if_not_same<U, T>::type* = 0) {} | 
 |  | 
 |     explicit Wrapper(int i) {} | 
 |   }; | 
 |  | 
 |   template <class T> | 
 |   struct Container { | 
 |     // It is important that the struct has implicit copy and move constructors. | 
 |     Container() : x() {} | 
 |  | 
 |     template <class U> | 
 |     Container(const Container<U>& other) : x(static_cast<T>(other.x)) {} | 
 |  | 
 |     // Implicit constructors are member-wise, so the field triggers instantiation | 
 |     // of T constructors and we instantiate all of them for overloading purposes. | 
 |     T x; | 
 |   }; | 
 |  | 
 |   void takesWrapperInContainer(const Container< Wrapper<int> >& c); | 
 |   void test() { | 
 |     // Type mismatch triggers initialization with conversion which requires | 
 |     // implicit constructors to be instantiated. | 
 |     Container<int> c; | 
 |     takesWrapperInContainer(c); | 
 |   } | 
 | } |