Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s
      2 
      3 auto f(); // expected-note {{previous}}
      4 int f(); // expected-error {{differ only in their return type}}
      5 
      6 auto &g();
      7 auto g() -> auto &;
      8 
      9 auto h() -> auto *;
     10 auto *h();
     11 
     12 struct Conv1 {
     13   operator auto(); // expected-note {{declared here}}
     14 } conv1;
     15 int 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}}
     17 Conv1::operator auto() { return 123; }
     18 int conv1b = conv1;
     19 int conv1c = conv1.operator auto();
     20 int conv1d = conv1.operator int(); // expected-error {{no member named 'operator int'}}
     21 
     22 struct 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 
     27 struct 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;
     31 int *conv3a = conv3; // expected-error {{ambiguous}}
     32 int *conv3b = conv3.operator auto();
     33 int *conv3c = conv3.operator auto*();
     34 
     35 template<typename T>
     36 struct Conv4 {
     37   operator auto() { return T(); }
     38 };
     39 Conv4<int> conv4int;
     40 int conv4a = conv4int;
     41 int conv4b = conv4int.operator auto();
     42 
     43 auto a();
     44 auto a() { return 0; }
     45 using T = decltype(a());
     46 using T = int;
     47 auto a(); // expected-note {{previous}}
     48 using T = decltype(a());
     49 auto *a(); // expected-error {{differ only in their return type}}
     50 
     51 auto b(bool k) {
     52   if (k)
     53     return "hello";
     54   return "goodbye";
     55 }
     56 
     57 auto *ptr_1() {
     58   return 100; // expected-error {{cannot deduce return type 'auto *' from returned value of type 'int'}}
     59 }
     60 
     61 const auto &ref_1() {
     62   return 0; // expected-warning {{returning reference to local temporary}}
     63 }
     64 
     65 auto init_list() {
     66   return { 1, 2, 3 }; // expected-error {{cannot deduce return type from initializer list}}
     67 }
     68 
     69 auto fwd_decl(); // expected-note 2{{here}}
     70 
     71 int n = fwd_decl(); // expected-error {{function 'fwd_decl' with deduced return type cannot be used before it is defined}}
     72 int k = sizeof(fwd_decl()); // expected-error {{used before it is defined}}
     73 
     74 auto fac(int n) {
     75   if (n <= 2)
     76     return n;
     77   return n * fac(n-1); // ok
     78 }
     79 
     80 auto 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 
     86 auto void_ret() {}
     87 using Void = void;
     88 using Void = decltype(void_ret());
     89 
     90 auto &void_ret_2() {} // expected-error {{cannot deduce return type 'auto &' for function with no return statements}}
     91 const auto void_ret_3() {} // ok, return type 'const void' is adjusted to 'void'
     92 
     93 const 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 
    101 namespace 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 
    213 auto fwd_decl_using();
    214 namespace N { using ::fwd_decl_using; }
    215 auto fwd_decl_using() { return 0; }
    216 namespace N { int k = N::fwd_decl_using(); }
    217 
    218 namespace 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 
    237 namespace 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 
    255 namespace 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 
    263 namespace 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++.
    270 using size_t = decltype(sizeof(0));
    271 auto operator new(size_t n, const char*); // expected-error {{must return type 'void *'}}
    272 auto operator delete(void *, const char*); // expected-error {{must return type 'void'}}
    273 
    274 namespace 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 
    296 namespace std_examples {
    297 
    298 namespace 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 
    310 namespace 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 
    322 namespace 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 
    342 namespace ExplicitInstantiationDecl {
    343   template<typename T> auto f(T t) { return t; }
    344   extern template auto f(int);
    345   int (*p)(int) = f;
    346 }
    347 namespace 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