1 // RUN: %clang_cc1 %s -fsyntax-only -verify -Winfinite-recursion
3 void a() { // expected-warning{{call itself}}
7 void b(int x
) { // expected-warning{{call itself}}
19 void d(int x
) { // expected-warning{{call itself}}
25 // Doesn't warn on mutually recursive functions
32 void g() { // expected-warning{{call itself}}
45 void i(int x
) { // expected-warning{{call itself}}
52 int j() { // expected-warning{{call itself}}
56 // Don't warn on infinite loops
83 void S::a() { // expected-warning{{call itself}}
87 void S::b() { // expected-warning{{call itself}}
95 template<class member
>
98 void a() { return a(); } // expected-warning{{call itself}}
99 static void b() { return b(); } // expected-warning{{call itself}}
104 foo
.a(); // expected-note{{in instantiation}}
105 foo
.b(); // expected-note{{in instantiation}}
110 void Fun() { // expected-warning{{call itself}}
115 // No warnings on templated functions
116 // sum<0>() is instantiated, does recursively call itself, but never runs.
119 return value
+ sum
<value
/2>();
123 int sum
<1>() { return 1; }
125 template<int x
, int y
>
126 int calculate_value() {
128 return sum
<x
- y
>(); // This instantiates sum<0>() even if never called.
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
>
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.
145 DoStuff
<First
, (First
+ Last
)/2>();
146 DoStuff
<(First
+ Last
)/2, Last
>();
150 int stuff
= DoStuff
<0, 1>();
155 // Similar to the above, Wrapper<0>::run() will discard the if statement.
158 return Wrapper
<x
/2>::run();
160 static int run2() { // expected-warning{{call itself}}
168 return Wrapper
<x
>::run() +
169 Wrapper
<x
>::run2(); // expected-note{{instantiation}}
173 int wrapper_sum
= test_wrapper
<2>(); // expected-note{{instantiation}}
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
);
193 virtual ~Q() = default;
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'}}
202 int unevaluated_recursive_function() {
203 (void)typeid(unevaluated_recursive_function());
207 void func1(int i
) { // expected-warning {{call itself}}
211 void func2(int i
) { // expected-warning {{call itself}}