185 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // RUN: %clang_cc1 -fsyntax-only -verify %s
 | |
| template<typename T>
 | |
| class X {
 | |
| public:
 | |
|   void f(T x); // expected-error{{argument may not have 'void' type}}
 | |
|   void g(T*);
 | |
| 
 | |
|   static int h(T, T); // expected-error {{argument may not have 'void' type}}
 | |
| };
 | |
| 
 | |
| int identity(int x) { return x; }
 | |
| 
 | |
| void test(X<int> *xi, int *ip, X<int(int)> *xf) {
 | |
|   xi->f(17);
 | |
|   xi->g(ip);
 | |
|   xf->f(&identity);
 | |
|   xf->g(identity);
 | |
|   X<int>::h(17, 25);
 | |
|   X<int(int)>::h(identity, &identity);
 | |
| }
 | |
| 
 | |
| void test_bad() {
 | |
|   X<void> xv; // expected-note{{in instantiation of template class 'X<void>' requested here}}
 | |
| }
 | |
| 
 | |
| template<typename T, typename U>
 | |
| class Overloading {
 | |
| public:
 | |
|   int& f(T, T); // expected-note{{previous declaration is here}}
 | |
|   float& f(T, U); // expected-error{{functions that differ only in their return type cannot be overloaded}}
 | |
| };
 | |
| 
 | |
| void test_ovl(Overloading<int, long> *oil, int i, long l) {
 | |
|   int &ir = oil->f(i, i);
 | |
|   float &fr = oil->f(i, l);
 | |
| }
 | |
| 
 | |
| void test_ovl_bad() {
 | |
|   Overloading<float, float> off; // expected-note{{in instantiation of template class 'Overloading<float, float>' requested here}}
 | |
| }
 | |
| 
 | |
| template<typename T>
 | |
| class HasDestructor {
 | |
| public:
 | |
|   virtual ~HasDestructor() = 0;
 | |
| };
 | |
| 
 | |
| int i = sizeof(HasDestructor<int>); // FIXME: forces instantiation, but 
 | |
|                 // the code below should probably instantiate by itself.
 | |
| int abstract_destructor[__is_abstract(HasDestructor<int>)? 1 : -1];
 | |
| 
 | |
| 
 | |
| template<typename T>
 | |
| class Constructors {
 | |
| public:
 | |
|   Constructors(const T&);
 | |
|   Constructors(const Constructors &other);
 | |
| };
 | |
| 
 | |
| void test_constructors() {
 | |
|   Constructors<int> ci1(17);
 | |
|   Constructors<int> ci2 = ci1;
 | |
| }
 | |
| 
 | |
| 
 | |
| template<typename T>
 | |
| struct ConvertsTo {
 | |
|   operator T();
 | |
| };
 | |
| 
 | |
| void test_converts_to(ConvertsTo<int> ci, ConvertsTo<int *> cip) {
 | |
|   int i = ci;
 | |
|   int *ip = cip;
 | |
| }
 | |
| 
 | |
| // PR4660
 | |
| template<class T> struct A0 { operator T*(); };
 | |
| template<class T> struct A1;
 | |
| 
 | |
| int *a(A0<int> &x0, A1<int> &x1) {
 | |
|   int *y0 = x0;
 | |
|   int *y1 = x1; // expected-error{{no viable conversion}}
 | |
| }
 | |
| 
 | |
| struct X0Base {
 | |
|   int &f();
 | |
|   int& g(int);
 | |
|   static double &g(double);
 | |
| };
 | |
| 
 | |
| template<typename T>
 | |
| struct X0 : X0Base {
 | |
| };
 | |
| 
 | |
| template<typename U>
 | |
| struct X1 : X0<U> {
 | |
|   int &f2() { 
 | |
|     return X0Base::f();
 | |
|   }
 | |
| };
 | |
| 
 | |
| void test_X1(X1<int> x1i) {
 | |
|   int &ir = x1i.f2();
 | |
| }
 | |
| 
 | |
| template<typename U>
 | |
| struct X2 : X0Base, U {
 | |
|   int &f2() { return X0Base::f(); }
 | |
| };
 | |
| 
 | |
| template<typename T>
 | |
| struct X3 {
 | |
|   void test(T x) {
 | |
|     double& d1 = X0Base::g(x);
 | |
|   }
 | |
| };
 | |
| 
 | |
| 
 | |
| template struct X3<double>;
 | |
| 
 | |
| // Don't try to instantiate this, it's invalid.
 | |
| namespace test1 {
 | |
|   template <class T> class A {};
 | |
|   template <class T> class B {
 | |
|     void foo(A<test1::Undeclared> &a) // expected-error {{no member named 'Undeclared' in namespace 'test1'}}
 | |
|     {}
 | |
|   };
 | |
|   template class B<int>;
 | |
| }
 | |
| 
 | |
| namespace PR6947 {
 | |
|   template< class T > 
 | |
|   struct X {
 | |
|     int f0( )      
 | |
|     {
 | |
|       typedef void ( X::*impl_fun_ptr )( );
 | |
|       impl_fun_ptr pImpl = &X::template
 | |
|         f0_impl1<int>;
 | |
|     }
 | |
|   private:                  
 | |
|     int f1() {
 | |
|     }
 | |
|     template< class Processor>                  
 | |
|     void f0_impl1( )                 
 | |
|     {
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   char g0() {
 | |
|     X<int> pc;
 | |
|     pc.f0();
 | |
|   }
 | |
| 
 | |
| }
 | |
| 
 | |
| namespace PR7022 {
 | |
|   template <typename > 
 | |
|   struct X1
 | |
|   {
 | |
|     typedef int state_t( );
 | |
|     state_t g ;
 | |
|   };
 | |
| 
 | |
|   template <  typename U = X1<int> > struct X2
 | |
|   {
 | |
|     X2( U = U())
 | |
|     {
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   void m(void)
 | |
|   {
 | |
|     typedef X2<> X2_type;
 | |
|     X2_type c;
 | |
|   }
 | |
| }
 | |
| 
 | |
| namespace SameSignatureAfterInstantiation {
 | |
|   template<typename T> struct S {
 | |
|     void f(T *); // expected-note {{previous}}
 | |
|     void f(const T*); // expected-error {{multiple overloads of 'f' instantiate to the same signature 'void (const int *)'}}
 | |
|   };
 | |
|   S<const int> s; // expected-note {{instantiation}}
 | |
| }
 | 
