1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3// Reachability tests have to come first because they get suppressed
4// if any errors have occurred.
5namespace test5 {
6  struct A {
7    __attribute__((noreturn)) void fail();
8    void nofail();
9  } a;
10
11  int &test1() {
12    a.nofail();
13  } // expected-warning {{control reaches end of non-void function}}
14
15  int &test2() {
16    a.fail();
17  }
18}
19
20// PR5620
21void f0() __attribute__((__noreturn__));
22void f1(void (*)());
23void f2() { f1(f0); }
24
25// Taking the address of a noreturn function
26void test_f0a() {
27  void (*fp)() = f0;
28  void (*fp1)() __attribute__((noreturn)) = f0;
29}
30
31// Taking the address of an overloaded noreturn function
32void f0(int) __attribute__((__noreturn__));
33
34void test_f0b() {
35  void (*fp)() = f0;
36  void (*fp1)() __attribute__((noreturn)) = f0;
37}
38
39// No-returned function pointers
40typedef void (* noreturn_fp)() __attribute__((noreturn));
41
42void f3(noreturn_fp); // expected-note{{candidate function}}
43
44void test_f3() {
45  f3(f0); // okay
46  f3(f2); // expected-error{{no matching function for call}}
47}
48
49
50class xpto {
51  int blah() __attribute__((noreturn));
52};
53
54int xpto::blah() {
55  return 3; // expected-warning {{function 'blah' declared 'noreturn' should not return}}
56}
57
58// PR12948
59
60namespace PR12948 {
61  template<int>
62  void foo() __attribute__((__noreturn__));
63
64  template<int>
65  void foo() {
66    while (1) continue;
67  }
68
69  void bar() __attribute__((__noreturn__));
70
71  void bar() {
72    foo<0>();
73  }
74
75
76  void baz() __attribute__((__noreturn__));
77  typedef void voidfn();
78  voidfn baz;
79
80  template<typename> void wibble()  __attribute__((__noreturn__));
81  template<typename> voidfn wibble;
82}
83
84// PR15291
85// Overload resolution per over.over should allow implicit noreturn adjustment.
86namespace PR15291 {
87  __attribute__((noreturn)) void foo(int) {}
88  __attribute__((noreturn)) void foo(double) {}
89
90  template <typename T>
91  __attribute__((noreturn)) void bar(T) {}
92
93  void baz(int) {}
94  void baz(double) {}
95
96  template <typename T>
97  void qux(T) {}
98
99  // expected-note@+5 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
100  // expected-note@+4 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
101  // expected-note@+3 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'bar' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
102  // expected-note@+2 {{candidate function [with T = void (*)(int)] not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
103  // expected-note@+1 {{candidate function [with T = void (int)] not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
104  template <typename T> void accept_T(T) {}
105
106  // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}
107  void accept_fptr(void (*f)(int)) {
108    f(42);
109  }
110
111  // expected-note@+2 {{candidate function not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
112  // expected-note@+1 {{candidate function not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}
113  void accept_noreturn_fptr(void __attribute__((noreturn)) (*f)(int)) {
114    f(42);
115  }
116
117  typedef void (*fptr_t)(int);
118  typedef void __attribute__((noreturn)) (*fptr_noreturn_t)(int);
119
120  // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'fptr_t' (aka 'void (*)(int)') for 1st argument}}
121  void accept_fptr_t(fptr_t f) {
122    f(42);
123  }
124
125  // expected-note@+2 {{candidate function not viable: no overload of 'baz' matching 'fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}}
126  // expected-note@+1 {{candidate function not viable: no overload of 'qux' matching 'fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}}
127  void accept_fptr_noreturn_t(fptr_noreturn_t f) {
128    f(42);
129  }
130
131  // Stripping noreturn should work if everything else is correct.
132  void strip_noreturn() {
133    accept_fptr(foo);
134    accept_fptr(bar<int>);
135    accept_fptr(bar<double>); // expected-error {{no matching function for call to 'accept_fptr'}}
136
137    accept_fptr_t(foo);
138    accept_fptr_t(bar<int>);
139    accept_fptr_t(bar<double>); // expected-error {{no matching function for call to 'accept_fptr_t'}}
140
141    accept_T<void __attribute__((noreturn)) (*)(int)>(foo);
142    accept_T<void __attribute__((noreturn)) (*)(int)>(bar<int>);
143    accept_T<void __attribute__((noreturn)) (*)(int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}}
144
145    accept_T<void (*)(int)>(foo);
146    accept_T<void (*)(int)>(bar<int>);
147    accept_T<void (*)(int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}}
148
149    accept_T<void (int)>(foo);
150    accept_T<void (int)>(bar<int>);
151    accept_T<void (int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}}
152  }
153
154  // Introducing noreturn should not work.
155  void introduce_noreturn() {
156    accept_noreturn_fptr(baz); // expected-error {{no matching function for call to 'accept_noreturn_fptr'}}
157    accept_noreturn_fptr(qux<int>); // expected-error {{no matching function for call to 'accept_noreturn_fptr'}}
158
159    accept_fptr_noreturn_t(baz); // expected-error {{no matching function for call to 'accept_fptr_noreturn_t'}}
160    accept_fptr_noreturn_t(qux<int>); // expected-error {{no matching function for call to 'accept_fptr_noreturn_t'}}
161
162    accept_T<void __attribute__((noreturn)) (*)(int)>(baz); // expected-error {{no matching function for call to 'accept_T'}}
163    accept_T<void __attribute__((noreturn)) (*)(int)>(qux<int>); // expected-error {{no matching function for call to 'accept_T'}}
164  }
165}
166