llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-tidy

Author: Zeyi Xu (zeyi2)

<details>
<summary>Changes</summary>

`ExceptionAnalyzer` represents exceptions of unknown type with a null `Type`, 
but some consumers dereferenced it unconditionally, resulting in a crash when 
`TreatFunctionsWithoutSpecificationAsThrowing` is enabled. This commit fixes 
the problem by skipping type-dependent processing for unknown exceptions.

Fixes #<!-- -->217649

---
Full diff: https://github.com/llvm/llvm-project/pull/218067.diff


4 Files Affected:

- (modified) clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp (+4) 
- (modified) clang-tools-extra/docs/ReleaseNotes.md (+5-1) 
- (added) 
clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro-unknown.cpp
 (+42) 
- (modified) 
clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-treat-functions-without-specification-as-throwing.cpp
 (+11) 


``````````diff
diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp 
b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
index 7decd18dd25b9..f414272ba15bd 100644
--- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
+++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
@@ -362,6 +362,8 @@ ExceptionAnalyzer::ExceptionInfo::filterByCatch(const Type 
*HandlerTy,
   SmallVector<const Type *, 8> TypesToDelete;
   for (const auto &ThrownException : ThrownExceptions) {
     const Type *ExceptionTy = ThrownException.getFirst();
+    if (!ExceptionTy)
+      continue;
     const CanQualType ExceptionCanTy =
         ExceptionTy->getCanonicalTypeUnqualified();
     const CanQualType HandlerCanTy = HandlerTy->getCanonicalTypeUnqualified();
@@ -607,6 +609,8 @@ ExceptionAnalyzer::throwsException(const Stmt *St,
                                   Excs.getExceptions(), CallStack));
     for (const auto &Exception : Excs.getExceptions()) {
       const Type *ExcType = Exception.getFirst();
+      if (!ExcType)
+        continue;
       if (const CXXRecordDecl *ThrowableRec = ExcType->getAsCXXRecordDecl()) {
         const ExceptionInfo DestructorExcs = throwsException(
             ThrowableRec->getDestructor(), Caught, CallStack, 
SourceLocation{});
diff --git a/clang-tools-extra/docs/ReleaseNotes.md 
b/clang-tools-extra/docs/ReleaseNotes.md
index 9cead803ad0e5..69660191e0077 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -118,6 +118,10 @@ infrastructure are described first, followed by 
tool-specific sections.
 
 #### Changes in existing checks
 
+- Fixed crashes in {doc}`bugprone-exception-escape
+  <clang-tidy/checks/bugprone/exception-escape>` when analyzing exceptions of
+  unknown type with `TreatFunctionsWithoutSpecificationAsThrowing` enabled.
+
 - Fixed a crash in {doc}`bugprone-misplaced-operator-in-strlen-in-alloc
   <clang-tidy/checks/bugprone/misplaced-operator-in-strlen-in-alloc>` when
   checking an array new expression without a size expression.
@@ -129,7 +133,7 @@ infrastructure are described first, followed by 
tool-specific sections.
 - Improved {doc}`cppcoreguidelines-pro-type-member-init
   <clang-tidy/checks/cppcoreguidelines/pro-type-member-init>` check by treating
   `std::array` the same as built-in arrays when `IgnoreArrays` option is 
enabled.
-  
+
 - Improved {doc}`cppcoreguidelines-use-enum-class
   <clang-tidy/checks/cppcoreguidelines/use-enum-class>` check by omitting 
unnamed enums from the `enum class` requirement, as previously the check 
suggested users an ill-formed fix.
 
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro-unknown.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro-unknown.cpp
new file mode 100644
index 0000000000000..a2325c401c404
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-coro-unknown.cpp
@@ -0,0 +1,42 @@
+// RUN: %check_clang_tidy -std=c++20-or-later %s bugprone-exception-escape %t 
-- \
+// RUN:     -config='{"CheckOptions": { \
+// RUN:       
"bugprone-exception-escape.TreatFunctionsWithoutSpecificationAsThrowing": 
"OnlyUndefined" \
+// RUN:     }}' -- -fexceptions
+
+namespace std {
+
+template <class Ret, typename... T> struct coroutine_traits {
+  using promise_type = typename Ret::promise_type;
+};
+
+template <class Promise = void> struct coroutine_handle {
+  template <class OtherPromise>
+  coroutine_handle(coroutine_handle<OtherPromise>) noexcept;
+  static coroutine_handle from_address(void *) noexcept;
+};
+
+struct suspend_never {
+  bool await_ready() noexcept { return true; }
+  void await_suspend(coroutine_handle<>) noexcept {}
+  void await_resume() noexcept {}
+};
+
+} // namespace std
+
+struct Task {
+  struct promise_type {
+    Task get_return_object() noexcept { return {}; }
+    std::suspend_never initial_suspend() noexcept { return {}; }
+    std::suspend_never final_suspend() noexcept { return {}; }
+    void return_void() noexcept {}
+    void unhandled_exception() noexcept {}
+  };
+};
+
+void undefined();
+
+Task calls_undefined() noexcept {
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in 
function 'calls_undefined' which should not throw exceptions
+  undefined();
+  co_return;
+}
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-treat-functions-without-specification-as-throwing.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-treat-functions-without-specification-as-throwing.cpp
index ee9f19b5a2896..051c88496ec21 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-treat-functions-without-specification-as-throwing.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-treat-functions-without-specification-as-throwing.cpp
@@ -47,6 +47,17 @@ void calls_unknown_caught() noexcept {
   }
 }
 
+struct Error {};
+
+void calls_unknown_typed_catch() noexcept {
+  // CHECK-MESSAGES-ALL: :[[@LINE-1]]:6: warning: an exception may be thrown 
in function 'calls_unknown_typed_catch' which should not throw exceptions
+  // CHECK-MESSAGES-UNDEFINED: :[[@LINE-2]]:6: warning: an exception may be 
thrown in function 'calls_unknown_typed_catch' which should not throw exceptions
+  try {
+    extern_declared();
+  } catch (const Error &) {
+  }
+}
+
 void definitely_nothrow() noexcept {}
 
 void calls_nothrow() noexcept {

``````````

</details>


https://github.com/llvm/llvm-project/pull/218067
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to