https://github.com/Qwinci updated 
https://github.com/llvm/llvm-project/pull/151836

>From 472cdf4a8433c776a3d955a2b8a7dbe71d85f763 Mon Sep 17 00:00:00 2001
From: Qwinci <qwinci...@gmail.com>
Date: Sun, 3 Aug 2025 16:18:37 +0300
Subject: [PATCH] [clang][sema]: Error when SEH __try is used in a function
 with C++ dtors

SEH __try is not allowed in a function with C++ objects that have non-trivial
destructors.
---
 .../clang/Basic/DiagnosticSemaKinds.td        |  2 +
 clang/lib/Sema/AnalysisBasedWarnings.cpp      | 45 +++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f4f1bc67724a1..f25584cb89bcf 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8264,6 +8264,8 @@ def err_mixing_cxx_try_seh_try : Error<
   "in the same function as SEH '__try'">;
 def err_seh_try_unsupported : Error<
   "SEH '__try' is not supported on this target">;
+def err_seh_try_dtor : Error<"cannot use C++ object with a destructor "
+                             "in the same function as SEH '__try'">;
 def note_conflicting_try_here : Note<
   "conflicting %0 here">;
 def warn_jump_out_of_seh_finally : Warning<
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp 
b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index f21e571e6e0ce..2e1ec446ed7e1 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -399,6 +399,47 @@ static bool isNoexcept(const FunctionDecl *FD) {
   return false;
 }
 
+//===----------------------------------------------------------------------===//
+// Check for SEH __try in a function with C++ objects that have destructors.
+//===----------------------------------------------------------------------===//
+
+static void emitDiagForSehTryUnwind(Sema &S, CFGElement &E) {
+  if (auto AD = E.getAs<CFGAutomaticObjDtor>()) {
+    const auto *VD = AD->getVarDecl();
+    S.Diag(VD->getLocation(), diag::err_seh_try_dtor);
+  } else if (auto TD = E.getAs<CFGTemporaryDtor>()) {
+    const auto *E = TD->getBindTemporaryExpr();
+    S.Diag(E->getBeginLoc(), diag::err_seh_try_dtor);
+  } else
+    llvm_unreachable("emitDiagForSehTryUnwind should only be used with "
+                     "AutomaticObjectDtor or TemporaryDtor");
+}
+
+static void checkSehTryNeedsUnwind(Sema &S, const FunctionDecl *FD,
+                                   AnalysisDeclContext &AC) {
+  CFG *BodyCFG = AC.getCFG();
+  if (!BodyCFG)
+    return;
+  if (BodyCFG->getExit().pred_empty())
+    return;
+  if (!FD->usesSEHTry())
+    return;
+
+  llvm::BitVector Reachable(BodyCFG->getNumBlockIDs());
+  clang::reachable_code::ScanReachableFromBlock(&BodyCFG->getEntry(),
+                                                Reachable);
+  for (CFGBlock *B : *BodyCFG) {
+    if (!Reachable[B->getBlockID()])
+      continue;
+    for (CFGElement &E : *B) {
+      auto Kind = E.getKind();
+      if (Kind == CFGElement::AutomaticObjectDtor ||
+          Kind == CFGElement::TemporaryDtor)
+        emitDiagForSehTryUnwind(S, E);
+    }
+  }
+}
+
 
//===----------------------------------------------------------------------===//
 // Check for missing return value.
 
//===----------------------------------------------------------------------===//
@@ -2821,6 +2862,10 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
       if (S.getLangOpts().CPlusPlus && !fscope->isCoroutine() && 
isNoexcept(FD))
         checkThrowInNonThrowingFunc(S, FD, AC);
 
+  if (S.getLangOpts().CPlusPlus)
+    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+      checkSehTryNeedsUnwind(S, FD, AC);
+
   // If none of the previous checks caused a CFG build, trigger one here
   // for the logical error handler.
   if (LogicalErrorHandler::hasActiveDiagnostics(Diags, D->getBeginLoc())) {

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

Reply via email to