1// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s
2
3auto f(); // expected-note {{previous}}
4int f(); // expected-error {{differ only in their return type}}
5
6auto &g();
7auto g() -> auto &;
8
9auto h() -> auto *;
10auto *h();
11
12struct Conv1 {
13  operator auto(); // expected-note {{declared here}}
14} conv1;
15int conv1a = conv1; // expected-error {{function 'operator auto' with deduced return type cannot be used before it is defined}}
16// expected-error@-1 {{no viable conversion}}
17Conv1::operator auto() { return 123; }
18int conv1b = conv1;
19int conv1c = conv1.operator auto();
20int conv1d = conv1.operator int(); // expected-error {{no member named 'operator int'}}
21
22struct Conv2 {
23  operator auto() { return 0; }  // expected-note 2{{previous}}
24  operator auto() { return 0.; } // expected-error {{cannot be redeclared}} expected-error {{redefinition of 'operator auto'}}
25};
26
27struct Conv3 {
28  operator auto() { int *p = nullptr; return p; }  // expected-note {{candidate}}
29  operator auto*() { int *p = nullptr; return p; } // expected-note {{candidate}}
30} conv3;
31int *conv3a = conv3; // expected-error {{ambiguous}}
32int *conv3b = conv3.operator auto();
33int *conv3c = conv3.operator auto*();
34
35template<typename T>
36struct Conv4 {
37  operator auto() { return T(); }
38};
39Conv4<int> conv4int;
40int conv4a = conv4int;
41int conv4b = conv4int.operator auto();
42
43auto a();
44auto a() { return 0; }
45using T = decltype(a());
46using T = int;
47auto a(); // expected-note {{previous}}
48using T = decltype(a());
49auto *a(); // expected-error {{differ only in their return type}}
50
51auto b(bool k) {
52  if (k)
53    return "hello";
54  return "goodbye";
55}
56
57auto *ptr_1() {
58  return 100; // expected-error {{cannot deduce return type 'auto *' from returned value of type 'int'}}
59}
60
61const auto &ref_1() {
62  return 0; // expected-warning {{returning reference to local temporary}}
63}
64
65auto init_list() {
66  return { 1, 2, 3 }; // expected-error {{cannot deduce return type from initializer list}}
67}
68
69auto fwd_decl(); // expected-note 2{{here}}
70
71int n = fwd_decl(); // expected-error {{function 'fwd_decl' with deduced return type cannot be used before it is defined}}
72int k = sizeof(fwd_decl()); // expected-error {{used before it is defined}}
73
74auto fac(int n) {
75  if (n <= 2)
76    return n;
77  return n * fac(n-1); // ok
78}
79
80auto fac_2(int n) { // expected-note {{declared here}}
81  if (n > 2)
82    return n * fac_2(n-1); // expected-error {{cannot be used before it is defined}}
83  return n;
84}
85
86auto void_ret() {}
87using Void = void;
88using Void = decltype(void_ret());
89
90auto &void_ret_2() {} // expected-error {{cannot deduce return type 'auto &' for function with no return statements}}
91const auto void_ret_3() {} // ok, return type 'const void' is adjusted to 'void'
92
93const auto void_ret_4() {
94  if (false)
95    return void();
96  if (false)
97    return;
98  return 0; // expected-error {{'auto' in return type deduced as 'int' here but deduced as 'void' in earlier return statement}}
99}
100
101namespace Templates {
102  template<typename T> auto f1() {
103    return T() + 1;
104  }
105  template<typename T> auto &f2(T &&v) { return v; }
106  int a = f1<int>();
107  const int &b = f2(0);
108  double d;
109  float &c = f2(0.0); // expected-error {{non-const lvalue reference to type 'float' cannot bind to a value of unrelated type 'double'}}
110
111  template<typename T> auto fwd_decl(); // expected-note {{declared here}}
112  int e = fwd_decl<int>(); // expected-error {{cannot be used before it is defined}}
113  template<typename T> auto fwd_decl() { return 0; }
114  int f = fwd_decl<int>();
115  template <typename T>
116  auto fwd_decl(); // expected-note {{candidate template ignored: could not match 'auto ()' against 'int ()'}}
117  int g = fwd_decl<char>();
118
119  auto (*p)() = f1; // expected-error {{incompatible initializer}}
120  auto (*q)() = f1<int>; // ok
121
122  typedef decltype(f2(1.2)) dbl; // expected-note {{previous}}
123  typedef float dbl; // expected-error {{typedef redefinition with different types ('float' vs 'decltype(f2(1.2))' (aka 'double &'))}}
124
125  extern template auto fwd_decl<double>();
126  int k1 = fwd_decl<double>();
127  extern template int fwd_decl<char>(); // expected-error {{does not refer to a function template}}
128  int k2 = fwd_decl<char>();
129
130  template <typename T> auto instantiate() { T::error; } // expected-error {{has no members}} \
131    // expected-note {{candidate template ignored: could not match 'auto ()' against 'void ()'}}
132  extern template auto instantiate<int>(); // ok
133  int k = instantiate<int>(); // expected-note {{in instantiation of}}
134  template<> auto instantiate<char>() {} // ok
135  template<> void instantiate<double>() {} // expected-error {{no function template matches}}
136
137  template<typename T> auto arg_single() { return 0; }
138  template<typename T> auto arg_multi() { return 0l; }
139  template<typename T> auto arg_multi(int) { return "bad"; }
140  template<typename T> struct Outer {
141    static auto arg_single() { return 0.f; }
142    static auto arg_multi() { return 0.; }
143    static auto arg_multi(int) { return "bad"; }
144  };
145  template<typename T> T &take_fn(T (*p)());
146
147  int &check1 = take_fn(arg_single); // expected-error {{no matching}} expected-note@-2 {{couldn't infer}}
148  int &check2 = take_fn(arg_single<int>);
149  int &check3 = take_fn<int>(arg_single); // expected-error {{no matching}} expected-note@-4{{no overload of 'arg_single'}}
150  int &check4 = take_fn<int>(arg_single<int>);
151  long &check5 = take_fn(arg_multi); // expected-error {{no matching}} expected-note@-6 {{couldn't infer}}
152  long &check6 = take_fn(arg_multi<int>);
153  long &check7 = take_fn<long>(arg_multi); // expected-error {{no matching}} expected-note@-8{{no overload of 'arg_multi'}}
154  long &check8 = take_fn<long>(arg_multi<int>);
155
156  float &mem_check1 = take_fn(Outer<int>::arg_single);
157  float &mem_check2 = take_fn<float>(Outer<char>::arg_single);
158  double &mem_check3 = take_fn(Outer<long>::arg_multi);
159  double &mem_check4 = take_fn<double>(Outer<double>::arg_multi);
160
161  namespace Deduce1 {
162  template <typename T> auto f() { return 0; } // expected-note {{candidate}} \
163                                               // expected-note {{candidate function has different return type ('int' expected but has 'auto')}}
164    template<typename T> void g(T(*)()); // expected-note 2{{candidate}}
165    void h() {
166      auto p = f<int>;
167      auto (*q)() = f<int>;
168      int (*r)() = f; // expected-error {{does not match}}
169      g(f<int>);
170      g<int>(f); // expected-error {{no matching function}}
171      g(f); // expected-error {{no matching function}}
172    }
173  }
174
175  namespace Deduce2 {
176  template <typename T> auto f(int) { return 0; } // expected-note {{candidate}} \
177    // expected-note {{candidate function has different return type ('int' expected but has 'auto')}}
178    template<typename T> void g(T(*)(int)); // expected-note 2{{candidate}}
179    void h() {
180      auto p = f<int>;
181      auto (*q)(int) = f<int>;
182      int (*r)(int) = f; // expected-error {{does not match}}
183      g(f<int>);
184      g<int>(f); // expected-error {{no matching function}}
185      g(f); // expected-error {{no matching function}}
186    }
187  }
188
189  namespace Deduce3 {
190    template<typename T> auto f(T) { return 0; }
191    template<typename T> void g(T(*)(int)); // expected-note {{couldn't infer}}
192    void h() {
193      auto p = f<int>;
194      auto (*q)(int) = f<int>;
195      int (*r)(int) = f; // ok
196      g(f<int>);
197      g<int>(f); // ok
198      g(f); // expected-error {{no matching function}}
199    }
200  }
201
202  namespace DeduceInDeducedReturnType {
203    template<typename T, typename U> auto f() -> auto (T::*)(U) {
204      int (T::*result)(U) = nullptr;
205      return result;
206    }
207    struct S {};
208    int (S::*(*p)())(double) = f;
209    int (S::*(*q)())(double) = f<S, double>;
210  }
211}
212
213auto fwd_decl_using();
214namespace N { using ::fwd_decl_using; }
215auto fwd_decl_using() { return 0; }
216namespace N { int k = N::fwd_decl_using(); }
217
218namespace OverloadResolutionNonTemplate {
219  auto f();
220  auto f(int); // expected-note {{here}}
221
222  int &g(int (*f)()); // expected-note {{not viable: no overload of 'f' matching 'int (*)()'}}
223  char &g(int (*f)(int)); // expected-note {{not viable: no overload of 'f' matching 'int (*)(int)'}}
224
225  int a = g(f); // expected-error {{no matching function}}
226
227  auto f() { return 0; }
228
229  // FIXME: It's not completely clear whether this should be ill-formed.
230  int &b = g(f); // expected-error {{used before it is defined}}
231
232  auto f(int) { return 0.0; }
233
234  int &c = g(f); // ok
235}
236
237namespace OverloadResolutionTemplate {
238  auto f();
239  template<typename T> auto f(T);
240
241  int &g(int (*f)()); // expected-note {{not viable: no overload of 'f' matching 'int (*)()'}} expected-note {{candidate}}
242  char &g(int (*f)(int)); // expected-note {{not viable: no overload of 'f' matching 'int (*)(int)'}} expected-note {{candidate}}
243
244  int a = g(f); // expected-error {{no matching function}}
245
246  auto f() { return 0; }
247
248  int &b = g(f); // ok (presumably), due to deduction failure forming type of 'f<int>'
249
250  template<typename T> auto f(T) { return 0; }
251
252  int &c = g(f); // expected-error {{ambiguous}}
253}
254
255namespace DefaultedMethods {
256  struct A {
257    auto operator=(const A&) = default; // expected-error {{must return 'DefaultedMethods::A &'}}
258    A &operator=(A&&); // expected-note {{previous}}
259  };
260  auto A::operator=(A&&) = default; // expected-error {{differs from the declaration in the return type}}
261}
262
263namespace Constexpr {
264  constexpr auto f1(int n) { return n; }
265  struct NonLiteral { ~NonLiteral(); } nl; // expected-note {{user-provided destructor}}
266  constexpr auto f2(int n) { return nl; } // expected-error {{return type 'Constexpr::NonLiteral' is not a literal type}}
267}
268
269// It's not really clear whether these are valid, but this matches g++.
270using size_t = decltype(sizeof(0));
271auto operator new(size_t n, const char*); // expected-error {{must return type 'void *'}}
272auto operator delete(void *, const char*); // expected-error {{must return type 'void'}}
273
274namespace Virtual {
275  struct S {
276    virtual auto f() { return 0; } // expected-error {{function with deduced return type cannot be virtual}} expected-note {{here}}
277  };
278  // Allow 'auto' anyway for error recovery.
279  struct T : S {
280    int f();
281  };
282  struct U : S {
283    auto f(); // expected-error {{different return}}
284  };
285
286  // And here's why...
287  struct V { virtual auto f(); }; // expected-error {{cannot be virtual}}
288  struct W : V { virtual auto f(); }; // expected-error {{cannot be virtual}}
289  auto V::f() { return 0; } // in tu1.cpp
290  auto W::f() { return 0.0; } // in tu2.cpp
291  W w;
292  int k1 = w.f();
293  int k2 = ((V&)w).f();
294}
295
296namespace std_examples {
297
298namespace NoReturn {
299  auto f() {}
300  void (*p)() = &f;
301
302  auto f(); // ok
303
304  auto *g() {} // expected-error {{cannot deduce return type 'auto *' for function with no return statements}}
305
306  auto h() = delete; // expected-note {{explicitly deleted}}
307  auto x = h(); // expected-error {{call to deleted}}
308}
309
310namespace UseBeforeComplete {
311  auto n = n; // expected-error {{variable 'n' declared with 'auto' type cannot appear in its own initializer}}
312  auto f(); // expected-note {{declared here}}
313  void g() { &f; } // expected-error {{function 'f' with deduced return type cannot be used before it is defined}}
314  auto sum(int i) {
315    if (i == 1)
316      return i;
317    else
318      return sum(i - 1) + i;
319  }
320}
321
322namespace Redecl {
323  auto f();
324  auto f() { return 42; }
325  auto f(); // expected-note 2{{previous}}
326  int f(); // expected-error {{functions that differ only in their return type cannot be overloaded}}
327  decltype(auto) f(); // expected-error {{cannot be overloaded}}
328
329  template <typename T> auto g(T t) { return t; } // expected-note {{candidate}} \
330                                                  // expected-note {{candidate function [with T = int]}}
331  template auto g(int);
332  template char g(char); // expected-error {{does not refer to a function}}
333  template<> auto g(double);
334
335  template<typename T> T g(T t) { return t; } // expected-note {{candidate}}
336  template char g(char);
337  template auto g(float);
338
339  void h() { return g(42); } // expected-error {{ambiguous}}
340}
341
342namespace ExplicitInstantiationDecl {
343  template<typename T> auto f(T t) { return t; }
344  extern template auto f(int);
345  int (*p)(int) = f;
346}
347namespace MemberTemplatesWithDeduction {
348  struct M {
349    template<class T> auto foo(T t) { return t; }
350    template<class T> auto operator()(T t) const { return t; }
351    template<class T> static __attribute__((unused)) int static_foo(T) {
352      return 5;
353    }
354    template<class T> operator T() { return T{}; }
355    operator auto() { return &static_foo<int>; }
356  };
357  struct N : M {
358    using M::foo;
359    using M::operator();
360    using M::static_foo;
361    using M::operator auto;
362  };
363
364  template <class T> int test() {
365    int i = T{}.foo(3);
366    T m = T{}.foo(M{});
367    int j = T{}(3);
368    M m2 = M{}(M{});
369    int k = T{}.static_foo(4);
370    int l = T::static_foo(5);
371    int l2 = T{};
372    struct X { };
373    X x = T{};
374    return 0;
375  }
376  int Minst = test<M>();
377  int Ninst = test<N>();
378
379}
380}
381