[clang-tools-extra] [clang-tidy] Fix modernize-use-noexcept crash on unparsed exception specs (PR #218256)

via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 24 06:48:47 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-tidy

Author: Hadong Lee (ChrisLee02)

<details>
<summary>Changes</summary>

A failed template instantiation can leave a function type with an `EST_Unparsed` exception specification. 
`modernize-use-noexcept` currently calls `FunctionProtoType::isNothrow()` for that type, which reaches an unreachable path in `FunctionProtoType::canThrow()`.

This fixes the crash by skipping unparsed exception specifications before querying whether the function is non-throwing.

Fixes #<!-- -->214291

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


2 Files Affected:

- (modified) clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp (+2-1) 
- (added) clang-tools-extra/test/clang-tidy/checkers/modernize/use-noexcept-unparsed-exception-spec.cpp (+12) 


``````````diff
diff --git a/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp
index 6bd5485abbac9..4641d56654e26 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp
@@ -76,7 +76,8 @@ void UseNoexceptCheck::check(const MatchFinder::MatchResult &Result) {
   }
 
   assert(FnTy && "FunctionProtoType is null.");
-  if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType()))
+  if (FnTy->getExceptionSpecType() == EST_Unparsed ||
+      isUnresolvedExceptionSpec(FnTy->getExceptionSpecType()))
     return;
 
   assert(Range.isValid() && "Exception Source Range is invalid.");
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-noexcept-unparsed-exception-spec.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-noexcept-unparsed-exception-spec.cpp
new file mode 100644
index 0000000000000..b7967e8558ac5
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-noexcept-unparsed-exception-spec.cpp
@@ -0,0 +1,12 @@
+// RUN: %check_clang_tidy -std=c++11,c++14 -check-suffix=COMMON -expect-clang-tidy-error %s modernize-use-noexcept %t
+// RUN: %check_clang_tidy -std=c++17-or-later -check-suffixes=COMMON,CXX17 -expect-clang-tidy-error %s modernize-use-noexcept %t
+
+struct S {
+  template <typename T>
+  static void f() throw(typename T::X);
+  // CHECK-MESSAGES-CXX17: :[[@LINE-1]]:19: error: ISO C++17 does not allow dynamic exception specifications [clang-diagnostic-dynamic-exception-spec]
+  // CHECK-MESSAGES-COMMON: :[[@LINE-2]]:19: warning: dynamic exception specification 'throw(typename T::X)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
+
+  typedef decltype(f<S>()) X;
+  // CHECK-MESSAGES-COMMON: :[[@LINE-1]]:20: error: exception specification is not available until end of class definition [clang-diagnostic-error]
+};

``````````

</details>


https://github.com/llvm/llvm-project/pull/218256


More information about the cfe-commits mailing list