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<llvm::SEHUnwindMapEntry,void>::operator[](unsigned
__int64 idx) Line 295 C++
llvm::calculateSEHStateForAsynchEH(const llvm::BasicBlock * BB, int State,
llvm::WinEHFuncInfo & EHInfo) Line 346 C++
llvm::calculateSEHStateNumbers(const llvm::Function * Fn, llvm::WinEHFuncInfo
& FuncInfo) Line 612 C++
llvm::FunctionLoweringInfo::set(const llvm::Function & fn,
llvm::MachineFunction & mf, llvm::SelectionDAG * DAG) Line 114 C++
llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction & 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