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 // Don't warn on infinite loops
46 void i(int x) { // expected-warning{{call itself}}
53 int j() { // expected-warning{{call itself}}
62 void S::a() { // expected-warning{{call itself}}
66 void S::b() { // expected-warning{{call itself}}
74 template<class member>
77 void a() { return a(); } // expected-warning{{call itself}}
78 static void b() { return b(); } // expected-warning{{call itself}}
83 foo.a(); // expected-note{{in instantiation}}
84 foo.b(); // expected-note{{in instantiation}}
89 void Fun() { // expected-warning{{call itself}}
94 // No warnings on templated functions
95 // sum<0>() is instantiated, does recursively call itself, but never runs.
98 return value + sum<value/2>();
102 int sum<1>() { return 1; }
104 template<int x, int y>
105 int calculate_value() {
107 return sum<x - y>(); // This instantiates sum<0>() even if never called.
112 int value = calculate_value<1,1>();
114 void DoSomethingHere();
116 // DoStuff<0,0>() is instantiated, but never called.
117 template<int First, int Last>
119 if (First + 1 == Last) {
120 // This branch gets removed during <0, 0> instantiation in so CFG for this
121 // function goes straight to the else branch.
124 DoStuff<First, (First + Last)/2>();
125 DoStuff<(First + Last)/2, Last>();
129 int stuff = DoStuff<0, 1>();
134 // Similar to the above, Wrapper<0>::run() will discard the if statement.
137 return Wrapper<x/2>::run();
139 static int run2() { // expected-warning{{call itself}}
147 return Wrapper<x>::run() +
148 Wrapper<x>::run2(); // expected-note{{instantiation}}
152 int wrapper_sum = test_wrapper<2>(); // expected-note{{instantiation}}