Add -Winfinite-recursion to Clang

This new warning detects when a function will recursively call itself on every
code path though that function.  This catches simple recursive cases such as:

void foo() {
  foo();
}

As well as more complex functions like:

void bar() {
  if (test()) {
    bar();
    return;
  } else {
    bar();
  }
  return;
}

This warning uses the CFG.  As with other CFG-based warnings, this is off
by default.  Due to false positives, this warning is also disabled for
templated functions.

llvm-svn: 197853
diff --git a/clang/test/SemaCXX/warn-infinite-recursion.cpp b/clang/test/SemaCXX/warn-infinite-recursion.cpp
new file mode 100644
index 0000000..088d4ba
--- /dev/null
+++ b/clang/test/SemaCXX/warn-infinite-recursion.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -Winfinite-recursion
+
+void a() {  // expected-warning{{call itself}}
+  a();
+}
+
+void b(int x) {  // expected-warning{{call itself}}
+  if (x)
+    b(x);
+  else
+    b(x+1);
+}
+
+void c(int x) {
+  if (x)
+    c(5);
+}
+
+void d(int x) {  // expected-warning{{call itself}}
+  if (x)
+    ++x;
+  return d(x);
+}
+
+// Doesn't warn on mutually recursive functions
+void e();
+void f();
+
+void e() { f(); }
+void f() { e(); }
+
+// Don't warn on infinite loops
+void g() {
+  while (true)
+    g();
+
+  g();
+}
+
+void h(int x) {
+  while (x < 5) {
+    h(x+1);
+  }
+}
+
+void i(int x) {  // expected-warning{{call itself}}
+  while (x < 5) {
+    --x;
+  }
+  i(0);
+}
+
+int j() {  // expected-warning{{call itself}}
+  return 5 + j();
+}
+
+class S {
+  static void a();
+  void b();
+};
+
+void S::a() {  // expected-warning{{call itself}}
+  return a();
+}
+
+void S::b() {  // expected-warning{{call itself}}
+  int i = 0;
+  do {
+    ++i;
+    b();
+  } while (i > 5);
+}
+
+template<class member>
+struct T {
+  member m;
+  void a() { return a(); }  // expected-warning{{call itself}}
+  static void b() { return b(); }  // expected-warning{{call itself}}
+};
+
+void test_T() {
+  T<int> foo;
+  foo.a();  // expected-note{{in instantiation}}
+  foo.b();  // expected-note{{in instantiation}}
+}
+
+class U {
+  U* u;
+  void Fun() {  // expected-warning{{call itself}}
+    u->Fun();
+  }
+};
+
+// No warnings on templated functions
+// sum<0>() is instantiated, does recursively call itself, but never runs.
+template <int value>
+int sum() {
+  return value + sum<value/2>();
+}
+
+template<>
+int sum<1>() { return 1; }
+
+template<int x, int y>
+int calculate_value() {
+  if (x != y)
+    return sum<x - y>();  // This instantiates sum<0>() even if never called.
+  else
+    return 0;
+}
+
+int value = calculate_value<1,1>();
+
+void DoSomethingHere();
+
+// DoStuff<0,0>() is instantiated, but never called.
+template<int First, int Last>
+int DoStuff() {
+  if (First + 1 == Last) {
+    // This branch gets removed during <0, 0> instantiation in so CFG for this
+    // function goes straight to the else branch.
+    DoSomethingHere();
+  } else {
+    DoStuff<First, (First + Last)/2>();
+    DoStuff<(First + Last)/2, Last>();
+  }
+  return 0;
+}
+int stuff = DoStuff<0, 1>();