[X86] Move getGFNICtrlMask before CTLZ/CTTZ lowering. NFC.
[llvm-project.git] / clang / test / SemaCXX / warn-infinite-recursion.cpp
blobd0f3fe7b164e195d1c8b459be6b276805d8bde21
1 // RUN: %clang_cc1 %s -fsyntax-only -verify -Winfinite-recursion
3 void a() { // expected-warning{{call itself}}
4 a();
7 void b(int x) { // expected-warning{{call itself}}
8 if (x)
9 b(x);
10 else
11 b(x+1);
14 void c(int x) {
15 if (x)
16 c(5);
19 void d(int x) { // expected-warning{{call itself}}
20 if (x)
21 ++x;
22 return d(x);
25 // Doesn't warn on mutually recursive functions
26 void e();
27 void f();
29 void e() { f(); }
30 void f() { e(); }
32 void g() { // expected-warning{{call itself}}
33 while (true)
34 g();
36 g();
39 void h(int x) {
40 while (x < 5) {
41 h(x+1);
45 void i(int x) { // expected-warning{{call itself}}
46 while (x < 5) {
47 --x;
49 i(0);
52 int j() { // expected-warning{{call itself}}
53 return 5 + j();
56 // Don't warn on infinite loops
57 void k() {
58 while(true) {
59 k();
63 void l() {
64 while (true) {}
66 l();
69 void m() {
70 static int count = 5;
71 if (count >0) {
72 count--;
73 l();
75 while (true) {}
78 class S {
79 static void a();
80 void b();
83 void S::a() { // expected-warning{{call itself}}
84 return a();
87 void S::b() { // expected-warning{{call itself}}
88 int i = 0;
89 do {
90 ++i;
91 b();
92 } while (i > 5);
95 template<class member>
96 struct T {
97 member m;
98 void a() { return a(); } // expected-warning{{call itself}}
99 static void b() { return b(); } // expected-warning{{call itself}}
102 void test_T() {
103 T<int> foo;
104 foo.a(); // expected-note{{in instantiation}}
105 foo.b(); // expected-note{{in instantiation}}
108 class U {
109 U* u;
110 void Fun() { // expected-warning{{call itself}}
111 u->Fun();
115 // No warnings on templated functions
116 // sum<0>() is instantiated, does recursively call itself, but never runs.
117 template <int value>
118 int sum() {
119 return value + sum<value/2>();
122 template<>
123 int sum<1>() { return 1; }
125 template<int x, int y>
126 int calculate_value() {
127 if (x != y)
128 return sum<x - y>(); // This instantiates sum<0>() even if never called.
129 else
130 return 0;
133 int value = calculate_value<1,1>();
135 void DoSomethingHere();
137 // DoStuff<0,0>() is instantiated, but never called.
138 template<int First, int Last>
139 int DoStuff() {
140 if (First + 1 == Last) {
141 // This branch gets removed during <0, 0> instantiation in so CFG for this
142 // function goes straight to the else branch.
143 DoSomethingHere();
144 } else {
145 DoStuff<First, (First + Last)/2>();
146 DoStuff<(First + Last)/2, Last>();
148 return 0;
150 int stuff = DoStuff<0, 1>();
152 template<int x>
153 struct Wrapper {
154 static int run() {
155 // Similar to the above, Wrapper<0>::run() will discard the if statement.
156 if (x == 1)
157 return 0;
158 return Wrapper<x/2>::run();
160 static int run2() { // expected-warning{{call itself}}
161 return run2();
165 template <int x>
166 int test_wrapper() {
167 if (x != 0)
168 return Wrapper<x>::run() +
169 Wrapper<x>::run2(); // expected-note{{instantiation}}
170 return 0;
173 int wrapper_sum = test_wrapper<2>(); // expected-note{{instantiation}}
175 namespace std {
176 class type_info {
177 public:
178 virtual ~type_info();
179 const char *name() const { return __name; }
180 bool operator==(const type_info &__arg) const {
181 return __name == __arg.__name;
184 bool operator!=(const type_info &__arg) const {
185 return !operator==(__arg);
188 protected:
189 const char *__name;
191 } // namespace std
192 struct Q {
193 virtual ~Q() = default;
196 Q q;
197 Q &evaluated_recursive_function(int x) { // expected-warning{{call itself}}
198 (void)typeid(evaluated_recursive_function(x)); // expected-warning {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}}
199 return q;
202 int unevaluated_recursive_function() {
203 (void)typeid(unevaluated_recursive_function());
204 return 0;
207 void func1(int i) { // expected-warning {{call itself}}
208 if (i || !i)
209 func1(i);
211 void func2(int i) { // expected-warning {{call itself}}
212 if (!i && i) {}
213 else
214 func2(i);