[llvm-branch-commits] [clang] clang: Emit "exception-model" module flag (PR #220053)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Aug 31 11:48:07 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-ir
Author: Matt Arsenault (arsenm)
<details>
<summary>Changes</summary>
Record the exception-handling model as an "exception-model" IR module
flag when it differs from the target triple's default, mirroring how
other target ABI properties are recorded. Adds a
CodeGenOptions::toExceptionHandling helper to translate clang's
ExceptionHandlingKind into the LLVM ExceptionHandling enum.
Co-authored-by: Claude (Claude-Opus-4.8) <noreply@<!-- -->anthropic.com>
---
Full diff: https://github.com/llvm/llvm-project/pull/220053.diff
3 Files Affected:
- (modified) clang/include/clang/Basic/CodeGenOptions.h (+19)
- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+12)
- (added) clang/test/CodeGen/exception-model-flag.c (+38)
``````````diff
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index 17f367bc02607..ff4ce0b8571ca 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -201,6 +201,25 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// Possible exception handling behavior.
enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm };
+ /// Translate a clang ExceptionHandlingKind into the corresponding LLVM
+ /// ExceptionHandling model.
+ static llvm::ExceptionHandling
+ toExceptionHandling(ExceptionHandlingKind Kind) {
+ switch (Kind) {
+ case ExceptionHandlingKind::None:
+ return llvm::ExceptionHandling::None;
+ case ExceptionHandlingKind::SjLj:
+ return llvm::ExceptionHandling::SjLj;
+ case ExceptionHandlingKind::WinEH:
+ return llvm::ExceptionHandling::WinEH;
+ case ExceptionHandlingKind::DwarfCFI:
+ return llvm::ExceptionHandling::DwarfCFI;
+ case ExceptionHandlingKind::Wasm:
+ return llvm::ExceptionHandling::Wasm;
+ }
+ llvm_unreachable("invalid ExceptionHandlingKind");
+ }
+
enum class SwiftAsyncFramePointerKind {
Auto, // Choose Swift async extended frame info based on deployment target.
Always, // Unconditionally emit Swift async extended frame info.
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 17b5f0fe4133d..94aae9c2c25bf 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1450,6 +1450,18 @@ void CodeGenModule::Release() {
getModule().setLongDoubleFormat(*Format);
}
+ // Record the exception model as a module flag when it differs from the
+ // target default.
+ llvm::ExceptionHandling ExceptionModel =
+ CodeGenOptions::toExceptionHandling(CodeGenOpts.getExceptionHandling());
+ if (ExceptionModel != llvm::ExceptionHandling::None &&
+ ExceptionModel != getTriple().getDefaultExceptionHandling()) {
+ getModule().addModuleFlag(
+ llvm::Module::Error, "exception-model",
+ llvm::MDString::get(getLLVMContext(),
+ llvm::getExceptionModelName(ExceptionModel)));
+ }
+
if (getTriple().isOSzOS()) {
getModule().addModuleFlag(llvm::Module::Warning,
"zos_product_major_version",
diff --git a/clang/test/CodeGen/exception-model-flag.c b/clang/test/CodeGen/exception-model-flag.c
new file mode 100644
index 0000000000000..9a7f93cb00579
--- /dev/null
+++ b/clang/test/CodeGen/exception-model-flag.c
@@ -0,0 +1,38 @@
+// Verify clang records the "exception-model" module flag when the exception
+// model differs from the target triple's default, and omits it otherwise.
+// The cc1 -exception-model option accepts dwarf/sjlj/seh/wasm/none; ARM EHABI
+// is triple-inferred and not user-selectable here.
+
+// i686-linux defaults to DWARF exception handling, so every other model emits.
+// RUN: %clang_cc1 -triple i686-unknown-linux-gnu -fexceptions -exception-model=sjlj -emit-llvm %s -o - | FileCheck %s --check-prefix=SJLJ
+// RUN: %clang_cc1 -triple i686-unknown-linux-gnu -fexceptions -exception-model=seh -emit-llvm %s -o - | FileCheck %s --check-prefix=WINEH
+
+// SEH maps to the "wineh" spelling regardless of the requesting triple.
+// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -exception-model=seh -emit-llvm %s -o - | FileCheck %s --check-prefix=WINEH
+
+// Wasm EH (needs the backend enable flag) records the "wasm" model.
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown -fexceptions -exception-model=wasm -mllvm -wasm-enable-eh -emit-llvm %s -o - | FileCheck %s --check-prefix=WASM
+
+// DWARF requested on a target that also defaults to DWARF: no flag.
+// RUN: %clang_cc1 -triple i686-unknown-linux-gnu -fexceptions -exception-model=dwarf -emit-llvm %s -o - | FileCheck %s --check-prefix=NONE
+
+// SjLj requested on a target that defaults to SjLj: no flag.
+// RUN: %clang_cc1 -triple armv7-apple-ios -fexceptions -exception-model=sjlj -emit-llvm %s -o - | FileCheck %s --check-prefix=NONE
+
+// A target that defaults to WinEH records no flag (clang rejects an explicit
+// -exception-model=seh here, so rely on the default).
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fexceptions -emit-llvm %s -o - | FileCheck %s --check-prefix=NONE
+
+// Explicitly "none": no flag (clang cannot distinguish this from unspecified).
+// RUN: %clang_cc1 -triple i686-unknown-linux-gnu -fexceptions -exception-model=none -emit-llvm %s -o - | FileCheck %s --check-prefix=NONE
+
+// No exception model requested at all: no flag.
+// RUN: %clang_cc1 -triple i686-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=NONE
+// RUN: %clang_cc1 -triple armv7-unknown-linux-gnueabi -emit-llvm %s -o - | FileCheck %s --check-prefix=NONE
+
+void f(void) {}
+
+// SJLJ: !{i32 1, !"exception-model", !"sjlj"}
+// WINEH: !{i32 1, !"exception-model", !"wineh"}
+// WASM: !{i32 1, !"exception-model", !"wasm"}
+// NONE-NOT: "exception-model"
``````````
</details>
https://github.com/llvm/llvm-project/pull/220053
More information about the llvm-branch-commits
mailing list