summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/LangOptions.def1
-rw-r--r--include/clang/Driver/Options.td2
-rw-r--r--lib/CodeGen/BackendUtil.cpp2
-rw-r--r--lib/CodeGen/CGException.cpp5
-rw-r--r--lib/Driver/ToolChains/Clang.cpp8
-rw-r--r--lib/Driver/ToolChains/WebAssembly.cpp20
-rw-r--r--lib/Frontend/CompilerInvocation.cpp7
-rw-r--r--test/CodeGenCXX/wasm-eh.cpp13
-rw-r--r--test/Driver/wasm-toolchain.c19
9 files changed, 65 insertions, 12 deletions
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index 31aca2b0d6..dec281e793 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -128,6 +128,7 @@ LANGOPT(CXXExceptions , 1, 0, "C++ exceptions")
LANGOPT(DWARFExceptions , 1, 0, "dwarf exception handling")
LANGOPT(SjLjExceptions , 1, 0, "setjmp-longjump exception handling")
LANGOPT(SEHExceptions , 1, 0, "SEH .xdata exception handling")
+LANGOPT(WasmExceptions , 1, 0, "WebAssembly exception handling")
LANGOPT(ExternCNoUnwind , 1, 0, "Assume extern C functions don't unwind")
LANGOPT(TraditionalCPP , 1, 0, "traditional CPP emulation")
LANGOPT(RTTI , 1, 1, "run-time type information")
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 01c0cd2db6..57bab1e1c4 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -904,6 +904,8 @@ def fsjlj_exceptions : Flag<["-"], "fsjlj-exceptions">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Use SjLj style exceptions">;
def fseh_exceptions : Flag<["-"], "fseh-exceptions">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Use SEH style exceptions">;
+def fwasm_exceptions : Flag<["-"], "fwasm-exceptions">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Use WebAssembly style exceptions">;
def fexcess_precision_EQ : Joined<["-"], "fexcess-precision=">,
Group<clang_ignored_gcc_optimization_f_Group>;
def : Flag<["-"], "fexpensive-optimizations">, Group<clang_ignored_gcc_optimization_f_Group>;
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index 251b1fce6d..71ae8fd4fb 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -468,6 +468,8 @@ static void initTargetOptions(llvm::TargetOptions &Options,
Options.ExceptionModel = llvm::ExceptionHandling::WinEH;
if (LangOpts.DWARFExceptions)
Options.ExceptionModel = llvm::ExceptionHandling::DwarfCFI;
+ if (LangOpts.WasmExceptions)
+ Options.ExceptionModel = llvm::ExceptionHandling::Wasm;
Options.NoInfsFPMath = CodeGenOpts.NoInfsFPMath;
Options.NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath;
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index 4c94cfb233..645d7a878e 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -165,10 +165,7 @@ static const EHPersonality &getCXXPersonality(const TargetInfo &Target,
return EHPersonality::GNU_CPlusPlus;
if (L.SEHExceptions)
return EHPersonality::GNU_CPlusPlus_SEH;
- // Wasm EH is a non-MVP feature for now.
- if (Target.hasFeature("exception-handling") &&
- (T.getArch() == llvm::Triple::wasm32 ||
- T.getArch() == llvm::Triple::wasm64))
+ if (L.WasmExceptions)
return EHPersonality::GNU_Wasm_CPlusPlus;
return EHPersonality::GNU_CPlusPlus;
}
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index 9b2d4d874a..6aff423bd1 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -4981,9 +4981,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
addExceptionArgs(Args, InputType, TC, KernelOrKext, Runtime, CmdArgs);
// Handle exception personalities
- Arg *A = Args.getLastArg(options::OPT_fsjlj_exceptions,
- options::OPT_fseh_exceptions,
- options::OPT_fdwarf_exceptions);
+ Arg *A = Args.getLastArg(
+ options::OPT_fsjlj_exceptions, options::OPT_fseh_exceptions,
+ options::OPT_fdwarf_exceptions, options::OPT_fwasm_exceptions);
if (A) {
const Option &Opt = A->getOption();
if (Opt.matches(options::OPT_fsjlj_exceptions))
@@ -4992,6 +4992,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fseh-exceptions");
if (Opt.matches(options::OPT_fdwarf_exceptions))
CmdArgs.push_back("-fdwarf-exceptions");
+ if (Opt.matches(options::OPT_fwasm_exceptions))
+ CmdArgs.push_back("-fwasm-exceptions");
} else {
switch (TC.GetExceptionModel(Args)) {
default:
diff --git a/lib/Driver/ToolChains/WebAssembly.cpp b/lib/Driver/ToolChains/WebAssembly.cpp
index de8325d46e..a9e5ec1c9c 100644
--- a/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/lib/Driver/ToolChains/WebAssembly.cpp
@@ -166,6 +166,26 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,
CC1Args.push_back("-target-feature");
CC1Args.push_back("+mutable-globals");
}
+
+ if (DriverArgs.getLastArg(options::OPT_fwasm_exceptions)) {
+ // '-fwasm-exceptions' is not compatible with '-mno-exception-handling'
+ if (DriverArgs.hasFlag(options::OPT_mno_exception_handing,
+ options::OPT_mexception_handing, false))
+ getDriver().Diag(diag::err_drv_argument_not_allowed_with)
+ << "-fwasm-exceptions"
+ << "-mno-exception-handling";
+ // '-fwasm-exceptions' is not compatible with
+ // '-mllvm -enable-emscripten-cxx-exceptions'
+ for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
+ if (StringRef(A->getValue(0)) == "-enable-emscripten-cxx-exceptions")
+ getDriver().Diag(diag::err_drv_argument_not_allowed_with)
+ << "-fwasm-exceptions"
+ << "-mllvm -enable-emscripten-cxx-exceptions";
+ }
+ // '-fwasm-exceptions' implies exception-handling
+ CC1Args.push_back("-target-feature");
+ CC1Args.push_back("+exception-handling");
+ }
}
ToolChain::RuntimeLibType WebAssembly::GetDefaultRuntimeLibType() const {
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 38d5694e7c..f051573e5a 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -2686,9 +2686,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.FixedPoint;
// Handle exception personalities
- Arg *A = Args.getLastArg(options::OPT_fsjlj_exceptions,
- options::OPT_fseh_exceptions,
- options::OPT_fdwarf_exceptions);
+ Arg *A = Args.getLastArg(
+ options::OPT_fsjlj_exceptions, options::OPT_fseh_exceptions,
+ options::OPT_fdwarf_exceptions, options::OPT_fwasm_exceptions);
if (A) {
const Option &Opt = A->getOption();
llvm::Triple T(TargetOpts.Triple);
@@ -2699,6 +2699,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.SjLjExceptions = Opt.matches(options::OPT_fsjlj_exceptions);
Opts.SEHExceptions = Opt.matches(options::OPT_fseh_exceptions);
Opts.DWARFExceptions = Opt.matches(options::OPT_fdwarf_exceptions);
+ Opts.WasmExceptions = Opt.matches(options::OPT_fwasm_exceptions);
}
Opts.ExternCNoUnwind = Args.hasArg(OPT_fexternc_nounwind);
diff --git a/test/CodeGenCXX/wasm-eh.cpp b/test/CodeGenCXX/wasm-eh.cpp
index 5d5cb6ba1c..6005701f23 100644
--- a/test/CodeGenCXX/wasm-eh.cpp
+++ b/test/CodeGenCXX/wasm-eh.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -target-feature +exception-handling -emit-llvm -o - -std=c++11 | FileCheck %s
-// RUN: %clang_cc1 %s -triple wasm64-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -target-feature +exception-handling -emit-llvm -o - -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -fwasm-exceptions -target-feature +exception-handling -emit-llvm -o - -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 %s -triple wasm64-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -fwasm-exceptions -target-feature +exception-handling -emit-llvm -o - -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -fwasm-exceptions -target-feature +exception-handling -S -o - -std=c++11 | FileCheck %s --check-prefix=ASSEMBLY
void may_throw();
void dont_throw() noexcept;
@@ -382,3 +383,11 @@ void test8() {
// CHECK: cleanupret from %[[CLEANUPPAD1]] unwind to caller
// CHECK: unreachable
+
+// Here we only check if the command enables wasm exception handling in the
+// backend so that exception handling instructions can be generated in .s file.
+
+// ASSEMBLY: try
+// ASSEMBLY: catch
+// ASSEMBLY: rethrow
+// ASSEMBLY: end_try
diff --git a/test/Driver/wasm-toolchain.c b/test/Driver/wasm-toolchain.c
index 263fcf7f39..e222d618d2 100644
--- a/test/Driver/wasm-toolchain.c
+++ b/test/Driver/wasm-toolchain.c
@@ -73,6 +73,25 @@
// RUN: | FileCheck -check-prefix=PTHREAD_NO_MUT_GLOBALS %s
// PTHREAD_NO_MUT_GLOBALS: invalid argument '-pthread' not allowed with '-mno-mutable-globals'
+// '-fwasm-exceptions' sets +exception-handling
+// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \
+// RUN: --sysroot=/foo %s -fwasm-exceptions 2>&1 \
+// RUN: | FileCheck -check-prefix=WASM_EXCEPTIONS %s
+// WASM_EXCEPTIONS: clang{{.*}}" "-cc1" {{.*}} "-target-feature" "+exception-handling"
+
+// '-fwasm-exceptions' not allowed with '-mno-exception-handling'
+// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \
+// RUN: --sysroot=/foo %s -fwasm-exceptions -mno-exception-handling 2>&1 \
+// RUN: | FileCheck -check-prefix=WASM_EXCEPTIONS_NO_EH %s
+// WASM_EXCEPTIONS_NO_EH: invalid argument '-fwasm-exceptions' not allowed with '-mno-exception-handling'
+
+// '-fwasm-exceptions' not allowed with
+// '-mllvm -enable-emscripten-cxx-exceptions'
+// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \
+// RUN: --sysroot=/foo %s -fwasm-exceptions -mllvm -enable-emscripten-cxx-exceptions 2>&1 \
+// RUN: | FileCheck -check-prefix=WASM_EXCEPTIONS_EMSCRIPTEN_EH %s
+// WASM_EXCEPTIONS_EMSCRIPTEN_EH: invalid argument '-fwasm-exceptions' not allowed with '-mllvm -enable-emscripten-cxx-exceptions'
+
// RUN: %clang %s -### -fsanitize=address -target wasm32-unknown-emscripten 2>&1 | FileCheck -check-prefix=CHECK-ASAN-EMSCRIPTEN %s
// CHECK-ASAN-EMSCRIPTEN: "-fsanitize=address"
// CHECK-ASAN-EMSCRIPTEN: "-fsanitize-address-globals-dead-stripping"