Skip to content

Commit 7502af8

Browse files
authored
clang: Forward exception_model flag for bitcode inputs (#146342)
This will enable removal of a hack from the wasm backend in a future change. This feels unnecessarily clunky. I would assume something was automatically parsing this and propagating it in the C++ case, but I can't seem to find it. In particular it feels wrong that I need to parse out the individual values, given they are listed in the options.td file. We should also be parsing and forwarding every flag that corresponds to something else in TargetOptions, which requires auditing.
1 parent b0e6faa commit 7502af8

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3679,6 +3679,22 @@ static StringRef GetInputKindName(InputKind IK) {
36793679
llvm_unreachable("unknown input language");
36803680
}
36813681

3682+
static StringRef getExceptionHandlingName(unsigned EHK) {
3683+
switch (static_cast<LangOptions::ExceptionHandlingKind>(EHK)) {
3684+
case LangOptions::ExceptionHandlingKind::None:
3685+
default:
3686+
return "none";
3687+
case LangOptions::ExceptionHandlingKind::SjLj:
3688+
return "sjlj";
3689+
case LangOptions::ExceptionHandlingKind::DwarfCFI:
3690+
return "dwarf";
3691+
case LangOptions::ExceptionHandlingKind::Wasm:
3692+
return "wasm";
3693+
}
3694+
3695+
llvm_unreachable("covered switch");
3696+
}
3697+
36823698
void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
36833699
ArgumentConsumer Consumer,
36843700
const llvm::Triple &T,
@@ -3694,6 +3710,10 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
36943710
GenerateArg(Consumer, OPT_pic_is_pie);
36953711
for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
36963712
GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
3713+
if (Opts.ExceptionHandling) {
3714+
GenerateArg(Consumer, OPT_exception_model,
3715+
getExceptionHandlingName(Opts.ExceptionHandling));
3716+
}
36973717

36983718
return;
36993719
}
@@ -4002,6 +4022,24 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
40024022
parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
40034023
Diags, Opts.Sanitize);
40044024

4025+
if (const Arg *A = Args.getLastArg(options::OPT_exception_model)) {
4026+
std::optional<LangOptions::ExceptionHandlingKind> EMValue =
4027+
llvm::StringSwitch<std::optional<LangOptions::ExceptionHandlingKind>>(
4028+
A->getValue())
4029+
.Case("dwarf", LangOptions::ExceptionHandlingKind::DwarfCFI)
4030+
.Case("sjlj", LangOptions::ExceptionHandlingKind::SjLj)
4031+
.Case("wineh", LangOptions::ExceptionHandlingKind::WinEH)
4032+
.Case("wasm", LangOptions::ExceptionHandlingKind::Wasm)
4033+
.Case("none", LangOptions::ExceptionHandlingKind::None)
4034+
.Default(std::nullopt);
4035+
if (EMValue) {
4036+
Opts.ExceptionHandling = static_cast<unsigned>(*EMValue);
4037+
} else {
4038+
Diags.Report(diag::err_drv_invalid_value)
4039+
<< A->getAsString(Args) << A->getValue();
4040+
}
4041+
}
4042+
40054043
return Diags.getNumErrors() == NumErrorsBefore;
40064044
}
40074045

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
; REQUIRES: webassembly-registered-target
2+
3+
; Check all the options parse
4+
; RUN: %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=none %s | FileCheck %s
5+
; RUN: %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=wasm %s | FileCheck %s
6+
; RUN: %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=dwarf %s | FileCheck %s
7+
; RUN: %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=sjlj %s | FileCheck %s
8+
9+
; RUN: not %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=invalid %s 2>&1 | FileCheck -check-prefix=ERR %s
10+
11+
; CHECK-LABEL: define void @test(
12+
13+
; ERR: error: invalid value 'invalid' in '-exception-model=invalid'
14+
define void @test() {
15+
ret void
16+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
; RUN: not %clang_cc1 -triple wasm32 -exception-model=arst -S %s 2>&1 | FileCheck -check-prefix=INVALID-VALUE %s
2+
3+
; Make sure invalid values are rejected for -exception-model when the
4+
; input is IR.
5+
6+
; INVALID-VALUE: error: invalid value 'arst' in '-exception-model=arst'
7+
8+
target triple = "wasm32"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clang -### -target wasm32-unknown-unknown -fwasm-exceptions -c -S -o - %S/Inputs/file.ll 2>&1 | FileCheck %s
2+
// RUN: %clang -### -target wasm32-unknown-unknown -Xclang -exception-model=wasm -c -S -o - %S/Inputs/file.ll 2>&1 | FileCheck %s
3+
// RUN: %clang -### -target wasm32-unknown-unknown -Xclang -exception-model=dwarf -c -S -o - %S/Inputs/file.ll 2>&1 | FileCheck -check-prefix=DWARF %s
4+
// RUN: %clang -### -target wasm32-unknown-unknown -Xclang -exception-model=sjlj -c -S -o - %S/Inputs/file.ll 2>&1 | FileCheck -check-prefix=SJLJ %s
5+
// RUN: %clang -### -target wasm32-unknown-unknown -Xclang -exception-model=wineh -c -S -o - %S/Inputs/file.ll 2>&1 | FileCheck -check-prefix=WINEH %s
6+
// RUN: %clang -### -target wasm32-unknown-unknown -Xclang -exception-model=arst -c -S -o - %S/Inputs/file.ll 2>&1 | FileCheck -check-prefix=INVALID %s
7+
8+
// Check that -fwasm-exceptions propagates -exception-model to cc1
9+
10+
// CHECK: "-exception-model=wasm"
11+
// DWARF: "-exception-model=dwarf"
12+
// SJLJ: "-exception-model=sjlj"
13+
// WINEH: "-exception-model=wineh"
14+
// INVALID: "-exception-model=arst"

0 commit comments

Comments
 (0)