1// RUN: %clang_cc1 -fsyntax-only -verify %s -Wmissing-noreturn -Wreturn-type
2void f() __attribute__((noreturn));
3
4template<typename T> void g(T) {
5  f();
6}
7
8template void g<int>(int);
9
10template<typename T> struct A {
11  void g() {
12    f();
13  }
14};
15
16template struct A<int>;
17
18struct B {
19  template<typename T> void g(T) {
20    f();
21  }
22};
23
24template void B::g<int>(int);
25
26// We don't want a warning here.
27struct X {
28  virtual void g() { f(); }
29};
30
31namespace test1 {
32  bool condition();
33
34  // We don't want a warning here.
35  void foo() {
36    while (condition()) {}
37  }
38}
39
40
41// <rdar://problem/7880658> - This test case previously had a false "missing return"
42// warning.
43struct R7880658 {
44  R7880658 &operator++();
45  bool operator==(const R7880658 &) const;
46  bool operator!=(const R7880658 &) const;
47};
48
49void f_R7880658(R7880658 f, R7880658 l) {  // no-warning
50  for (; f != l; ++f) {
51  }
52}
53
54namespace test2 {
55
56  bool g();
57  void *h() __attribute__((noreturn));
58  void *j();
59
60  struct A {
61    void *f;
62
63    A() : f(0) { }
64    A(int) : f(h()) { } // expected-warning {{function 'A' could be declared with attribute 'noreturn'}}
65    A(char) : f(j()) { }
66    A(bool b) : f(b ? h() : j()) { }
67  };
68}
69
70namespace test3 {
71  struct A {
72    ~A();
73  };
74
75  struct B {
76    ~B() { }
77
78    A a;
79  };
80
81  struct C : A {
82    ~C() { }
83  };
84}
85
86// <rdar://problem/8875247> - Properly handle CFGs with destructors.
87struct rdar8875247 {
88  ~rdar8875247 ();
89};
90void rdar8875247_aux();
91
92int rdar8875247_test() {
93  rdar8875247 f;
94} // expected-warning{{control reaches end of non-void function}}
95
96struct rdar8875247_B {
97  rdar8875247_B();
98  ~rdar8875247_B();
99};
100
101rdar8875247_B test_rdar8875247_B() {
102  rdar8875247_B f;
103  return f;
104} // no-warning
105
106namespace PR10801 {
107  struct Foo {
108    void wibble() __attribute((__noreturn__));
109  };
110
111  struct Bar {
112    void wibble();
113  };
114
115  template <typename T> void thingy(T thing) {
116    thing.wibble();
117  }
118
119  void test() {
120    Foo f;
121    Bar b;
122    thingy(f);
123    thingy(b);
124  }
125}
126