forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			489 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			489 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
| // RUN: %clang_cc1 -verify -std=c++11 %s
 | |
| // RUN: %clang_cc1 -verify -std=c++11 -fdelayed-template-parsing %s
 | |
| 
 | |
| template<typename T>
 | |
| void f0() {
 | |
|   struct X;
 | |
|   typedef struct Y {
 | |
|     T (X::* f1())(int) { return 0; }
 | |
|   } Y2;
 | |
| 
 | |
|   Y2 y = Y();
 | |
| }
 | |
| 
 | |
| template void f0<int>();
 | |
| 
 | |
| // PR5764
 | |
| namespace PR5764 {
 | |
|   struct X {
 | |
|     template <typename T>
 | |
|     void Bar() {
 | |
|       typedef T ValueType;
 | |
|       struct Y {
 | |
|         Y() { V = ValueType(); }
 | |
| 
 | |
|         ValueType V;
 | |
|       };
 | |
| 
 | |
|       Y y;
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   void test(X x) {
 | |
|     x.Bar<int>();
 | |
|   }
 | |
| }
 | |
| 
 | |
| // Instantiation of local classes with virtual functions.
 | |
| namespace local_class_with_virtual_functions {
 | |
|   template <typename T> struct X { };
 | |
|   template <typename T> struct Y { };
 | |
| 
 | |
|   template <typename T>
 | |
|   void f() {
 | |
|     struct Z : public X<Y<T>*> {
 | |
|       virtual void g(Y<T>* y) { }
 | |
|       void g2(int x) {(void)x;}
 | |
|     };
 | |
|     Z z;
 | |
|     (void)z;
 | |
|   }
 | |
| 
 | |
|   struct S { };
 | |
|   void test() { f<S>(); }
 | |
| }
 | |
| 
 | |
| namespace PR8801 {
 | |
|   template<typename T>
 | |
|   void foo() {
 | |
|     class X;
 | |
|     typedef int (X::*pmf_type)();
 | |
|     class X : public T { };
 | |
|     
 | |
|     pmf_type pmf = &T::foo;
 | |
|   }
 | |
| 
 | |
|   struct Y { int foo(); };
 | |
| 
 | |
|   template void foo<Y>();
 | |
| }
 | |
| 
 | |
| namespace TemplatePacksAndLambdas {
 | |
|   template <typename ...T> int g(T...);
 | |
|   struct S {
 | |
|     template <typename ...T> static void f(int f = g([]{ static T t; return ++t; }()...)) {}
 | |
|   };
 | |
|   void h() { S::f<int, int, int>(); }
 | |
| }
 | |
| 
 | |
| namespace PR9685 {
 | |
|   template <class Thing> void forEach(Thing t) { t.func(); }
 | |
| 
 | |
|   template <typename T> void doIt() {
 | |
|     struct Functor {
 | |
|       void func() { (void)i; }
 | |
|       int i;
 | |
|     };
 | |
| 
 | |
|     forEach(Functor());
 | |
|   }
 | |
| 
 | |
|   void call() {
 | |
|     doIt<int>();
 | |
|   }
 | |
| }
 | |
| 
 | |
| namespace PR12702 {
 | |
|   struct S {
 | |
|     template <typename F> bool apply(F f) { return f(); }
 | |
|   };
 | |
| 
 | |
|   template <typename> struct T {
 | |
|     void foo() {
 | |
|       struct F {
 | |
|         int x;
 | |
| 
 | |
|         bool operator()() { return x == 0; }
 | |
|       };
 | |
| 
 | |
|       S().apply(F());
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   void call() { T<int>().foo(); }
 | |
| }
 | |
| 
 | |
| namespace PR17139 {
 | |
|   template <class T> void foo(const T &t) { t.foo(); }
 | |
| 
 | |
|   template <class F> void bar(F *f) {
 | |
|     struct B {
 | |
|       F *fn;
 | |
|       void foo() const { fn(); }
 | |
|     } b = { f };
 | |
|     foo(b);
 | |
|   }
 | |
| 
 | |
|   void go() {}
 | |
| 
 | |
|   void test() { bar(go); }
 | |
| }
 | |
| 
 | |
| namespace PR17740 {
 | |
| class C {
 | |
| public:
 | |
|   template <typename T> static void foo(T function);
 | |
|   template <typename T> static void bar(T function);
 | |
|   template <typename T> static void func(T function);
 | |
| };
 | |
| 
 | |
| template <typename T> void C::foo(T function) { function(); }
 | |
| 
 | |
| template <typename T> void C::bar(T function) {
 | |
|   foo([&function]() { function(); });
 | |
| }
 | |
| 
 | |
| template <typename T> void C::func(T function) {
 | |
|   struct Struct {
 | |
|     T mFunction;
 | |
| 
 | |
|     Struct(T function) : mFunction(function) {};
 | |
| 
 | |
|     void operator()() {
 | |
|       mFunction();
 | |
|     };
 | |
|   };
 | |
| 
 | |
|   bar(Struct(function));
 | |
| }
 | |
| 
 | |
| void call() {
 | |
|   C::func([]() {});
 | |
| }
 | |
| }
 | |
| 
 | |
| namespace PR14373 {
 | |
|   struct function {
 | |
|     template <typename _Functor> function(_Functor __f) { __f(); }
 | |
|   };
 | |
|   template <typename Func> function exec_func(Func f) {
 | |
|     struct functor {
 | |
|       functor(Func f) : func(f) {}
 | |
|       void operator()() const { func(); }
 | |
|       Func func;
 | |
|     };
 | |
|     return functor(f);
 | |
|   }
 | |
|   struct Type {
 | |
|     void operator()() const {}
 | |
|   };
 | |
|   int call() {
 | |
|     exec_func(Type());
 | |
|     return 0;
 | |
|   }
 | |
| }
 | |
| 
 | |
| namespace PR18907 {
 | |
| template <typename>
 | |
| class C : public C<int> {}; // expected-error{{within its own definition}}
 | |
| 
 | |
| template <typename X>
 | |
| void F() {
 | |
|   struct A : C<X> {};
 | |
| }
 | |
| 
 | |
| struct B {
 | |
|   void f() { F<int>(); }
 | |
| };
 | |
| }
 | |
| 
 | |
| namespace PR23194 {
 | |
|   struct X {
 | |
|     int operator()() const { return 0; }
 | |
|   };
 | |
|   struct Y {
 | |
|     Y(int) {}
 | |
|   };
 | |
|   template <bool = true> int make_seed_pair() noexcept {
 | |
|     struct state_t {
 | |
|       X x;
 | |
|       Y y{x()};
 | |
|     };
 | |
|     return 0;
 | |
|   }
 | |
|   int func() {
 | |
|     return make_seed_pair();
 | |
|   }
 | |
| }
 | |
| 
 | |
| namespace PR18653 {
 | |
|   // Forward declarations
 | |
| 
 | |
|   template<typename T> void f1() {
 | |
|     void g1(struct x1);
 | |
|     struct x1 {};
 | |
|   }
 | |
|   template void f1<int>();
 | |
| 
 | |
|   template<typename T> void f1a() {
 | |
|     void g1(union x1);
 | |
|     union x1 {};
 | |
|   }
 | |
|   template void f1a<int>();
 | |
| 
 | |
|   template<typename T> void f2() {
 | |
|     void g2(enum x2);  // expected-error{{ISO C++ forbids forward references to 'enum' types}}
 | |
|     enum x2 { nothing };
 | |
|   }
 | |
|   template void f2<int>();
 | |
| 
 | |
|   template<typename T> void f3() {
 | |
|     void g3(enum class x3);
 | |
|     enum class x3 { nothing };
 | |
|   }
 | |
|   template void f3<int>();
 | |
| 
 | |
| 
 | |
|   template<typename T> void f4() {
 | |
|     void g4(struct x4 {} x);  // expected-error{{'x4' cannot be defined in a parameter type}}
 | |
|   }
 | |
|   template void f4<int>();
 | |
| 
 | |
|   template<typename T> void f4a() {
 | |
|     void g4(union x4 {} x);  // expected-error{{'x4' cannot be defined in a parameter type}}
 | |
|   }
 | |
|   template void f4a<int>();
 | |
| 
 | |
| 
 | |
|   template <class T> void f();
 | |
|   template <class T> struct S1 {
 | |
|     void m() {
 | |
|       f<class newclass>();
 | |
|       f<union newunion>();
 | |
|     }
 | |
|   };
 | |
|   template struct S1<int>;
 | |
| 
 | |
|   template <class T> struct S2 {
 | |
|     void m() {
 | |
|       f<enum new_enum>();  // expected-error{{ISO C++ forbids forward references to 'enum' types}}
 | |
|     }
 | |
|   };
 | |
|   template struct S2<int>;
 | |
| 
 | |
|   template <class T> struct S3 {
 | |
|     void m() {
 | |
|       f<enum class new_enum>();
 | |
|     }
 | |
|   };
 | |
|   template struct S3<int>;
 | |
| 
 | |
|   template <class T> struct S4 {
 | |
|     struct local {};
 | |
|     void m() {
 | |
|       f<local>();
 | |
|     }
 | |
|   };
 | |
|   template struct S4<int>;
 | |
| 
 | |
|   template <class T> struct S4a {
 | |
|     union local {};
 | |
|     void m() {
 | |
|       f<local>();
 | |
|     }
 | |
|   };
 | |
|   template struct S4a<int>;
 | |
| 
 | |
|   template <class T> struct S5 {
 | |
|     enum local { nothing };
 | |
|     void m() {
 | |
|       f<local>();
 | |
|     }
 | |
|   };
 | |
|   template struct S5<int>;
 | |
| 
 | |
|   template <class T> struct S7 {
 | |
|     enum class local { nothing };
 | |
|     void m() {
 | |
|       f<local>();
 | |
|     }
 | |
|   };
 | |
|   template struct S7<int>;
 | |
| 
 | |
| 
 | |
|   template <class T> void fff(T *x);
 | |
|   template <class T> struct S01 {
 | |
|     struct local { };
 | |
|     void m() {
 | |
|       local x;
 | |
|       fff(&x);
 | |
|     }
 | |
|   };
 | |
|   template struct S01<int>;
 | |
| 
 | |
|   template <class T> struct S01a {
 | |
|     union local { };
 | |
|     void m() {
 | |
|       local x;
 | |
|       fff(&x);
 | |
|     }
 | |
|   };
 | |
|   template struct S01a<int>;
 | |
| 
 | |
|   template <class T> struct S02 {
 | |
|     enum local { nothing };
 | |
|     void m() {
 | |
|       local x;
 | |
|       fff(&x);
 | |
|     }
 | |
|   };
 | |
|   template struct S02<int>;
 | |
| 
 | |
|   template <class T> struct S03 {
 | |
|     enum class local { nothing };
 | |
|     void m() {
 | |
|       local x;
 | |
|       fff(&x);
 | |
|     }
 | |
|   };
 | |
|   template struct S03<int>;
 | |
| 
 | |
| 
 | |
|   template <class T> struct S04 {
 | |
|     void m() {
 | |
|       struct { } x;
 | |
|       fff(&x);
 | |
|     }
 | |
|   };
 | |
|   template struct S04<int>;
 | |
| 
 | |
|   template <class T> struct S04a {
 | |
|     void m() {
 | |
|       union { } x;
 | |
|       fff(&x);
 | |
|     }
 | |
|   };
 | |
|   template struct S04a<int>;
 | |
| 
 | |
|   template <class T> struct S05 {
 | |
|     void m() {
 | |
|       enum { nothing } x;
 | |
|       fff(&x);
 | |
|     }
 | |
|   };
 | |
|   template struct S05<int>;
 | |
| 
 | |
|   template <class T> struct S06 {
 | |
|     void m() {
 | |
|       class { virtual void mmm() {} } x;
 | |
|       fff(&x);
 | |
|     }
 | |
|   };
 | |
|   template struct S06<int>;
 | |
| }
 | |
| 
 | |
| namespace PR20625 {
 | |
| template <typename T>
 | |
| void f() {
 | |
|   struct N {
 | |
|     static constexpr int get() { return 42; }
 | |
|   };
 | |
|   constexpr int n = N::get();
 | |
|   static_assert(n == 42, "n == 42");
 | |
| }
 | |
| 
 | |
| void g() { f<void>(); }
 | |
| }
 | |
| 
 | |
| 
 | |
| namespace PR21332 {
 | |
|   template<typename T> void f1() {
 | |
|     struct S {  // expected-note{{in instantiation of member class 'S' requested here}}
 | |
|       void g1(int n = T::error);  // expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
 | |
|     };
 | |
|   }
 | |
|   template void f1<int>();  // expected-note{{in instantiation of function template specialization 'PR21332::f1<int>' requested here}}
 | |
| 
 | |
|   template<typename T> void f2() {
 | |
|     struct S {  // expected-note{{in instantiation of member class 'S' requested here}}
 | |
|       void g2() noexcept(T::error);  // expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
 | |
|     };
 | |
|   }
 | |
|   template void f2<int>();  // expected-note{{in instantiation of function template specialization 'PR21332::f2<int>' requested here}}
 | |
| 
 | |
|   template<typename T> void f3() {
 | |
|     enum S {
 | |
|       val = T::error;  // expected-error{{expected '}' or ','}} expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
 | |
|     };
 | |
|   }
 | |
|   template void f3<int>();  //expected-note{{in instantiation of function template specialization 'PR21332::f3<int>' requested here}}
 | |
| 
 | |
|   template<typename T> void f4() {
 | |
|     enum class S {
 | |
|       val = T::error;  // expected-error{{expected '}' or ','}} expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
 | |
|     };
 | |
|   }
 | |
|   template void f4<int>();  // expected-note{{in instantiation of function template specialization 'PR21332::f4<int>' requested here}}
 | |
| 
 | |
|   template<typename T> void f5() {
 | |
|     class S {  // expected-note {{in instantiation of default member initializer 'PR21332::f5()::S::val' requested here}}
 | |
|       int val = T::error;  // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
 | |
|      };
 | |
|   }
 | |
|   template void f5<int>();  // expected-note {{in instantiation of function template specialization 'PR21332::f5<int>' requested here}}
 | |
| 
 | |
|   template<typename T> void f6() {
 | |
|     class S {  // expected-note {{in instantiation of member function 'PR21332::f6()::S::get' requested here}}
 | |
|       void get() {
 | |
|         class S2 {  // expected-note {{in instantiation of member class 'S2' requested here}}
 | |
|           void g1(int n = T::error);  // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
 | |
|         };
 | |
|       }
 | |
|     };
 | |
|   }
 | |
|   template void f6<int>();  // expected-note{{in instantiation of function template specialization 'PR21332::f6<int>' requested here}}
 | |
| 
 | |
|   template<typename T> void f7() {
 | |
|     struct S { void g() noexcept(undefined_val); };  // expected-error{{use of undeclared identifier 'undefined_val'}}
 | |
|   }
 | |
|   template void f7<int>();
 | |
| }
 | |
| 
 | |
| // rdar://23721638: Ensure that we correctly perform implicit
 | |
| // conversions when instantiating the default arguments of local functions.
 | |
| namespace rdar23721638 {
 | |
|   struct A {
 | |
|     A(const char *) = delete;  // expected-note 2 {{explicitly marked deleted here}}
 | |
|   };
 | |
| 
 | |
|   template <typename T> void foo() {
 | |
|     struct Inner { // expected-note {{in instantiation}}
 | |
|       void operator()(T a = "") {} // expected-error {{conversion function from 'const char [1]' to 'rdar23721638::A' invokes a deleted function}}
 | |
|       // expected-note@-1 {{passing argument to parameter 'a' here}}
 | |
|       // expected-note@-2 {{candidate function not viable}}
 | |
|     };
 | |
|     Inner()(); // expected-error {{no matching function}}
 | |
|   }
 | |
|   template void foo<A>(); // expected-note 2 {{in instantiation}}
 | |
| 
 | |
|   template <typename T> void bar() {
 | |
|     auto lambda = [](T a = "") {}; // expected-error {{conversion function from 'const char [1]' to 'rdar23721638::A' invokes a deleted function}}
 | |
|       // expected-note@-1 {{passing argument to parameter 'a' here}}
 | |
|       // expected-note@-2 {{candidate function not viable}}
 | |
|       // expected-note@-3 {{conversion candidate of type}}
 | |
|     lambda(); // expected-error {{no matching function}}
 | |
|   }
 | |
|   template void bar<A>(); // expected-note {{in instantiation}}
 | |
| }
 | |
| 
 | |
| namespace anon_union_default_member_init {
 | |
|   template<typename T> void f() {
 | |
|     struct S {
 | |
|       union {
 | |
|         int i = 0;
 | |
|       };
 | |
|     };
 | |
|   }
 | |
|   void g() { f<int>(); }
 | |
| }
 |