https://github.com/GkvJwa updated 
https://github.com/llvm/llvm-project/pull/172287

>From e1a11aa30ccf63162de6f7d9507460db9614362b Mon Sep 17 00:00:00 2001
From: GkvJwa <[email protected]>
Date: Thu, 18 Dec 2025 00:30:02 +0800
Subject: [PATCH 1/3] Use sema

---
 clang/lib/Sema/SemaStmt.cpp           | 61 +++++++++++++++++++++++++++
 clang/test/SemaCXX/exceptions-seh.cpp | 42 ++++++++++++++++++
 2 files changed, 103 insertions(+)

diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 1b1643250d05e..a32d5c37b4605 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -4515,6 +4515,55 @@ void Sema::DiagnoseExceptionUse(SourceLocation Loc, bool 
IsTry) {
     targetDiag(Loc, diag::err_exceptions_disabled) << (IsTry ? "try" : 
"throw");
 }
 
+// Walk the statement subtree and return the first statement that
+// contains a non-trivial C++ object that would require destruction at
+// scope exit, or nullptr if none was found.
+static const Stmt *findNonTrivialObject(const Stmt *S) {
+  if (!S)
+    return nullptr;
+
+  llvm::SmallVector<const Stmt *, 32> Worklist;
+  Worklist.push_back(S);
+
+  while (!Worklist.empty()) {
+    const Stmt *Cur = Worklist.pop_back_val();
+    if (!Cur)
+      continue;
+
+    if (isa<CXXThrowExpr>(Cur))
+      return nullptr;
+
+    if (isa<CXXConstructExpr>(Cur) || isa<CXXTemporaryObjectExpr>(Cur) ||
+        isa<CXXNewExpr>(Cur)) {
+      return Cur;
+    }
+
+    if (isa<CXXBindTemporaryExpr>(Cur) || isa<CXXDeleteExpr>(Cur)) {
+      return Cur;
+    }
+
+    if (const auto *DS = dyn_cast<DeclStmt>(Cur)) {
+      for (const Decl *D : DS->decls()) {
+        if (const auto *VD = dyn_cast<VarDecl>(D)) {
+          QualType QT = VD->getType();
+          if (const CXXRecordDecl *RD = QT->getAsCXXRecordDecl()) {
+            if (const CXXDestructorDecl *DD = RD->getDestructor()) {
+              if (!DD->isTrivial())
+                return DS;
+            }
+          }
+        }
+      }
+    }
+
+    for (const Stmt *Child : Cur->children())
+      if (Child)
+        Worklist.push_back(Child);
+  }
+
+  return nullptr;
+}
+
 StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc,
                                   Stmt *TryBlock, Stmt *Handler) {
   assert(TryBlock && Handler);
@@ -4531,6 +4580,10 @@ StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, 
SourceLocation TryLoc,
                   ? "'try'"
                   : "'@try'");
     }
+    if (const Stmt *Offending = findNonTrivialObject(TryBlock)) {
+      return StmtError(
+          Diag(Offending->getBeginLoc(), diag::err_seh_try_outside_functions));
+    }
   }
 
   FSI->setHasSEHTry(TryLoc);
@@ -4562,6 +4615,14 @@ StmtResult Sema::ActOnSEHExceptBlock(SourceLocation Loc, 
Expr *FilterExpr,
         Diag(FilterExpr->getExprLoc(), diag::err_filter_expression_integral)
         << FTy);
   }
+  // Disallow non-trivial C++ objects in an SEH __except handler. Skip
+  // this diagnostic when Borland extensions are enabled.
+  if (!getLangOpts().Borland) {
+    if (const Stmt *Offending = findNonTrivialObject(Block)) {
+      return StmtError(
+          Diag(Offending->getBeginLoc(), diag::err_seh_try_outside_functions));
+    }
+  }
   return SEHExceptStmt::Create(Context, Loc, FilterExpr, Block);
 }
 
diff --git a/clang/test/SemaCXX/exceptions-seh.cpp 
b/clang/test/SemaCXX/exceptions-seh.cpp
index 02bb786160dcf..bdc369ff767da 100644
--- a/clang/test/SemaCXX/exceptions-seh.cpp
+++ b/clang/test/SemaCXX/exceptions-seh.cpp
@@ -126,3 +126,45 @@ void instantiate_dependent_filter() {
   dependent_filter<int>();
   dependent_filter<NotInteger>(); // expected-note {{requested here}}
 }
