summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeejin Ahn <aheejin@gmail.com>2019-09-12 04:01:37 +0000
committerHeejin Ahn <aheejin@gmail.com>2019-09-12 04:01:37 +0000
commited5c51707d766248bdc935fe333e3ac0739b10d7 (patch)
tree27d8eeaedc065142003e44525362558b5953cec2
parent23a6eed24ca3cbe75d9173ca0272cac2d88578de (diff)
downloadclang-ed5c51707d766248bdc935fe333e3ac0739b10d7.tar.gz
[WebAssembly] Add -fwasm-exceptions for wasm EH
Summary: This adds `-fwasm-exceptions` (in similar fashion with `-fdwarf-exceptions` or `-fsjlj-exceptions`) that turns on everything with wasm exception handling from the frontend to the backend. We currently have `-mexception-handling` in clang frontend, but this is only about the architecture capability and does not turn on other necessary options such as the exception model in the backend. (This can be turned on with `llc -exception-model=wasm`, but llc is not invoked separately as a command line tool, so this option has to be transferred from clang.) Turning on `-fwasm-exceptions` in clang also turns on `-mexception-handling` if not specified, and will error out if `-mno-exception-handling` is specified. Reviewers: dschuff, tlively, sbc100 Subscribers: aprantl, jgravelle-google, sunfish, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D67208 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@371708 91177308-0d34-0410-b5e6-96231b3b80d8
-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"