[PATCH] D152330: [clang-tidy] Check functions called from catch blocks

2023-06-11 Thread Deniz Evrenci via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGdaac014fec42: [clang-tidy] Check functions called from catch 
blocks (authored by denizevrenci).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152330/new/

https://reviews.llvm.org/D152330

Files:
  clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
  clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.h
  clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp
@@ -0,0 +1,36 @@
+// RUN: %check_clang_tidy -std=c++11,c++14,c++17,c++20 %s bugprone-exception-escape %t -- \
+// RUN: -- -fexceptions
+
+void rethrower() {
+throw;
+}
+
+void callsRethrower() {
+rethrower();
+}
+
+void callsRethrowerNoexcept() noexcept {
+rethrower();
+}
+
+int throwsAndCallsRethrower() noexcept {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'throwsAndCallsRethrower' which should not throw exceptions
+try {
+throw 1;
+} catch(...) {
+rethrower();
+}
+}
+
+int throwsAndCallsCallsRethrower() noexcept {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'throwsAndCallsCallsRethrower' which should not throw exceptions
+try {
+throw 1;
+} catch(...) {
+callsRethrower();
+}
+}
+
+void rethrowerNoexcept() noexcept {
+throw;
+}
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
@@ -36,17 +36,18 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise;
 
 template <
 typename T, bool ThrowInTaskConstructor = false,
 bool ThrowInPromiseConstructor = false, bool ThrowInInitialSuspend = false,
