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