aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp38
-rw-r--r--clang/test/CodeGen/WebAssembly/wasm-exception-model-flag-parse-ir-input.ll16
-rw-r--r--clang/test/CodeGen/WebAssembly/wasm-invalid-exception-kinds.ll8
-rw-r--r--clang/test/Driver/ir-exception-model.c14
4 files changed, 76 insertions, 0 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index f366e90..d8916a6 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3679,6 +3679,22 @@ static StringRef GetInputKindName(InputKind IK) {
llvm_unreachable("unknown input language");
}
+static StringRef getExceptionHandlingName(unsigned EHK) {
+ switch (static_cast<LangOptions::ExceptionHandlingKind>(EHK)) {
+ case LangOptions::ExceptionHandlingKind::None:
+ default:
+ return "none";
+ case LangOptions::ExceptionHandlingKind::SjLj:
+ return "sjlj";
+ case LangOptions::ExceptionHandlingKind::DwarfCFI:
+ return "dwarf";
+ case LangOptions::ExceptionHandlingKind::Wasm:
+ return "wasm";
+ }
+
+ llvm_unreachable("covered switch");
+}
+
void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
ArgumentConsumer Consumer,
const llvm::Triple &T,
@@ -3694,6 +3710,10 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
GenerateArg(Consumer, OPT_pic_is_pie);
for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
+ if (Opts.ExceptionHandling) {
+ GenerateArg(Consumer, OPT_exception_model,
+ getExceptionHandlingName(Opts.ExceptionHandling));
+ }
return;
}
@@ -4002,6 +4022,24 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
Diags, Opts.Sanitize);
+ if (const Arg *A = Args.getLastArg(options::OPT_exception_model)) {
+ std::optional<LangOptions::ExceptionHandlingKind> EMValue =
+ llvm::StringSwitch<std::optional<LangOptions::ExceptionHandlingKind>>(
+ A->getValue())
+ .Case("dwarf", LangOptions::ExceptionHandlingKind::DwarfCFI)
+ .Case("sjlj", LangOptions::ExceptionHandlingKind::SjLj)
+ .Case("wineh", LangOptions::ExceptionHandlingKind::WinEH)
+ .Case("wasm", LangOptions::ExceptionHandlingKind::Wasm)
+ .Case("none", LangOptions::ExceptionHandlingKind::None)
+ .Default(std::nullopt);
+ if (EMValue) {
+ Opts.ExceptionHandling = static_cast<unsigned>(*EMValue);
+ } else {
+ Diags.Report(diag::err_drv_invalid_value)
+ << A->getAsString(Args) << A->getValue();
+ }
+ }
+
return Diags.getNumErrors() == NumErrorsBefore;
}
diff --git a/clang/test/CodeGen/WebAssembly/wasm-exception-model-flag-parse-ir-input.ll b/clang/test/CodeGen/WebAssembly/wasm-exception-model-flag-parse-ir-input.ll
new file mode 100644
index 0000000..4a7eeec
--- /dev/null
+++ b/clang/test/CodeGen/WebAssembly/wasm-exception-model-flag-parse-ir-input.ll
@@ -0,0 +1,16 @@
+; REQUIRES: webassembly-registered-target
+
+; Check all the options parse
+; RUN: %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=none %s | FileCheck %s
+; RUN: %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=wasm %s | FileCheck %s
+; RUN: %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=dwarf %s | FileCheck %s
+; RUN: %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=sjlj %s | FileCheck %s
+
+; RUN: not %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=invalid %s 2>&1 | FileCheck -check-prefix=ERR %s
+
+; CHECK-LABEL: define void @test(
+
+; ERR: error: invalid value 'invalid' in '-exception-model=invalid'
+define void @test() {
+ ret void
+}
diff --git a/clang/test/CodeGen/WebAssembly/wasm-invalid-exception-kinds.ll b/clang/test/CodeGen/WebAssembly/wasm-invalid-exception-kinds.ll
new file mode 100644
index 0000000..27fb696
--- /dev/null
+++ b/clang/test/CodeGen/WebAssembly/wasm-invalid-exception-kinds.ll
@@ -0,0 +1,8 @@
+; RUN: not %clang_cc1 -triple wasm32 -exception-model=arst -S %s 2>&1 | FileCheck -check-prefix=INVALID-VALUE %s
+
+; Make sure invalid values are rejected for -exception-model when the
+; input is IR.
+
+; INVALID-VALUE: error: invalid value 'arst' in '-exception-model=arst'
+
+target triple = "wasm32"
diff --git a/clang/test/Driver/ir-exception-model.c b/clang/test/Driver/ir-exception-model.c
new file mode 100644
index 0000000..9e8f998
--- /dev/null
+++ b/clang/test/Driver/ir-exception-model.c
@@ -0,0 +1,14 @@
+// RUN: %clang -### -target wasm32-unknown-unknown -fwasm-exceptions -c -S -o - %S/Inputs/file.ll 2>&1 | FileCheck %s
+// RUN: %clang -### -target wasm32-unknown-unknown -Xclang -exception-model=wasm -c -S -o - %S/Inputs/file.ll 2>&1 | FileCheck %s
+// RUN: %clang -### -target wasm32-unknown-unknown -Xclang -exception-model=dwarf -c -S -o - %S/Inputs/file.ll 2>&1 | FileCheck -check-prefix=DWARF %s
+// RUN: %clang -### -target wasm32-unknown-unknown -Xclang -exception-model=sjlj -c -S -o - %S/Inputs/file.ll 2>&1 | FileCheck -check-prefix=SJLJ %s
+// RUN: %clang -### -target wasm32-unknown-unknown -Xclang -exception-model=wineh -c -S -o - %S/Inputs/file.ll 2>&1 | FileCheck -check-prefix=WINEH %s
+// RUN: %clang -### -target wasm32-unknown-unknown -Xclang -exception-model=arst -c -S -o - %S/Inputs/file.ll 2>&1 | FileCheck -check-prefix=INVALID %s
+
+// Check that -fwasm-exceptions propagates -exception-model to cc1
+
+// CHECK: "-exception-model=wasm"
+// DWARF: "-exception-model=dwarf"
+// SJLJ: "-exception-model=sjlj"
+// WINEH: "-exception-model=wineh"
+// INVALID: "-exception-model=arst"