-bool ThrowInGetReturnObject = false, bool ThrowInUnhandledException = false>
+bool ThrowInGetReturnObject = false, bool ThrowInUnhandledException = false,
+bool RethrowInUnhandledException = false>
 struct Task {
   using promise_type =
   Promise;
+  ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException>;
 
   explicit Task(promise_type ) {
 if constexpr (ThrowInTaskConstructor) {
@@ -67,13 +68,13 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Task {
+ThrowInUnhandledException, RethrowInUnhandledException> {
   using promise_type =
   Promise;
+  ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException>;
 
   explicit Task(promise_type ) {
 if constexpr (ThrowInTaskConstructor) {
@@ -92,7 +93,7 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise {
   Promise() {
 if constexpr (ThrowInPromiseConstructor) {
@@ -130,6 +131,8 @@
   void unhandled_exception() {
 if constexpr (ThrowInUnhandledException) {
   throw 1;
+} else if constexpr (RethrowInUnhandledException) {
+  throw;
 }
   }
 
@@ -138,9 +141,9 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise {
+   ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException> {
   Promise() {
 if constexpr (ThrowInPromiseConstructor) {
   throw 1;
@@ -170,6 +173,8 @@
   void unhandled_exception() {
 if constexpr (ThrowInUnhandledException) {
   throw 1;
+} else if constexpr (RethrowInUnhandledException) {
+  throw;
 }
   }
 
@@ -266,6 +271,33 @@
   co_return a / b;
 }
 
+Task
+i_ShouldNotDiag(const int a, const int b) {
+  co_return a / b;
+}
+
+Task
+i_ShouldNotDiagNoexcept(const int a, const int b) noexcept {
+  co_return a / b;
+}
+
+Task
+j_ShouldNotDiag(const int a, const int b) {
+  if (b == 0)
+throw b;
+
+  co_return a / b;
+}
+
+Task
+j_ShouldDiag(const int a, const int b) noexcept {
+  // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: an exception may be thrown in function 'j_ShouldDiag' which should not throw exceptions
+  if (b == 0)
+throw b;
+
+  co_return a / b;
+}
+
 } // namespace coreturn
 
 namespace coyield {
@@ -347,6 +379,33 @@
   co_yield a / b;
 }
 
+Task
+i_ShouldNotDiag(const int a, const int b) {
+  co_yield a / b;
+}
+
+Task
+i_ShouldNotDiagNoexcept(const int a, const int b) noexcept {
+  co_yield a / b;
+}
+
+Task
+j_ShouldNotDiag(const int a, const int b) {
+  

[PATCH] D152330: [clang-tidy] Check functions called from catch blocks

2023-06-11 Thread Deniz Evrenci via Phabricator via cfe-commits
denizevrenci updated this revision to Diff 530296.
denizevrenci added a comment.

Rebase on main


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152330/new/

https://reviews.llvm.org/D152330

Files:
  clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
  clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.h
  clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp
@@ -0,0 +1,36 @@
+// RUN: %check_clang_tidy -std=c++11,c++14,c++17,c++20 %s bugprone-exception-escape %t -- \
+// RUN: -- -fexceptions
+
+void rethrower() {
+throw;
+}
+
+void callsRethrower() {
+rethrower();
+}
+
+void callsRethrowerNoexcept() noexcept {
+rethrower();
+}
+
+int throwsAndCallsRethrower() noexcept {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'throwsAndCallsRethrower' which should not throw exceptions
+try {
+throw 1;
+} catch(...) {
+rethrower();
+}
+}
+
+int throwsAndCallsCallsRethrower() noexcept {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'throwsAndCallsCallsRethrower' which should not throw exceptions
+try {
+throw 1;
+} catch(...) {
+callsRethrower();
+}
+}
+
+void rethrowerNoexcept() noexcept {
+throw;
+}
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
@@ -36,17 +36,18 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise;
 
 template <
 typename T, bool ThrowInTaskConstructor = false,
 bool ThrowInPromiseConstructor = false, bool ThrowInInitialSuspend = false,
-bool ThrowInGetReturnObject = false, bool ThrowInUnhandledException = false>
+bool ThrowInGetReturnObject = false, bool ThrowInUnhandledException = false,
+bool RethrowInUnhandledException = false>
 struct Task {
   using promise_type =
   Promise;
+  ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException>;
 
   explicit Task(promise_type ) {
 if constexpr (ThrowInTaskConstructor) {
@@ -67,13 +68,13 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Task {
+ThrowInUnhandledException, RethrowInUnhandledException> {
   using promise_type =
   Promise;
+  ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException>;
 
   explicit Task(promise_type ) {
 if constexpr (ThrowInTaskConstructor) {
@@ -92,7 +93,7 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise {
   Promise() {
 if constexpr (ThrowInPromiseConstructor) {
@@ -130,6 +131,8 @@
   void unhandled_exception() {
 if constexpr (ThrowInUnhandledException) {
   throw 1;
+} else if constexpr (RethrowInUnhandledException) {
+  throw;
 }
   }
 
@@ -138,9 +141,9 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise {
+   ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException> {
   Promise() {
 if constexpr (ThrowInPromiseConstructor) {
   throw 1;
@@ -170,6 +173,8 @@
   void unhandled_exception() {
 if constexpr (ThrowInUnhandledException) {
   throw 1;
+} else if constexpr (RethrowInUnhandledException) {
+  throw;
 }
   }
 
@@ -266,6 +271,33 @@
   co_return a / b;
 }
 
+Task
+i_ShouldNotDiag(const int a, const int b) {
+  co_return a / b;
+}
+
+Task
+i_ShouldNotDiagNoexcept(const int a, const int b) noexcept {
+  co_return a / b;
+}
+
+Task
+j_ShouldNotDiag(const int a, const int b) {
+  if (b == 0)
+throw b;
+
+  co_return a / b;
+}
+
+Task
+j_ShouldDiag(const int a, const int b) noexcept {
+  // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: an exception may be thrown in function 'j_ShouldDiag' which should not throw exceptions
+  if (b == 0)
+throw b;
+
+  co_return a / b;
+}
+
 } // namespace coreturn
 
 namespace coyield {
@@ -347,6 +379,33 @@
   co_yield a / b;
 }
 
+Task
+i_ShouldNotDiag(const int a, const int b) {
+  co_yield a / b;
+}
+
+Task
+i_ShouldNotDiagNoexcept(const int a, const int b) noexcept {
+  co_yield a / b;
+}
+
+Task
+j_ShouldNotDiag(const int a, const int b) {
+  if (b == 0)
+throw b;
+
+  co_yield a / b;
+}
+
+Task
+j_ShouldDiag(const int a, const 

[PATCH] D152330: [clang-tidy] Check functions called from catch blocks

2023-06-06 Thread Deniz Evrenci via Phabricator via cfe-commits
denizevrenci updated this revision to Diff 529140.
denizevrenci added a comment.

Sort tests out a bit more


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152330/new/

https://reviews.llvm.org/D152330

Files:
  clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
  clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.h
  clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp
@@ -0,0 +1,36 @@
+// RUN: %check_clang_tidy -std=c++11,c++14,c++17,c++20 %s bugprone-exception-escape %t -- \
+// RUN: -- -fexceptions
+
+void rethrower() {
+throw;
+}
+
+void callsRethrower() {
+rethrower();
+}
+
+void callsRethrowerNoexcept() noexcept {
+rethrower();
+}
+
+int throwsAndCallsRethrower() noexcept {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'throwsAndCallsRethrower' which should not throw exceptions
+try {
+throw 1;
+} catch(...) {
+rethrower();
+}
+}
+
+int throwsAndCallsCallsRethrower() noexcept {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'throwsAndCallsCallsRethrower' which should not throw exceptions
+try {
+throw 1;
+} catch(...) {
+callsRethrower();
+}
+}
+
+void rethrowerNoexcept() noexcept {
+throw;
+}
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
@@ -36,17 +36,18 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise;
 
 template <
 typename T, bool ThrowInTaskConstructor = false,
 bool ThrowInPromiseConstructor = false, bool ThrowInInitialSuspend = false,
-bool ThrowInGetReturnObject = false, bool ThrowInUnhandledException = false>
+bool ThrowInGetReturnObject = false, bool ThrowInUnhandledException = false,
+bool RethrowInUnhandledException = false>
 struct Task {
   using promise_type =
   Promise;
+  ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException>;
 
   explicit Task(promise_type ) {
 if constexpr (ThrowInTaskConstructor) {
@@ -67,13 +68,13 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Task {
+ThrowInUnhandledException, RethrowInUnhandledException> {
   using promise_type =
   Promise;
+  ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException>;
 
   explicit Task(promise_type ) {
 if constexpr (ThrowInTaskConstructor) {
@@ -92,7 +93,7 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise {
   Promise() {
 if constexpr (ThrowInPromiseConstructor) {
@@ -130,6 +131,8 @@
   void unhandled_exception() {
 if constexpr (ThrowInUnhandledException) {
   throw 1;
+} else if constexpr (RethrowInUnhandledException) {
+  throw;
 }
   }
 
@@ -138,9 +141,9 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise {
+   ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException> {
   Promise() {
 if constexpr (ThrowInPromiseConstructor) {
   throw 1;
@@ -170,6 +173,8 @@
   void unhandled_exception() {
 if constexpr (ThrowInUnhandledException) {
   throw 1;
+} else if constexpr (RethrowInUnhandledException) {
+  throw;
 }
   }
 
@@ -266,6 +271,33 @@
   co_return a / b;
 }
 
+Task
+i_ShouldNotDiag(const int a, const int b) {
+  co_return a / b;
+}
+
+Task
+i_ShouldNotDiagNoexcept(const int a, const int b) noexcept {
+  co_return a / b;
+}
+
+Task
+j_ShouldNotDiag(const int a, const int b) {
+  if (b == 0)
+throw b;
+
+  co_return a / b;
+}
+
+Task
+j_ShouldDiag(const int a, const int b) noexcept {
+  // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: an exception may be thrown in function 'j_ShouldDiag' which should not throw exceptions
+  if (b == 0)
+throw b;
+
+  co_return a / b;
+}
+
 } // namespace coreturn
 
 namespace coyield {
@@ -347,6 +379,33 @@
   co_yield a / b;
 }
 
+Task
+i_ShouldNotDiag(const int a, const int b) {
+  co_yield a / b;
+}
+
+Task
+i_ShouldNotDiagNoexcept(const int a, const int b) noexcept {
+  co_yield a / b;
+}
+
+Task
+j_ShouldNotDiag(const int a, const int b) {
+  if (b == 0)
+throw b;
+
+  co_yield a / b;
+}
+
+Task
+j_ShouldDiag(const 

[PATCH] D152330: [clang-tidy] Check functions called from catch blocks

2023-06-06 Thread Deniz Evrenci via Phabricator via cfe-commits
denizevrenci updated this revision to Diff 529137.
denizevrenci added a comment.

Sort out tests


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152330/new/

https://reviews.llvm.org/D152330

Files:
  clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
  clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.h
  clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp
@@ -0,0 +1,36 @@
+// RUN: %check_clang_tidy -std=c++11,c++14,c++17,c++20 %s bugprone-exception-escape %t -- \
+// RUN: -- -fexceptions
+
+void rethrower() {
+throw;
+}
+
+void callsRethrower() {
+rethrower();
+}
+
+void callsRethrowerNoexcept() noexcept {
+rethrower();
+}
+
+int throwsAndCallsRethrower() noexcept {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'throwsAndCallsRethrower' which should not throw exceptions
+try {
+throw 1;
+} catch(...) {
+rethrower();
+}
+}
+
+int throwsAndCallsCallsRethrower() noexcept {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'throwsAndCallsCallsRethrower' which should not throw exceptions
+try {
+throw 1;
+} catch(...) {
+callsRethrower();
+}
+}
+
+void rethrowerNoexcept() noexcept {
+throw;
+}
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
@@ -36,17 +36,18 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise;
 
 template <
 typename T, bool ThrowInTaskConstructor = false,
 bool ThrowInPromiseConstructor = false, bool ThrowInInitialSuspend = false,
-bool ThrowInGetReturnObject = false, bool ThrowInUnhandledException = false>
+bool ThrowInGetReturnObject = false, bool ThrowInUnhandledException = false,
+bool RethrowInUnhandledException = false>
 struct Task {
   using promise_type =
   Promise;
+  ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException>;
 
   explicit Task(promise_type ) {
 if constexpr (ThrowInTaskConstructor) {
@@ -67,13 +68,13 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Task {
+ThrowInUnhandledException, RethrowInUnhandledException> {
   using promise_type =
   Promise;
+  ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException>;
 
   explicit Task(promise_type ) {
 if constexpr (ThrowInTaskConstructor) {
@@ -92,7 +93,7 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise {
   Promise() {
 if constexpr (ThrowInPromiseConstructor) {
@@ -130,6 +131,8 @@
   void unhandled_exception() {
 if constexpr (ThrowInUnhandledException) {
   throw 1;
+} else if constexpr (RethrowInUnhandledException) {
+  throw;
 }
   }
 
@@ -138,9 +141,9 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise {
+   ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException> {
   Promise() {
 if constexpr (ThrowInPromiseConstructor) {
   throw 1;
@@ -170,6 +173,8 @@
   void unhandled_exception() {
 if constexpr (ThrowInUnhandledException) {
   throw 1;
+} else if constexpr (RethrowInUnhandledException) {
+  throw;
 }
   }
 
@@ -266,6 +271,29 @@
   co_return a / b;
 }
 
+Task
+i_ShouldNotDiag(const int a, const int b) {
+  co_return a / b;
+}
+
+Task
+i_ShouldNotDiagNoexcept(const int a, const int b) noexcept {
+  co_return a / b;
+}
+
+Task
+j_ShouldNotDiag(const int a, const int b) {
+  throw 1;
+  co_return a / b;
+}
+
+Task
+j_ShouldDiag(const int a, const int b) noexcept {
+  // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: an exception may be thrown in function 'j_ShouldDiag' which should not throw exceptions
+  throw 1;
+  co_return a / b;
+}
+
 } // namespace coreturn
 
 namespace coyield {
@@ -347,6 +375,29 @@
   co_yield a / b;
 }
 
+Task
+i_ShouldNotDiag(const int a, const int b) {
+  co_yield a / b;
+}
+
+Task
+i_ShouldNotDiagNoexcept(const int a, const int b) noexcept {
+  co_yield a / b;
+}
+
+Task
+j_ShouldNotDiag(const int a, const int b) {
+  throw 1;
+  co_yield a / b;
+}
+
+Task
+j_ShouldDiag(const int a, const int b) noexcept {
+  // CHECK-MESSAGES: :[[@LINE-1]]:1: 

[PATCH] D152330: [clang-tidy] Check functions called from catch blocks

2023-06-06 Thread Deniz Evrenci via Phabricator via cfe-commits
denizevrenci updated this revision to Diff 529134.
denizevrenci added a comment.

Rebase on main


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152330/new/

https://reviews.llvm.org/D152330

Files:
  clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
  clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.h
  clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp
@@ -0,0 +1,36 @@
+// RUN: %check_clang_tidy -std=c++11,c++14,c++17,c++20 %s bugprone-exception-escape %t -- \
+// RUN: -- -fexceptions
+
+void rethrower() {
+throw;
+}
+
+void callsRethrower() {
+rethrower();
+}
+
+void callsRethrowerNoexcept() noexcept {
+rethrower();
+}
+
+int throwsAndCallsRethrower() noexcept {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'throwsAndCallsRethrower' which should not throw exceptions
+try {
+throw 1;
+} catch(...) {
+rethrower();
+}
+}
+
+int throwsAndCallsCallsRethrower() noexcept {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'throwsAndCallsCallsRethrower' which should not throw exceptions
+try {
+throw 1;
+} catch(...) {
+callsRethrower();
+}
+}
+
+void rethrowerNoexcept() noexcept {
+throw;
+}
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
@@ -36,17 +36,18 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise;
 
 template <
 typename T, bool ThrowInTaskConstructor = false,
 bool ThrowInPromiseConstructor = false, bool ThrowInInitialSuspend = false,
-bool ThrowInGetReturnObject = false, bool ThrowInUnhandledException = false>
+bool ThrowInGetReturnObject = false, bool ThrowInUnhandledException = false,
+bool RethrowInUnhandledException = false>
 struct Task {
   using promise_type =
   Promise;
+  ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException>;
 
   explicit Task(promise_type ) {
 if constexpr (ThrowInTaskConstructor) {
@@ -67,13 +68,13 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Task {
+ThrowInUnhandledException, RethrowInUnhandledException> {
   using promise_type =
   Promise;
+  ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException>;
 
   explicit Task(promise_type ) {
 if constexpr (ThrowInTaskConstructor) {
@@ -92,7 +93,7 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise {
   Promise() {
 if constexpr (ThrowInPromiseConstructor) {
@@ -130,6 +131,8 @@
   void unhandled_exception() {
 if constexpr (ThrowInUnhandledException) {
   throw 1;
+} else if constexpr (RethrowInUnhandledException) {
+  throw;
 }
   }
 
@@ -138,9 +141,9 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise {
+   ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException> {
   Promise() {
 if constexpr (ThrowInPromiseConstructor) {
   throw 1;
@@ -170,6 +173,8 @@
   void unhandled_exception() {
 if constexpr (ThrowInUnhandledException) {
   throw 1;
+} else if constexpr (RethrowInUnhandledException) {
+  throw;
 }
   }
 
@@ -266,6 +271,23 @@
   co_return a / b;
 }
 
+Task
+i_ShouldNotDiag(const int a, const int b) {
+  co_return a / b;
+}
+
+Task
+i_ShouldNotDiagNoexcept(const int a, const int b) noexcept {
+  co_return a / b;
+}
+
+Task
+i_ShouldDiag(const int a, const int b) noexcept {
+  // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: an exception may be thrown in function 'i_ShouldDiag' which should not throw exceptions
+  throw 1;
+  co_return a / b;
+}
+
 } // namespace coreturn
 
 namespace coyield {
@@ -347,6 +369,23 @@
   co_yield a / b;
 }
 
+Task
+i_ShouldNotDiag(const int a, const int b) {
+  co_yield a / b;
+}
+
+Task
+i_ShouldNotDiagNoexcept(const int a, const int b) noexcept {
+  co_yield a / b;
+}
+
+Task
+i_ShouldDiag(const int a, const int b) noexcept {
+  // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: an exception may be thrown in function 'i_ShouldDiag' which should not throw exceptions
+  throw 1;
+  co_yield a / b;
+}
+
 } // namespace coyield
 
 namespace 

[PATCH] D152330: [clang-tidy] Check functions called from catch blocks

2023-06-06 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu accepted this revision.
ChuanqiXu added a comment.
This revision is now accepted and ready to land.

LGTM. And please wait for several days for other reviewers.




Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp:132-136
 if constexpr (ThrowInUnhandledException) {
   throw 1;
+} else if constexpr (RethrowInUnhandledException) {
+  throw;
 }

denizevrenci wrote:
> ChuanqiXu wrote:
> > I don't know clang-tidy a lot. But is these two branches different in 
> > clang-tidy really?
> Yes, rethrows are handled differently than throw expressions with arguments. 
> You can find the relevant implementation in ExceptionAnalyzer.cpp:[462:475].
OK, sounds good to me. 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152330/new/

https://reviews.llvm.org/D152330

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D152330: [clang-tidy] Check functions called from catch blocks

2023-06-06 Thread Deniz Evrenci via Phabricator via cfe-commits
denizevrenci added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp:132-136
 if constexpr (ThrowInUnhandledException) {
   throw 1;
+} else if constexpr (RethrowInUnhandledException) {
+  throw;
 }

ChuanqiXu wrote:
> I don't know clang-tidy a lot. But is these two branches different in 
> clang-tidy really?
Yes, rethrows are handled differently than throw expressions with arguments. 
You can find the relevant implementation in ExceptionAnalyzer.cpp:[462:475].


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152330/new/

https://reviews.llvm.org/D152330

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D152330: [clang-tidy] Check functions called from catch blocks

2023-06-06 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp:132-136
 if constexpr (ThrowInUnhandledException) {
   throw 1;
+} else if constexpr (RethrowInUnhandledException) {
+  throw;
 }

I don't know clang-tidy a lot. But is these two branches different in 
clang-tidy really?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152330/new/

https://reviews.llvm.org/D152330

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D152330: [clang-tidy] Check functions called from catch blocks

2023-06-06 Thread Deniz Evrenci via Phabricator via cfe-commits
denizevrenci created this revision.
denizevrenci added reviewers: njames93, PiotrZSL, ChuanqiXu.
Herald added subscribers: carlosgalvezp, xazax.hun.
Herald added a project: All.
denizevrenci requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

These functions can rethrow a current exception that is caught by the
catch block. We can pass the currently caught excections to the function
declaration analyzer just like the statement analyzer to handle this
case.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152330

Files:
  clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
  clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.h
  clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
  
clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-rethrow.cpp
@@ -0,0 +1,36 @@
+// RUN: %check_clang_tidy -std=c++11,c++14,c++17,c++20 %s bugprone-exception-escape %t -- \
+// RUN: -- -fexceptions
+
+void rethrower() {
+throw;
+}
+
+void callsRethrower() {
+rethrower();
+}
+
+void callsRethrowerNoexcept() noexcept {
+rethrower();
+}
+
+int throwsAndCallsRethrower() noexcept {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'throwsAndCallsRethrower' which should not throw exceptions
+try {
+throw 1;
+} catch(...) {
+rethrower();
+}
+}
+
+int throwsAndCallsCallsRethrower() noexcept {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'throwsAndCallsCallsRethrower' which should not throw exceptions
+try {
+throw 1;
+} catch(...) {
+callsRethrower();
+}
+}
+
+void rethrowerNoexcept() noexcept {
+throw;
+}
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro.cpp
@@ -36,17 +36,18 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise;
 
 template <
 typename T, bool ThrowInTaskConstructor = false,
 bool ThrowInPromiseConstructor = false, bool ThrowInInitialSuspend = false,
-bool ThrowInGetReturnObject = false, bool ThrowInUnhandledException = false>
+bool ThrowInGetReturnObject = false, bool ThrowInUnhandledException = false,
+bool RethrowInUnhandledException = false>
 struct Task {
   using promise_type =
   Promise;
+  ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException>;
 
   explicit Task(promise_type ) {
 if constexpr (ThrowInTaskConstructor) {
@@ -67,13 +68,13 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Task {
+ThrowInUnhandledException, RethrowInUnhandledException> {
   using promise_type =
   Promise;
+  ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException>;
 
   explicit Task(promise_type ) {
 if constexpr (ThrowInTaskConstructor) {
@@ -92,7 +93,7 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise {
   Promise() {
 if constexpr (ThrowInPromiseConstructor) {
@@ -130,6 +131,8 @@
   void unhandled_exception() {
 if constexpr (ThrowInUnhandledException) {
   throw 1;
+} else if constexpr (RethrowInUnhandledException) {
+  throw;
 }
   }
 
@@ -138,9 +141,9 @@
 
 template 
+  bool ThrowInUnhandledException, bool RethrowInUnhandledException>
 struct Promise {
+   ThrowInGetReturnObject, ThrowInUnhandledException, RethrowInUnhandledException> {
   Promise() {
 if constexpr (ThrowInPromiseConstructor) {
   throw 1;
@@ -170,6 +173,8 @@
   void unhandled_exception() {
 if constexpr (ThrowInUnhandledException) {
   throw 1;
+} else if constexpr (RethrowInUnhandledException) {
+  throw;
 }
   }
 
@@ -266,6 +271,23 @@
   co_return a / b;
 }
 
+Task
+i_ShouldNotDiag(const int a, const int b) {
+  co_return a / b;
+}
+
+Task
+i_ShouldNotDiagNoexcept(const int a, const int b) noexcept {
+  co_return a / b;
+}
+
+Task
+i_ShouldDiag(const int a, const int b) noexcept {
+  // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: an exception may be thrown in function 'i_ShouldDiag' which should not throw exceptions
+  throw 1;
+  co_return a / b;
+}
+
 } // namespace coreturn
 
 namespace coyield {
@@ -347,6 +369,23 @@
   co_yield a / b;
 }
 
+Task
+i_ShouldNotDiag(const int a, const int b) {
+  co_yield a / b;
+}
+