diff options
author | Heejin Ahn <aheejin@gmail.com> | 2019-09-12 04:01:37 +0000 |
---|---|---|
committer | Heejin Ahn <aheejin@gmail.com> | 2019-09-12 04:01:37 +0000 |
commit | ed5c51707d766248bdc935fe333e3ac0739b10d7 (patch) | |
tree | 27d8eeaedc065142003e44525362558b5953cec2 | |
parent | 23a6eed24ca3cbe75d9173ca0272cac2d88578de (diff) | |
download | clang-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.def | 1 | ||||
-rw-r--r-- | include/clang/Driver/Options.td | 2 | ||||
-rw-r--r-- | lib/CodeGen/BackendUtil.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGException.cpp | 5 | ||||
-rw-r--r-- | lib/Driver/ToolChains/Clang.cpp | 8 | ||||
-rw-r--r-- | lib/Driver/ToolChains/WebAssembly.cpp | 20 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 7 | ||||
-rw-r--r-- | test/CodeGenCXX/wasm-eh.cpp | 13 | ||||
-rw-r--r-- | test/Driver/wasm-toolchain.c | 19 |
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" |