1 // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only  -emit-llvm-only %s
2 // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only  -fdelayed-template-parsing %s
3 // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only  -fms-extensions %s
4 // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only  -fdelayed-template-parsing -fms-extensions %s
5 
6 template<class T, class U> struct is_same { enum { value = false }; };
7 template<class T> struct is_same<T, T> { enum { value = true }; };
8 
9 namespace test_sfinae_and_delete {
10 
11 namespace ns1 {
12 template<class T> double f(T) = delete; //expected-note{{candidate}}
13 char f(...); //expected-note{{candidate}}
14 
15 static_assert(is_same<decltype(f(3)),char>::value, ""); //expected-error{{call to deleted function}} expected-error{{static_assert failed}}
16 
17 template<class T> decltype(f(T{})) g(T); // this one sfinae's out.
18 template<class T> int *g(T);
foo()19 void foo() {
20   int *ip = g(3);
21 }
22 } //end ns1
23 
24 namespace ns2 {
25 template<class T> double* f(T);
26 template<> double* f(double) = delete;
27 
28 template<class T> decltype(f(T{})) g(T); // expected-note{{candidate}}
29 template<class T> int *g(T); //expected-note{{candidate}}
foo()30 void foo() {
31   double *dp = g(3); //expected-error{{ambiguous}}
32   int *ip = g(3.14); // this is OK - because the explicit specialization is deleted and sfinae's out one of the template candidates
33 }
34 
35 } // end ns2
36 
37 namespace ns3 {
38 template<class T> double* f(T) = delete;
39 template<> double* f(double);
40 
41 template<class T> decltype(f(T{})) g(T); // expected-note{{candidate}}
42 template<class T> int *g(T); //expected-note{{candidate}}
43 
foo()44 void foo() {
45   int *dp = g(3); // this is OK - because the non-double specializations are deleted and sfinae's out one of the template candidates
46   double *ip = g(3.14); //expected-error{{ambiguous}}
47 }
48 
49 } // end ns3
50 } // end ns test_sfinae_and_delete
51 
52 namespace test_explicit_specialization_of_member {
53 namespace ns1 {
54 template<class T> struct X {
55   int* f(T) = delete;
56 };
f(int)57 template<> int* X<int>::f(int) { }
58 
59 template<class T> decltype(X<T>{}.f(T{})) g(T); // expected-note{{candidate}}
60 template<class T> int *g(T); //expected-note{{candidate}}
61 
foo()62 void foo() {
63   int *ip2 = g(3.14); // this is OK - because the non-int specializations are deleted and sfinae's out one of the template candidates
64   int *ip = g(3); //expected-error{{ambiguous}}
65 }
66 
67 } // end ns1
68 
69 namespace ns2 {
70 struct X {
71 template<class T> double* f(T) = delete;
72 };
73 template<> double* X::f(int);
74 
75 template<class T> decltype(X{}.f(T{})) g(T); // expected-note{{candidate}}
76 template<class T> int *g(T); //expected-note{{candidate}}
77 
foo()78 void foo() {
79   int *ip2 = g(3.14); // this is OK - because the non-int specializations are deleted and sfinae's out one of the template candidates
80   int *ip = g(3); //expected-error{{ambiguous}}
81 }
82 
83 } // end ns2
84 
85 namespace ns3 {
86 template<class T> struct X {
87   template<class U> double *f1(U, T) = delete;
88   template<class U> double *f2(U, T) = delete;
89 };
90 template<> template<> double* X<int>::f1(int, int);
91 template<> template<class U> double* X<int>::f2(U, int);
92 
93 template<class T, class U> decltype(X<T>{}.f1(U{}, T{})) g1(U, T); // expected-note{{candidate}}
94 template<class T, class U> int *g1(U, T); //expected-note{{candidate}}
95 
96 template<class T, class U> decltype(X<T>{}.f2(U{}, T{})) g2(U, T); // expected-note2{{candidate}}
97 template<class T, class U> int *g2(U, T); //expected-note2{{candidate}}
98 
99 
foo()100 void foo() {
101   int *ip2 = g1(3.14, 3); // this is OK - because the non-int specializations are deleted and sfinae's out one of the template candidates
102   int *ip = g1(3, 3); //expected-error{{ambiguous}}
103   {
104    int *ip3 = g2(3.14, 3); //expected-error{{ambiguous}}
105    int *ip4 = g2(3, 3); //expected-error{{ambiguous}}
106   }
107   {
108    int *ip3 = g2(3.14, 3.14);
109    int *ip4 = g2(3, 3.14);
110   }
111 }
112 
113 
114 } // end ns3
115 
116 namespace ns4 {
117 template < typename T> T* foo (T);
118 template <> int* foo(int) = delete;
119 template <> int* foo(int); //expected-note{{candidate}}
120 
121 int *IP = foo(2); //expected-error{{deleted}}
122 double *DP = foo(3.14);
123 } //end ns4
124 
125 namespace ns5 {
126 template < typename T> T* foo (T);
127 template <> int* foo(int); //expected-note{{previous}}
128 template <> int* foo(int) = delete; //expected-error{{deleted definition must be first declaration}}
129 
130 } //end ns5
131 
132 
133 } // end test_explicit_specializations_and_delete
134