[clang] clang/WebAssembly: Add -femscripten-exceptions driver flag (PR #221431)

Matt Arsenault via cfe-commits cfe-commits at lists.llvm.org
Sat Sep 5 03:24:54 PDT 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/221431

Add a proper -femscripten-exceptions driver flag for Emscripten
exception handling, parallel to -fwasm-exceptions. Previously the only way
to select Emscripten EH was to pass the backend implementation detail
-mllvm -enable-emscripten-cxx-exceptions.

This drives the existing cl::opt mechanism, but in the future this will
change the emitted exception model module flag.

Co-authored-by: Claude (Claude-Opus-4.8) <noreply at anthropic.com>

>From 89e13008600307db52c421ab59c0e98ea2508518 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sat, 5 Sep 2026 12:19:03 +0200
Subject: [PATCH] clang/WebAssembly: Add -femscripten-exceptions driver flag

Add a proper -femscripten-exceptions driver flag for Emscripten
exception handling, parallel to -fwasm-exceptions. Previously the only way
to select Emscripten EH was to pass the backend implementation detail
-mllvm -enable-emscripten-cxx-exceptions.

This drives the existing cl::opt mechanism, but in the future this will
change the emitted exception model module flag.

Co-authored-by: Claude (Claude-Opus-4.8) <noreply at anthropic.com>
---
 clang/include/clang/Options/Options.td      |  3 +++
 clang/lib/Driver/ToolChains/WebAssembly.cpp | 18 +++++++++++++++---
 clang/test/Driver/wasm-toolchain.c          | 21 ++++++++++++++++++++-
 3 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 37e5c3199a003..2f2ab2f2ba6d8 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -2454,6 +2454,9 @@ def fseh_exceptions : Flag<["-"], "fseh-exceptions">, Group<f_Group>,
   HelpText<"Use SEH style exceptions">;
 def fwasm_exceptions : Flag<["-"], "fwasm-exceptions">, Group<f_Group>,
   HelpText<"Use WebAssembly style exceptions">;
+def femscripten_exceptions : Flag<["-"], "femscripten-exceptions">,
+  Group<f_Group>,
+  HelpText<"Use Emscripten JavaScript-based C++ exceptions">;
 def exception_model : Separate<["-"], "exception-model">,
   Visibility<[CC1Option]>, HelpText<"The exception model">,
   Values<"dwarf,sjlj,seh,wasm,none">,
diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 7d5d406df2399..0d3271d31a0b7 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -423,6 +423,10 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,
       getDriver().Diag(diag::err_drv_argument_not_allowed_with)
           << CurOption << "-mno-reference-types";
 
+    if (DriverArgs.hasArg(options::OPT_femscripten_exceptions))
+      getDriver().Diag(diag::err_drv_argument_not_allowed_with)
+          << CurOption << "-femscripten-exceptions";
+
     for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
       for (const auto *Option :
            {"-enable-emscripten-cxx-exceptions", "-enable-emscripten-sjlj",
@@ -458,12 +462,20 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,
     CC1Args.push_back("-wasm-enable-eh");
   }
 
+  if (DriverArgs.getLastArg(options::OPT_femscripten_exceptions)) {
+    // Backend needs -enable-emscripten-cxx-exceptions to enable Emscripten EH
+    CC1Args.push_back("-mllvm");
+    CC1Args.push_back("-enable-emscripten-cxx-exceptions");
+  }
+
   for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
     StringRef Opt = A->getValue(0);
     if (Opt.starts_with("-emscripten-cxx-exceptions-allowed")) {
       // '-mllvm -emscripten-cxx-exceptions-allowed' should be used with
-      // '-mllvm -enable-emscripten-cxx-exceptions'
-      bool EmEHArgExists = false;
+      // '-femscripten-exceptions' (or the underlying
+      // '-mllvm -enable-emscripten-cxx-exceptions').
+      bool EmEHArgExists =
+          DriverArgs.hasArg(options::OPT_femscripten_exceptions);
       for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
         if (StringRef(A->getValue(0)) == "-enable-emscripten-cxx-exceptions") {
           EmEHArgExists = true;
@@ -473,7 +485,7 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,
       if (!EmEHArgExists)
         getDriver().Diag(diag::err_drv_argument_only_allowed_with)
             << "-mllvm -emscripten-cxx-exceptions-allowed"
-            << "-mllvm -enable-emscripten-cxx-exceptions";
+            << "-femscripten-exceptions";
 
       // Prevent functions specified in -emscripten-cxx-exceptions-allowed list
       // from being inlined before reaching the wasm backend.
diff --git a/clang/test/Driver/wasm-toolchain.c b/clang/test/Driver/wasm-toolchain.c
index 467d79e57aff1..083773e8e8197 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -133,7 +133,26 @@
 // RUN: not %clang -### --target=wasm32-unknown-unknown \
 // RUN:     --sysroot=/foo %s -mllvm -emscripten-cxx-exceptions-allowed 2>&1 \
 // RUN:   | FileCheck -check-prefix=EMSCRIPTEN_EH_ALLOWED_WO_ENABLE %s
-// EMSCRIPTEN_EH_ALLOWED_WO_ENABLE: invalid argument '-mllvm -emscripten-cxx-exceptions-allowed' only allowed with '-mllvm -enable-emscripten-cxx-exceptions'
+// EMSCRIPTEN_EH_ALLOWED_WO_ENABLE: invalid argument '-mllvm -emscripten-cxx-exceptions-allowed' only allowed with '-femscripten-exceptions'
+
+// '-femscripten-exceptions' sets '-mllvm -enable-emscripten-cxx-exceptions'
+// RUN: %clang -### --target=wasm32-unknown-unknown \
+// RUN:    --sysroot=/foo %s -femscripten-exceptions 2>&1 \
+// RUN:  | FileCheck -check-prefix=EMSCRIPTEN_EXCEPTIONS %s
+// EMSCRIPTEN_EXCEPTIONS: "-cc1" {{.*}} "-mllvm" "-enable-emscripten-cxx-exceptions"
+
+// '-femscripten-exceptions' satisfies the '-emscripten-cxx-exceptions-allowed'
+// companion requirement.
+// RUN: %clang -### --target=wasm32-unknown-unknown \
+// RUN:    --sysroot=/foo %s -femscripten-exceptions \
+// RUN:    -mllvm -emscripten-cxx-exceptions-allowed=foo,bar 2>&1 \
+// RUN:  | FileCheck -check-prefix=EMSCRIPTEN_EH_ALLOWED_NOINLINE %s
+
+// '-fwasm-exceptions' not allowed with '-femscripten-exceptions'
+// RUN: not %clang -### --target=wasm32-unknown-unknown \
+// RUN:     --sysroot=/foo %s -fwasm-exceptions -femscripten-exceptions 2>&1 \
+// RUN:   | FileCheck -check-prefix=WASM_EXCEPTIONS_FEMSCRIPTEN_EH %s
+// WASM_EXCEPTIONS_FEMSCRIPTEN_EH: invalid argument '-fwasm-exceptions' not allowed with '-femscripten-exceptions'
 
 // '-fwasm-exceptions' sets +exception-handling, -multivalue, -reference-types,
 // "-exception-model=wasm", and '-mllvm -wasm-enable-eh'



More information about the cfe-commits mailing list