1 // RUN: clang-cc -fsyntax-only -verify %s 2 template<typename T> 3 class X { 4 public: 5 void f(T x); // expected-error{{argument may not have 'void' type}} 6 void g(T*); 7 8 static int h(T, T); // expected-error 2{{argument may not have 'void' type}} 9 }; 10 11 int identity(int x) { return x; } 12 13 void test(X<int> *xi, int *ip, X<int(int)> *xf) { 14 xi->f(17); 15 xi->g(ip); 16 xf->f(&identity); 17 xf->g(identity); 18 X<int>::h(17, 25); 19 X<int(int)>::h(identity, &identity); 20 } 21 22 void test_bad() { 23 X<void> xv; // expected-note{{in instantiation of template class 'class X<void>' requested here}} 24 } 25 26 template<typename T, typename U> 27 class Overloading { 28 public: 29 int& f(T, T); // expected-note{{previous declaration is here}} 30 float& f(T, U); // expected-error{{functions that differ only in their return type cannot be overloaded}} 31 }; 32 33 void test_ovl(Overloading<int, long> *oil, int i, long l) { 34 int &ir = oil->f(i, i); 35 float &fr = oil->f(i, l); 36 } 37 38 void test_ovl_bad() { 39 Overloading<float, float> off; // expected-note{{in instantiation of template class 'class Overloading<float, float>' requested here}} 40 } 41 42 template<typename T> 43 class HasDestructor { 44 public: 45 virtual ~HasDestructor() = 0; 46 }; 47 48 int i = sizeof(HasDestructor<int>); // FIXME: forces instantiation, but 49 // the code below should probably instantiate by itself. 50 int abstract_destructor[__is_abstract(HasDestructor<int>)? 1 : -1]; 51 52 53 template<typename T> 54 class Constructors { 55 public: 56 Constructors(const T&); 57 Constructors(const Constructors &other); 58 }; 59 60 void test_constructors() { 61 Constructors<int> ci1(17); 62 Constructors<int> ci2 = ci1; 63 } 64 65 66 template<typename T> 67 struct ConvertsTo { 68 operator T(); 69 }; 70 71 void test_converts_to(ConvertsTo<int> ci, ConvertsTo<int *> cip) { 72 int i = ci; 73 int *ip = cip; 74 } 75