1a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith// RUN: %clang_cc1 -verify -std=c++1y %s
2a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith
3a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith// Example from the standard.
4a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smithnamespace X {
5a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  void p() {
6a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    q(); // expected-error {{undeclared}}
7a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    extern void q();
8a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  }
9a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  void middle() {
10a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    q(); // expected-error {{undeclared}}
11a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  }
12a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  void q() { /*...*/ }
13a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  void bottom() {
14a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    q();
15a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  }
16a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith}
17a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smithint q();
18a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith
19a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smithnamespace Test1 {
20a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  void f() {
21a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    extern int a; // expected-note {{previous}}
22a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    int g(void); // expected-note {{previous}}
23a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  }
24a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  double a; // expected-error {{different type: 'double' vs 'int'}}
25a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  double g(); // expected-error {{differ only in their return type}}
26a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith}
27a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith
28a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smithnamespace Test2 {
29a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  void f() {
30a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    extern int a; // expected-note {{previous}}
31a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    int g(void); // expected-note {{previous}}
32a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  }
33a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  void h() {
34a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    extern double a; // expected-error {{different type: 'double' vs 'int'}}
35a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    double g(void); // expected-error {{differ only in their return type}}
36a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  }
37a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith}
38a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith
39a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smithnamespace Test3 {
40a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  constexpr void (*f())() {
41a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    void h();
42a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    return &h;
43a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  }
44a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  constexpr void (*g())() {
45a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    void h();
46a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    return &h;
47a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  }
48a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  static_assert(f() == g(), "");
49a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith}
50a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith
51a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smithnamespace Test4 {
52a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  template<typename T>
53a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  constexpr void (*f())() {
54a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    void h();
55a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    return &h;
56a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  }
57a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  static_assert(f<int>() == f<char>(), "");
58a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  void h();
59a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  static_assert(f<int>() == &h, "");
60a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith}
61a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith
62a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smithnamespace Test5 {
63a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  constexpr auto f() -> void (*)() {
64a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    void g();
65a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    struct X {
66a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith      friend void g();
67a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith      static constexpr auto h() -> void (*)() { return g; }
68a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    };
69a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith    return X::h();
70a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  }
71a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  void g();
72a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith  static_assert(f() == g, "");
73a41c97a5d1912ffd184381d269fd8e5a25ee5e59Richard Smith}
74