Clang Project

clang_source_code/test/SemaCXX/delete-and-function-templates.cpp
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
6template<class T, class U> struct is_same { enum { value = false }; };
7template<class T> struct is_same<T, T> { enum { value = true }; };
8
9namespace test_sfinae_and_delete {
10
11namespace ns1 {
12template<class T> double f(T) = delete; //expected-note{{candidate}}
13char f(...); //expected-note{{candidate}}
14
15static_assert(is_same<decltype(f(3)),char>::value, ""); //expected-error{{call to deleted function}} expected-error{{static_assert failed}}
16
17template<class T> decltype(f(T{})) g(T); // this one sfinae's out.
18template<class T> int *g(T);
19void foo() {
20  int *ip = g(3);
21}
22} //end ns1
23
24namespace ns2 {
25template<class T> double* f(T);
26template<> double* f(double) = delete;
27
28template<class T> decltype(f(T{})) g(T); // expected-note{{candidate}}
29template<class T> int *g(T); //expected-note{{candidate}}
30void 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
37namespace ns3 {
38template<class T> double* f(T) = delete;
39template<> double* f(double);
40
41template<class T> decltype(f(T{})) g(T); // expected-note{{candidate}}
42template<class T> int *g(T); //expected-note{{candidate}}
43
44void 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
52namespace test_explicit_specialization_of_member {
53namespace ns1 {
54template<class T> struct X {
55  int* f(T) = delete;
56}; 
57template<> int* X<int>::f(int) { }
58
59template<class T> decltype(X<T>{}.f(T{})) g(T); // expected-note{{candidate}}
60template<class T> int *g(T); //expected-note{{candidate}}
61
62void 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
69namespace ns2 {
70struct X {
71template<class T> double* f(T) = delete;
72}; 
73template<> double* X::f(int);
74
75template<class T> decltype(X{}.f(T{})) g(T); // expected-note{{candidate}}
76template<class T> int *g(T); //expected-note{{candidate}}
77
78void 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
85namespace ns3 {
86template<class T> struct X {
87  template<class U> double *f1(U, T) = delete;
88  template<class U> double *f2(U, T) = delete;
89};
90template<> template<> double* X<int>::f1(int, int);
91template<> template<class U> double* X<int>::f2(U, int);
92
93template<class T, class U> decltype(X<T>{}.f1(U{}, T{})) g1(U, T); // expected-note{{candidate}}
94template<class T, class U> int *g1(U, T); //expected-note{{candidate}}
95
96template<class T, class U> decltype(X<T>{}.f2(U{}, T{})) g2(U, T); // expected-note2{{candidate}}
97template<class T, class U> int *g2(U, T); //expected-note2{{candidate}}
98
99
100void 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
116namespace ns4 {
117template < typename T> T* foo (T);
118template <> int* foo(int) = delete;
119template <> int* foo(int); //expected-note{{candidate}}
120
121int *IP = foo(2); //expected-error{{deleted}}
122double *DP = foo(3.14);
123} //end ns4
124
125namespace ns5 {
126template < typename T> T* foo (T);
127template <> int* foo(int); //expected-note{{previous}}
128template <> 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