]> granicus.if.org Git - clang/commitdiff
Restore Check for Unreachable Exit Block in -Winfinite-recursion
authorRobert Widmann <devteam.codafi@gmail.com>
Wed, 13 Feb 2019 22:22:23 +0000 (22:22 +0000)
committerRobert Widmann <devteam.codafi@gmail.com>
Wed, 13 Feb 2019 22:22:23 +0000 (22:22 +0000)
Summary:
When this was rewritten in D43737, the logic changed to better explore infinite loops. The check for a reachable exit block was deleted which accidentally introduced false positives in case the exit node was unreachable.

We were testing for cases like this, but @steven_wu provided an additional test case that I've included in the regression tests for this patch.

Reviewers: steven_wu, rtrieu

Reviewed By: steven_wu, rtrieu

Subscribers: cfe-commits, steven_wu

Tags: #clang

Differential Revision: https://reviews.llvm.org/D58122

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@353984 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/AnalysisBasedWarnings.cpp
test/SemaCXX/warn-infinite-recursion.cpp

index 7ce69fd8c19da22e8f37843df202dd69dd24f449..6120d2b9df3cdd836b9dbb060c94a90e6326c35f 100644 (file)
@@ -249,6 +249,10 @@ static void checkRecursiveFunction(Sema &S, const FunctionDecl *FD,
   CFG *cfg = AC.getCFG();
   if (!cfg) return;
 
+  // If the exit block is unreachable, skip processing the function.
+  if (cfg->getExit().pred_empty())
+    return;
+
   // Emit diagnostic if a recursive function call is detected for all paths.
   if (checkForRecursiveFunctionCall(FD, cfg))
     S.Diag(Body->getBeginLoc(), diag::warn_infinite_recursive_function);
index bbeff92a657b8f8fe0672857bc1437b7884e470b..e5a5a18b6571792edb5c7dc6b820a5230222abe8 100644 (file)
@@ -53,19 +53,28 @@ int j() {  // expected-warning{{call itself}}
   return 5 + j();
 }
 
-void k() {  // expected-warning{{call itself}}
+// Don't warn on infinite loops
+void k() {
   while(true) {
     k();
   }
 }
 
-// Don't warn on infinite loops
 void l() {
   while (true) {}
 
   l();
 }
 
+void m() {
+  static int count = 5;
+  if (count >0) {
+    count--;
+    l();
+  }
+  while (true) {}
+}
+
 class S {
   static void a();
   void b();