+
+int puts(const char *);
+class CheckError {
+public:
+ static CheckError Check(const char* msg);
+
+ ~CheckError();
+};
+
+int foo__try(const int* f) {
+  int e;
+  __try {
+    CheckError::Check("null pointer"); // expected-error{{cannot use SEH 
'__try' in blocks}}
+    e = *f;
+  } __except (1) {
+    puts("Caught a C-based exception.");
+  }
+  return e;
+}
+
+int foo__except(const int* f) {
+  int e;
+  __try {
+    puts("null pointer");
+    e = *f;
+  } __except (1) {
+    CheckError::Check("Caught a C-based exception."); // 
expected-error{{cannot use SEH '__try' in blocks}}
+  }
+  return e;
+}
+
+// has throw should work
+int foo__except_with_throw(const int* f) {
+  int e;
+  __try {
+    puts("null pointer");
+    e = *f;
+  } __except (1) {
+    throw(CheckError::Check("Caught a C-based exception."));
+  }
+  return e;
+}

>From 86db2c253868a1fb867497c88ee06a2d938696c1 Mon Sep 17 00:00:00 2001
From: GkvJwa <[email protected]>
Date: Sun, 21 Dec 2025 16:24:55 +0800
Subject: [PATCH 2/3] Revert "Use sema"

This reverts commit e1a11aa30ccf63162de6f7d9507460db9614362b.
---
 clang/lib/Sema/SemaStmt.cpp           | 61 ---------------------------
 clang/test/SemaCXX/exceptions-seh.cpp | 42 ------------------
 2 files changed, 103 deletions(-)

diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index a32d5c37b4605..1b1643250d05e 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -4515,55 +4515,6 @@ void Sema::DiagnoseExceptionUse(SourceLocation Loc, bool 
IsTry) {
     targetDiag(Loc, diag::err_exceptions_disabled) << (IsTry ? "try" : 
"throw");
 }
 
-// Walk the statement subtree and return the first statement that
-// contains a non-trivial C++ object that would require destruction at
-// scope exit, or nullptr if none was found.
-static const Stmt *findNonTrivialObject(const Stmt *S) {
-  if (!S)
-    return nullptr;
-
-  llvm::SmallVector<const Stmt *, 32> Worklist;
-  Worklist.push_back(S);
-
-  while (!Worklist.empty()) {
-    const Stmt *Cur = Worklist.pop_back_val();
-    if (!Cur)
-      continue;
-
-    if (isa<CXXThrowExpr>(Cur))
-      return nullptr;
-
-    if (isa<CXXConstructExpr>(Cur) || isa<CXXTemporaryObjectExpr>(Cur) ||
-        isa<CXXNewExpr>(Cur)) {
-      return Cur;
-    }
-
-    if (isa<CXXBindTemporaryExpr>(Cur) || isa<CXXDeleteExpr>(Cur)) {
-      return Cur;
-    }
-
-    if (const auto *DS = dyn_cast<DeclStmt>(Cur)) {
-      for (const Decl *D : DS->decls()) {
-        if (const auto *VD = dyn_cast<VarDecl>(D)) {
-          QualType QT = VD->getType();
-          if (const CXXRecordDecl *RD = QT->getAsCXXRecordDecl()) {
-            if (const CXXDestructorDecl *DD = RD->getDestructor()) {
-              if (!DD->isTrivial())
-                return DS;
-            }
-          }
-        }
-      }
-    }
-
-    for (const Stmt *Child : Cur->children())
-      if (Child)
-        Worklist.push_back(Child);
-  }
-
-  return nullptr;
-}
-
 StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc,
                                   Stmt *TryBlock, Stmt *Handler) {
   assert(TryBlock && Handler);
@@ -4580,10 +4531,6 @@ StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, 
SourceLocation TryLoc,
                   ? "'try'"
                   : "'@try'");
     }
-    if (const Stmt *Offending = findNonTrivialObject(TryBlock)) {
-      return StmtError(
-          Diag(Offending->getBeginLoc(), diag::err_seh_try_outside_functions));
-    }
   }
 
   FSI->setHasSEHTry(TryLoc);
@@ -4615,14 +4562,6 @@ StmtResult Sema::ActOnSEHExceptBlock(SourceLocation Loc, 
Expr *FilterExpr,
         Diag(FilterExpr->getExprLoc(), diag::err_filter_expression_integral)
         << FTy);
   }
-  // Disallow non-trivial C++ objects in an SEH __except handler. Skip
-  // this diagnostic when Borland extensions are enabled.
-  if (!getLangOpts().Borland) {
-    if (const Stmt *Offending = findNonTrivialObject(Block)) {
-      return StmtError(
-          Diag(Offending->getBeginLoc(), diag::err_seh_try_outside_functions));
-    }
-  }
   return SEHExceptStmt::Create(Context, Loc, FilterExpr, Block);
 }
 
diff --git a/clang/test/SemaCXX/exceptions-seh.cpp 
b/clang/test/SemaCXX/exceptions-seh.cpp
index bdc369ff767da..02bb786160dcf 100644
--- a/clang/test/SemaCXX/exceptions-seh.cpp
+++ b/clang/test/SemaCXX/exceptions-seh.cpp
@@ -126,45 +126,3 @@ void instantiate_dependent_filter() {
   dependent_filter<int>();
   dependent_filter<NotInteger>(); // expected-note {{requested here}}
 }
