160e141e1f87211ca831de6821003d80fe20a06f3Richard Smith// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y
2a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-c++1y-extensions
3a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith
4a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith// FIXME: This is in p11 (?) in C++1y.
5a2c3646c35dd09d21b74826240aa916545b1873fRichard Smithvoid f() {
6a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  decltype(auto) a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}}
7a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  if (decltype(auto) b = b) {} // expected-error {{variable 'b' declared with 'auto' type cannot appear in its own initializer}}
8a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  decltype(auto) c = ({ decltype(auto) d = c; 0; }); // expected-error {{variable 'c' declared with 'auto' type cannot appear in its own initializer}}
9a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith}
10a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith
11a2c3646c35dd09d21b74826240aa916545b1873fRichard Smithvoid g() {
12a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  decltype(auto) a; // expected-error{{declaration of variable 'a' with type 'decltype(auto)' requires an initializer}}
13a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith
14a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  decltype(auto) *b; // expected-error{{cannot form pointer to 'decltype(auto)'}} expected-error{{declaration of variable 'b' with type 'decltype(auto) *' requires an initializer}}
15a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith
16a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  if (decltype(auto) b) {} // expected-error {{must have an initializer}}
17a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  for (;decltype(auto) b;) {} // expected-error {{must have an initializer}}
18a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  while (decltype(auto) b) {} // expected-error {{must have an initializer}}
19a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  if (decltype(auto) b = true) { (void)b; }
20a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith}
21a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith
22a2c3646c35dd09d21b74826240aa916545b1873fRichard Smithdecltype(auto) n(1,2,3); // expected-error{{initializer for variable 'n' with type 'decltype(auto)' contains multiple expressions}}
23a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith
24a2c3646c35dd09d21b74826240aa916545b1873fRichard Smithnamespace N
25a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith{
26a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  // All of these are references, because a string literal is an lvalue.
27a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  decltype(auto) a = "const char (&)[19]", b = a, c = (a);
28a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith}
29a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith
30a2c3646c35dd09d21b74826240aa916545b1873fRichard Smithvoid h() {
31a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  decltype(auto) b = 42ULL;
32a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith
33a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  for (decltype(auto) c = 0; c < b; ++c) {
34a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  }
35a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith}
36a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith
37a2c3646c35dd09d21b74826240aa916545b1873fRichard Smithtemplate<typename T, typename U> struct same;
38a2c3646c35dd09d21b74826240aa916545b1873fRichard Smithtemplate<typename T> struct same<T, T> {};
39a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith
40a2c3646c35dd09d21b74826240aa916545b1873fRichard Smithvoid i() {
41a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  decltype(auto) x = 5;
42a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  decltype(auto) int r; // expected-error {{cannot combine with previous 'decltype(auto)' declaration specifier}} expected-error {{requires an initializer}}
43a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith}
4460e141e1f87211ca831de6821003d80fe20a06f3Richard Smith
4560e141e1f87211ca831de6821003d80fe20a06f3Richard Smithnamespace p3_example {
4660e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  template<typename T, typename U> struct is_same_impl {
4760e141e1f87211ca831de6821003d80fe20a06f3Richard Smith    static const bool value = false;
4860e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  };
4960e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  template<typename T> struct is_same_impl<T, T> {
5060e141e1f87211ca831de6821003d80fe20a06f3Richard Smith    static const bool value = true;
5160e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  };
5260e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  template<typename T, typename U> constexpr bool is_same() {
5360e141e1f87211ca831de6821003d80fe20a06f3Richard Smith    return is_same_impl<T,U>::value;
5460e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  }
5560e141e1f87211ca831de6821003d80fe20a06f3Richard Smith
5660e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  auto x = 5;
5760e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  const auto *v = &x, u = 6;
5860e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  static auto y = 0.0;
5960e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  auto int r;  // expected-warning {{storage class}} expected-error {{file-scope}}
6060e141e1f87211ca831de6821003d80fe20a06f3Richard Smith
6160e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  static_assert(is_same<decltype(x), int>(), "");
6260e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  static_assert(is_same<decltype(v), const int*>(), "");
6360e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  static_assert(is_same<decltype(u), const int>(), "");
6460e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  static_assert(is_same<decltype(y), double>(), "");
6560e141e1f87211ca831de6821003d80fe20a06f3Richard Smith
6660e141e1f87211ca831de6821003d80fe20a06f3Richard Smith#ifdef CXX1Y
6760e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  auto f() -> int;
6860e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  auto g() { return 0.0; }
6960e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  auto h();
7060e141e1f87211ca831de6821003d80fe20a06f3Richard Smith
7160e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  static_assert(is_same<decltype(f), int()>(), "");
7260e141e1f87211ca831de6821003d80fe20a06f3Richard Smith  static_assert(is_same<decltype(g), double()>(), "");
7360e141e1f87211ca831de6821003d80fe20a06f3Richard Smith#endif
7460e141e1f87211ca831de6821003d80fe20a06f3Richard Smith}
75