Home | History | Annotate | Download | only in SemaCXX
      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);
     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}}
     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 
     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 };
     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 
     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 
     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 
    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