forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			101 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C++
		
	
	
	
| // 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);
 | |
|   }
 | |
| }
 |