-
-int puts(const char *);
-class CheckError {
-public:
- static CheckError Check(const char* msg);
-
- ~CheckError();
-};
-
-int foo__try(const int* f) {
-  int e;
-  __try {
-    CheckError::Check("null pointer"); // expected-error{{cannot use SEH 
'__try' in blocks}}
-    e = *f;
-  } __except (1) {
-    puts("Caught a C-based exception.");
-  }
-  return e;
-}
-
-int foo__except(const int* f) {
-  int e;
-  __try {
-    puts("null pointer");
-    e = *f;
-  } __except (1) {
-    CheckError::Check("Caught a C-based exception."); // 
expected-error{{cannot use SEH '__try' in blocks}}
-  }
-  return e;
-}
-
-// has throw should work
-int foo__except_with_throw(const int* f) {
-  int e;
-  __try {
-    puts("null pointer");
-    e = *f;
-  } __except (1) {
-    throw(CheckError::Check("Caught a C-based exception."));
-  }
-  return e;
-}

>From d56028a47bcdf940f3d73154a043240ec3db7777 Mon Sep 17 00:00:00 2001
From: GkvJwa <[email protected]>
Date: Sun, 21 Dec 2025 16:32:27 +0800
Subject: [PATCH 3/3] Move to CodeGen

---
 clang/lib/CodeGen/CGException.cpp        | 24 ++++++++++++++++++++++++
 clang/test/CodeGenCXX/exceptions-seh.cpp | 20 ++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/clang/lib/CodeGen/CGException.cpp 
b/clang/lib/CodeGen/CGException.cpp
index e9d20672ce185..3fc87e0e2456b 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -2170,6 +2170,26 @@ void CodeGenFunction::pushSEHCleanup(CleanupKind Kind,
   EHStack.pushCleanup<PerformSEHFinally>(Kind, FinallyFunc);
 }
 
+static bool StmtCanNotSEH(const Stmt *S) {
+  if (!S)
+    return false;
+
+  if (isa<CXXThrowExpr>(S))
+    return false;
+
+  if (isa<CXXBindTemporaryExpr>(S))
+    return true;
+
+  if (isa<CXXConstructExpr>(S))
+    return true;
+
+  for (const auto *child : S->children())
+    if (StmtCanNotSEH(child))
+      return true;
+
+  return false;
+}
+
 void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) {
   CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);
   HelperCGF.ParentCGF = this;
@@ -2186,6 +2206,10 @@ void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt 
&S) {
   // Otherwise, we must have an __except block.
   const SEHExceptStmt *Except = S.getExceptHandler();
   assert(Except);
+  if (!CGM.getLangOpts().Borland &&
+      (StmtCanNotSEH(&S) || StmtCanNotSEH(Except)))
+    CGM.getDiags().Report(CurFuncDecl->getLocation(),
+                          diag::err_seh_try_outside_functions);
   EHCatchScope *CatchScope = EHStack.pushCatch(1);
   SEHCodeSlotStack.push_back(
       CreateMemTemp(getContext().IntTy, "__exception_code"));
diff --git a/clang/test/CodeGenCXX/exceptions-seh.cpp 
b/clang/test/CodeGenCXX/exceptions-seh.cpp
index bb374dd1f5bd5..39c39b179983d 100644
--- a/clang/test/CodeGenCXX/exceptions-seh.cpp
+++ b/clang/test/CodeGenCXX/exceptions-seh.cpp
@@ -4,6 +4,10 @@
 // RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s 
-triple=x86_64-windows-msvc -emit-llvm \
 // RUN:         -o - -mconstructor-aliases -O1 -disable-llvm-passes | \
 // RUN:         FileCheck %s --check-prefix=CHECK --check-prefix=NOCXX
+// RUN: %clang_cc1 -triple x86_64-windows -fasync-exceptions -fcxx-exceptions 
-fexceptions \
+// RUN:         -x c++ -emit-llvm -verify %s -DERR1
+// RUN: %clang_cc1 -triple x86_64-windows -fasync-exceptions -fcxx-exceptions 
-fexceptions \
+// RUN:         -x c++ -emit-llvm -verify %s -DERR2
 
 extern "C" unsigned long _exception_code();
 extern "C" void might_throw();
@@ -175,3 +179,19 @@ void use_inline() {
 // CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} }
 
 void seh_in_noexcept() noexcept { __try {} __finally {} }
+
+#if defined(ERR1)
+void seh_unwinding() { // expected-error{{cannot use SEH '__try' in blocks}}
+  __try {
+    HasCleanup x;
+  } __except (1) {
+  }
+}
+#elif defined(ERR2)
+void seh_unwinding() { // expected-error{{cannot use SEH '__try' in blocks}}
+  __try {
+  } __except (1) {
+    HasCleanup x;
+  }
+}
+#endif

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

Reply via email to