lebedev.ri created this revision.
lebedev.ri added reviewers: aaron.ballman, alexfh, djasper, malcolm.parsons.
lebedev.ri added a project: clang-tools-extra.
Herald added a subscriber: xazax.hun.

The readability-else-after-return check was not warning about  an else after a 
call to the function that will not return. In particular, marker with a 
noreturn attribute, be it either C++11 `[[noreturn]]`, or the 
`__attribute__((noreturn))`.
This differential adds support to diagnose normal function calls, and calls to 
member functions; but not constructors, destructors and special member 
functions.

A follow-up for https://reviews.llvm.org/D40505.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41456

Files:
  clang-tidy/readability/ElseAfterReturnCheck.cpp
  docs/ReleaseNotes.rst
  test/clang-tidy/readability-else-after-return.cpp

Index: test/clang-tidy/readability-else-after-return.cpp
===================================================================
--- test/clang-tidy/readability-else-after-return.cpp
+++ test/clang-tidy/readability-else-after-return.cpp
@@ -11,6 +11,28 @@
   my_exception(const std::string &s);
 };
 
+__attribute__((noreturn)) void my_noreturn();
+[[noreturn]] void my_noreturn2();
+[[noreturn]] __attribute__((noreturn)) void my_noreturn3();
+struct my_struct {
+  [[noreturn]] static void test();
+  [[noreturn]] void test_2();
+};
+struct my_assign {
+  my_assign();
+  [[noreturn]] my_assign& operator=(const my_assign& c);
+};
+struct my_copy {
+  my_copy();
+  [[noreturn]] my_copy(const my_copy& c);
+};
+struct noreturn_ctor {
+  [[noreturn]] noreturn_ctor();
+};
+struct noreturn_dtor {
+  [[noreturn]] noreturn_dtor();
+};
+
 void f(int a) {
   if (a > 0)
     return;
@@ -103,5 +125,69 @@
     // CHECK-FIXES: {{^}}    } // comment-10
       x++;
     }
+    if (x) {
+      my_noreturn();
+    } else { // comment-11
+    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use 'else' after 'noreturn call'
+    // CHECK-FIXES: {{^}}    } // comment-11
+      x++;
+    }
+    if (x) {
+      my_noreturn2();
+    } else { // comment-12
+    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use 'else' after 'noreturn call'
+    // CHECK-FIXES: {{^}}    } // comment-12
+      x++;
+    }
+    if (x) {
+      my_noreturn3();
+    } else { // comment-13
+    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use 'else' after 'noreturn call'
+    // CHECK-FIXES: {{^}}    } // comment-13
+      x++;
+    }
+    if (x) {
+      my_struct::test();
+    } else { // comment-14
+    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use 'else' after 'noreturn call'
+    // CH1ECK-FIXES: {{^}}    } // comment-14
+      x++;
+    }
+    if (x) {
+      my_struct s;
+      s.test_2();
+    } else { // comment-15
+    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use 'else' after 'noreturn call'
+    // CHECK-FIXES: {{^}}    } // comment-15
+      x++;
+    }
+    if (x) {
+      my_assign a0;
+      my_assign a1;
+      a1 = a0;
+    } else { // comment-16
+    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use 'else' after 'noreturn call'
+    // CHECK-FIXES: {{^}}    } // comment-16
+      x++;
+    }
+    if (x) {
+      // FIXME
+      my_copy c0;
+      my_copy c1(c0);
+    } else { // comment-17
+      x++;
+    }
+    if (x) {
+      // FIXME
+      noreturn_ctor n;
+    } else { // comment-18
+      x++;
+    }
+    if (x) {
+      // FIXME
+      noreturn_dtor n;
+    } else { // comment-19
+      x++;
+    }
   }
 }
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -186,6 +186,8 @@
   Finds property declarations in Objective-C files that do not follow the
   pattern of property names in Apple's programming guide.
 
+- The 'readability-else-after-return' check was adjusted to handle throw expressions that require cleanups, calls to functions marked with noreturn attribute.
+
 - New `readability-static-accessed-through-instance
   <http://clang.llvm.org/extra/clang-tidy/checks/readability-static-accessed-through-instance.html>`_ check
 
Index: clang-tidy/readability/ElseAfterReturnCheck.cpp
===================================================================
--- clang-tidy/readability/ElseAfterReturnCheck.cpp
+++ clang-tidy/readability/ElseAfterReturnCheck.cpp
@@ -22,7 +22,9 @@
   const auto ControlFlowInterruptorMatcher =
       stmt(anyOf(returnStmt().bind("return"), continueStmt().bind("continue"),
                  breakStmt().bind("break"),
-                 expr(ignoringImplicit(cxxThrowExpr().bind("throw")))));
+                 expr(ignoringImplicit(cxxThrowExpr().bind("throw"))),
+                 callExpr(hasDeclaration(functionDecl(isNoReturn())))
+                     .bind("noreturn call")));
   Finder->addMatcher(
       compoundStmt(forEach(
           ifStmt(hasThen(stmt(
@@ -37,7 +39,8 @@
   const auto *If = Result.Nodes.getNodeAs<IfStmt>("if");
   SourceLocation ElseLoc = If->getElseLoc();
   std::string ControlFlowInterruptor;
-  for (const auto *BindingName : {"return", "continue", "break", "throw"})
+  for (const auto *BindingName :
+       {"return", "continue", "break", "throw", "noreturn call"})
     if (Result.Nodes.getNodeAs<Stmt>(BindingName))
       ControlFlowInterruptor = BindingName;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to