1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s 3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s 4 5 // PR4607 6 template <class T> struct X {}; 7 8 template <> struct X<char> 9 { 10 static char* g(); 11 }; 12 13 template <class T> struct X2 {}; 14 15 template <class U> 16 struct X2<U*> { 17 static void f() { 18 X<U>::g(); 19 } 20 }; 21 22 void a(char *a, char *b) {X2<char*>::f();} 23 24 namespace WonkyAccess { 25 template<typename T> 26 struct X { 27 int m; 28 }; 29 30 template<typename U> 31 class Y; 32 33 template<typename U> 34 struct Y<U*> : X<U> { }; 35 36 template<> 37 struct Y<float*> : X<float> { }; 38 39 int f(Y<int*> y, Y<float*> y2) { 40 return y.m + y2.m; 41 } 42 } 43 44 // <rdar://problem/9169404> 45 namespace rdar9169404 { 46 template<typename T, T N> struct X { }; 47 template<bool C> struct X<bool, C> { 48 typedef int type; 49 }; 50 51 X<bool, -1>::type value; 52 #if __cplusplus >= 201103L 53 // expected-error@-2 {{non-type template argument evaluates to -1, which cannot be narrowed to type 'bool'}} 54 #endif 55 } 56 57 // rdar://problem/39524996 58 namespace rdar39524996 { 59 template <typename T, typename U> 60 struct enable_if_not_same 61 { 62 typedef void type; 63 }; 64 template <typename T> 65 struct enable_if_not_same<T, T>; 66 67 template <typename T> 68 struct Wrapper { 69 // Assertion triggered on trying to set twice the same partial specialization 70 // enable_if_not_same<int, int> 71 template <class U> 72 Wrapper(const Wrapper<U>& other, 73 typename enable_if_not_same<U, T>::type* = 0) {} 74 75 explicit Wrapper(int i) {} 76 }; 77 78 template <class T> 79 struct Container { 80 // It is important that the struct has implicit copy and move constructors. 81 Container() : x() {} 82 83 template <class U> 84 Container(const Container<U>& other) : x(static_cast<T>(other.x)) {} 85 86 // Implicit constructors are member-wise, so the field triggers instantiation 87 // of T constructors and we instantiate all of them for overloading purposes. 88 T x; 89 }; 90 91 void takesWrapperInContainer(const Container< Wrapper<int> >& c); 92 void test() { 93 // Type mismatch triggers initialization with conversion which requires 94 // implicit constructors to be instantiated. 95 Container<int> c; 96 takesWrapperInContainer(c); 97 } 98 } 99 100 namespace InstantiationDependent { 101 template<typename> using ignore = void; // expected-warning 0-1{{extension}} 102 template<typename T, typename = void> struct A { 103 static const bool specialized = false; 104 }; 105 template<typename T> struct Hide { typedef void type; }; 106 template<typename T> struct A<T, Hide<ignore<typename T::type> >::type> { 107 static const bool specialized = true; 108 }; 109 110 struct X {}; 111 struct Y { typedef int type; }; 112 _Static_assert(!A<X>::specialized, ""); 113 _Static_assert(A<Y>::specialized, ""); 114 } 115