Home | History | Annotate | Download | only in temp.deduct.call
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 
      3 namespace test0 {
      4   template<class T> void apply(T x, void (*f)(T)) { f(x); } // expected-note 2 {{candidate template ignored: deduced conflicting types for parameter 'T'}}\
      5   // expected-note {{no overload of 'temp2' matching 'void (*)(int)'}}
      6 
      7   template<class A> void temp(A);
      8   void test0() {
      9     // okay: deduce T=int from first argument, A=int during overload
     10     apply(0, &temp);
     11     apply(0, &temp<>);
     12 
     13     // okay: deduce T=int from first and second arguments
     14     apply(0, &temp<int>);
     15 
     16     // deduction failure: T=int from first, T=long from second
     17     apply(0, &temp<long>); // expected-error {{no matching function for call to 'apply'}}
     18   }
     19 
     20   void over(int);
     21   int over(long);
     22 
     23   void test1() {
     24     // okay: deductions match
     25     apply(0, &over);
     26 
     27     // deduction failure: deduced T=long from first argument, T=int from second
     28     apply(0L, &over); // expected-error {{no matching function for call to 'apply'}}
     29   }
     30 
     31   void over(short);
     32 
     33   void test2() {
     34     // deduce T=int from first arg, second arg is undeduced context,
     35     // pick correct overload of 'over' during overload resolution for 'apply'
     36     apply(0, &over);
     37   }
     38 
     39   template<class A, class B> B temp2(A);
     40   void test3() {
     41     // deduce T=int from first arg, A=int B=void during overload resolution
     42     apply(0, &temp2);
     43     apply(0, &temp2<>);
     44     apply(0, &temp2<int>);
     45 
     46     // overload failure
     47     apply(0, &temp2<long>); // expected-error {{no matching function for call to 'apply'}}
     48   }
     49 }
     50 
     51 namespace test1 {
     52   template<class T> void invoke(void (*f)(T)) { f(T()); } // expected-note 6 {{couldn't infer template argument}} \
     53   // expected-note {{candidate template ignored: couldn't infer template argument 'T'}}
     54 
     55   template<class T> void temp(T);
     56   void test0() {
     57     // deduction failure: overload has template => undeduced context
     58     invoke(&temp); // expected-error {{no matching function for call to 'invoke'}}
     59     invoke(&temp<>); // expected-error {{no matching function for call to 'invoke'}}
     60 
     61     // okay: full template-id
     62     invoke(&temp<int>);
     63   }
     64 
     65   void over(int);
     66   int over(long);
     67 
     68   void test1() {
     69     // okay: only one overload matches
     70     invoke(&over);
     71   }
     72 
     73   void over(short);
     74 
     75   void test2() {
     76     // deduction failure: overload has multiple matches => undeduced context
     77     invoke(&over); // expected-error {{no matching function for call to 'invoke'}}
     78   }
     79 
     80   template<class A, class B> B temp2(A);
     81   void test3() {
     82     // deduction failure: overload has template => undeduced context
     83     // (even though partial application temp2<int> could in theory
     84     // let us infer T=int)
     85     invoke(&temp2); // expected-error {{no matching function for call to 'invoke'}}
     86     invoke(&temp2<>); // expected-error {{no matching function for call to 'invoke'}}
     87     invoke(&temp2<int>); // expected-error {{no matching function for call to 'invoke'}}
     88 
     89     // okay: full template-id
     90     invoke(&temp2<int, void>);
     91 
     92     // overload failure
     93     invoke(&temp2<int, int>); // expected-error {{no matching function for call to 'invoke'}}
     94   }
     95 }
     96 
     97 namespace rdar8360106 {
     98   template<typename R, typename T> void f0(R (*)(T), T);
     99   template<typename R, typename T> void f1(R (&)(T) , T); // expected-note{{candidate template ignored: couldn't infer template argument 'R'}}
    100   template<typename R, typename T> void f2(R (* const&)(T), T); // expected-note{{candidate template ignored: couldn't infer template argument 'R'}}
    101 
    102   int g(int);
    103   int g(int, int);
    104 
    105   void h() {
    106     f0(g, 1);
    107     f0(&g, 1);
    108     f1(g, 1);
    109     f1(&g, 1); // expected-error{{no matching function for call to 'f1'}}
    110     f2(g, 1); // expected-error{{no matching function for call to 'f2'}}
    111     f2(&g, 1);
    112   }
    113 }
    114 
    115 namespace PR11713 {
    116   template<typename T>
    117   int f(int, int, int);
    118 
    119   template<typename T>
    120   float f(float, float);
    121 
    122   template<typename R, typename B1, typename B2, typename A1, typename A2>
    123   R& g(R (*)(B1, B2), A1, A2);
    124 
    125   void h() {
    126     float &fr = g(f<int>, 1, 2);
    127   }
    128 }
    129