llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: None (GkvJwa)

<details>
<summary>Changes</summary>

Consider the following code:
```
class CheckError {
 public:
  static CheckError Check();

  ~CheckError();
};

void Foo(const int* p) {
  int d = 0;
  __try {
    d = *p;
  } __except (EXCEPTION_EXECUTE_HANDLER) {
    ::CheckError::Check();
  }
}

```

The following error will occur in mscv.
```
error C2712: Cannot use __try in functions that require object unwinding
```

However, using LLVM /EHa will cause it to crash.
```
llvm::SmallVectorTemplateCommon&lt;llvm::SEHUnwindMapEntry,void&gt;::operator[](unsigned
 __int64 idx) Line 295  C++
llvm::calculateSEHStateForAsynchEH(const llvm::BasicBlock * BB, int State, 
llvm::WinEHFuncInfo &amp; EHInfo) Line 346   C++
llvm::calculateSEHStateNumbers(const llvm::Function * Fn, llvm::WinEHFuncInfo 
&amp; FuncInfo) Line 612  C++
llvm::FunctionLoweringInfo::set(const llvm::Function &amp; fn, 
llvm::MachineFunction &amp; mf, llvm::SelectionDAG * DAG) Line 114       C++
llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction &amp; mf) 
Line 588   C++
```

This patch is compatible with the crash(Unexpected state == -1)

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


2 Files Affected:

- (modified) clang/lib/CodeGen/CGException.cpp (+24) 
- (modified) clang/test/CodeGenCXX/exceptions-seh.cpp (+20) 


``````````diff
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

``````````

</details>


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

Reply via email to