1*67e74705SXin Li // RUN: %clang_cc1 %s -fsyntax-only -verify -Winfinite-recursion
2*67e74705SXin Li
a()3*67e74705SXin Li void a() { // expected-warning{{call itself}}
4*67e74705SXin Li a();
5*67e74705SXin Li }
6*67e74705SXin Li
b(int x)7*67e74705SXin Li void b(int x) { // expected-warning{{call itself}}
8*67e74705SXin Li if (x)
9*67e74705SXin Li b(x);
10*67e74705SXin Li else
11*67e74705SXin Li b(x+1);
12*67e74705SXin Li }
13*67e74705SXin Li
c(int x)14*67e74705SXin Li void c(int x) {
15*67e74705SXin Li if (x)
16*67e74705SXin Li c(5);
17*67e74705SXin Li }
18*67e74705SXin Li
d(int x)19*67e74705SXin Li void d(int x) { // expected-warning{{call itself}}
20*67e74705SXin Li if (x)
21*67e74705SXin Li ++x;
22*67e74705SXin Li return d(x);
23*67e74705SXin Li }
24*67e74705SXin Li
25*67e74705SXin Li // Doesn't warn on mutually recursive functions
26*67e74705SXin Li void e();
27*67e74705SXin Li void f();
28*67e74705SXin Li
e()29*67e74705SXin Li void e() { f(); }
f()30*67e74705SXin Li void f() { e(); }
31*67e74705SXin Li
32*67e74705SXin Li // Don't warn on infinite loops
g()33*67e74705SXin Li void g() {
34*67e74705SXin Li while (true)
35*67e74705SXin Li g();
36*67e74705SXin Li
37*67e74705SXin Li g();
38*67e74705SXin Li }
39*67e74705SXin Li
h(int x)40*67e74705SXin Li void h(int x) {
41*67e74705SXin Li while (x < 5) {
42*67e74705SXin Li h(x+1);
43*67e74705SXin Li }
44*67e74705SXin Li }
45*67e74705SXin Li
i(int x)46*67e74705SXin Li void i(int x) { // expected-warning{{call itself}}
47*67e74705SXin Li while (x < 5) {
48*67e74705SXin Li --x;
49*67e74705SXin Li }
50*67e74705SXin Li i(0);
51*67e74705SXin Li }
52*67e74705SXin Li
j()53*67e74705SXin Li int j() { // expected-warning{{call itself}}
54*67e74705SXin Li return 5 + j();
55*67e74705SXin Li }
56*67e74705SXin Li
57*67e74705SXin Li class S {
58*67e74705SXin Li static void a();
59*67e74705SXin Li void b();
60*67e74705SXin Li };
61*67e74705SXin Li
a()62*67e74705SXin Li void S::a() { // expected-warning{{call itself}}
63*67e74705SXin Li return a();
64*67e74705SXin Li }
65*67e74705SXin Li
b()66*67e74705SXin Li void S::b() { // expected-warning{{call itself}}
67*67e74705SXin Li int i = 0;
68*67e74705SXin Li do {
69*67e74705SXin Li ++i;
70*67e74705SXin Li b();
71*67e74705SXin Li } while (i > 5);
72*67e74705SXin Li }
73*67e74705SXin Li
74*67e74705SXin Li template<class member>
75*67e74705SXin Li struct T {
76*67e74705SXin Li member m;
aT77*67e74705SXin Li void a() { return a(); } // expected-warning{{call itself}}
bT78*67e74705SXin Li static void b() { return b(); } // expected-warning{{call itself}}
79*67e74705SXin Li };
80*67e74705SXin Li
test_T()81*67e74705SXin Li void test_T() {
82*67e74705SXin Li T<int> foo;
83*67e74705SXin Li foo.a(); // expected-note{{in instantiation}}
84*67e74705SXin Li foo.b(); // expected-note{{in instantiation}}
85*67e74705SXin Li }
86*67e74705SXin Li
87*67e74705SXin Li class U {
88*67e74705SXin Li U* u;
Fun()89*67e74705SXin Li void Fun() { // expected-warning{{call itself}}
90*67e74705SXin Li u->Fun();
91*67e74705SXin Li }
92*67e74705SXin Li };
93*67e74705SXin Li
94*67e74705SXin Li // No warnings on templated functions
95*67e74705SXin Li // sum<0>() is instantiated, does recursively call itself, but never runs.
96*67e74705SXin Li template <int value>
sum()97*67e74705SXin Li int sum() {
98*67e74705SXin Li return value + sum<value/2>();
99*67e74705SXin Li }
100*67e74705SXin Li
101*67e74705SXin Li template<>
sum()102*67e74705SXin Li int sum<1>() { return 1; }
103*67e74705SXin Li
104*67e74705SXin Li template<int x, int y>
calculate_value()105*67e74705SXin Li int calculate_value() {
106*67e74705SXin Li if (x != y)
107*67e74705SXin Li return sum<x - y>(); // This instantiates sum<0>() even if never called.
108*67e74705SXin Li else
109*67e74705SXin Li return 0;
110*67e74705SXin Li }
111*67e74705SXin Li
112*67e74705SXin Li int value = calculate_value<1,1>();
113*67e74705SXin Li
114*67e74705SXin Li void DoSomethingHere();
115*67e74705SXin Li
116*67e74705SXin Li // DoStuff<0,0>() is instantiated, but never called.
117*67e74705SXin Li template<int First, int Last>
DoStuff()118*67e74705SXin Li int DoStuff() {
119*67e74705SXin Li if (First + 1 == Last) {
120*67e74705SXin Li // This branch gets removed during <0, 0> instantiation in so CFG for this
121*67e74705SXin Li // function goes straight to the else branch.
122*67e74705SXin Li DoSomethingHere();
123*67e74705SXin Li } else {
124*67e74705SXin Li DoStuff<First, (First + Last)/2>();
125*67e74705SXin Li DoStuff<(First + Last)/2, Last>();
126*67e74705SXin Li }
127*67e74705SXin Li return 0;
128*67e74705SXin Li }
129*67e74705SXin Li int stuff = DoStuff<0, 1>();
130*67e74705SXin Li
131*67e74705SXin Li template<int x>
132*67e74705SXin Li struct Wrapper {
runWrapper133*67e74705SXin Li static int run() {
134*67e74705SXin Li // Similar to the above, Wrapper<0>::run() will discard the if statement.
135*67e74705SXin Li if (x == 1)
136*67e74705SXin Li return 0;
137*67e74705SXin Li return Wrapper<x/2>::run();
138*67e74705SXin Li }
run2Wrapper139*67e74705SXin Li static int run2() { // expected-warning{{call itself}}
140*67e74705SXin Li return run2();
141*67e74705SXin Li }
142*67e74705SXin Li };
143*67e74705SXin Li
144*67e74705SXin Li template <int x>
test_wrapper()145*67e74705SXin Li int test_wrapper() {
146*67e74705SXin Li if (x != 0)
147*67e74705SXin Li return Wrapper<x>::run() +
148*67e74705SXin Li Wrapper<x>::run2(); // expected-note{{instantiation}}
149*67e74705SXin Li return 0;
150*67e74705SXin Li }
151*67e74705SXin Li
152*67e74705SXin Li int wrapper_sum = test_wrapper<2>(); // expected-note{{instantiation}}
153