https://github.com/ilovepi updated https://github.com/llvm/llvm-project/pull/174894
>From e02ffa1e6e7ef1a45c01814dc739ff0923c19880 Mon Sep 17 00:00:00 2001 From: Paul Kirth <[email protected]> Date: Wed, 7 Jan 2026 14:30:55 -0800 Subject: [PATCH 1/6] [clang][driver] Expose a frontend option for trap-unreachable We have several issues that list surprising behavior around UB. In many cases, this causes undesirable control flow, such as execution falling through to the next function (or whatever is in memory) instead of remaining within the bounds of the procedure. #174844, #48943, #146791, and #137741 all discuss a host of related issues. In #174844, it was mentioned that we have backend support for this for Rust, and at least one big class of these issues could be addressed by exposing the option to clang. This patch adds a new driver option that does just that. For now, we're leaving this option off by default, though we expect only small differences in code size or performance as a result if it were to be enabled. There will be an RFC in the future when we have more confidence this should be the default configuration. Fixes #174844 --- clang/include/clang/Basic/CodeGenOptions.def | 3 +++ clang/include/clang/Options/Options.td | 7 +++++++ clang/lib/CodeGen/BackendUtil.cpp | 1 + clang/lib/Driver/ToolChains/Clang.cpp | 3 +++ clang/test/CodeGen/X86/unreachable-trap.c | 18 ++++++++++++++++++ clang/test/Driver/clang_f_opts.c | 5 +++++ 6 files changed, 37 insertions(+) create mode 100644 clang/test/CodeGen/X86/unreachable-trap.c diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 8c056bb690690..8aea3008ac4d1 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -434,6 +434,9 @@ CODEGENOPT(DirectAccessExternalData, 1, 0, Benign) /// paths that reach the end of a function without executing a required return. CODEGENOPT(StrictReturn, 1, 1, Benign) +/// Whether we should use make unreachable trap or not. +CODEGENOPT(TrapUnreachable, 1, 0, Benign) + /// Whether emit pseudo probes for sample pgo profile collection. CODEGENOPT(PseudoProbeForProfiling, 1, 0, Benign) diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index a274017953b1d..6f7dd462aef05 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -4751,6 +4751,13 @@ defm strict_return : BoolFOption<"strict-return", " of a non-void function as unreachable">, PosFlag<SetTrue>>; +defm trap_unreachable + : BoolFOption<"trap-unreachable", CodeGenOpts<"TrapUnreachable">, + DefaultFalse, + PosFlag<SetTrue, [], [ClangOption, CC1Option], + "Treat unreachable instructions as traps">, + NegFlag<SetFalse>>; + let Flags = [TargetSpecific] in { defm ptrauth_intrinsics : OptInCC1FFlag<"ptrauth-intrinsics", "Enable pointer authentication intrinsics">; defm ptrauth_calls : OptInCC1FFlag<"ptrauth-calls", "Enable signing and authentication of all indirect calls">; diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 94257fb96fc7f..dfd26c6b4a564 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -467,6 +467,7 @@ static bool initTargetOptions(const CompilerInstance &CI, Options.XCOFFReadOnlyPointers = CodeGenOpts.XCOFFReadOnlyPointers; Options.VecLib = convertDriverVectorLibraryToVectorLibrary(CodeGenOpts.getVecLib()); + Options.TrapUnreachable = CodeGenOpts.TrapUnreachable; switch (CodeGenOpts.getSwiftAsyncFramePointer()) { case CodeGenOptions::SwiftAsyncFramePointerKind::Auto: diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index c16aa33f29ebb..50c69efd754f3 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5851,6 +5851,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.addOptInFlag(CmdArgs, options::OPT_fsplit_stack, options::OPT_fno_split_stack); + Args.addOptInFlag(CmdArgs, options::OPT_ftrap_unreachable, + options::OPT_ftrap_unreachable); + // -fprotect-parens=0 is default. if (Args.hasFlag(options::OPT_fprotect_parens, options::OPT_fno_protect_parens, false)) diff --git a/clang/test/CodeGen/X86/unreachable-trap.c b/clang/test/CodeGen/X86/unreachable-trap.c new file mode 100644 index 0000000000000..bea34e80dd873 --- /dev/null +++ b/clang/test/CodeGen/X86/unreachable-trap.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 %s -O1 -triple=x86_64-unknown-linux-gnu -ftrap-unreachable -S -o - 2>&1 | FileCheck %s --check-prefix=TRAP +// RUN: %clang_cc1 %s -O1 -triple=x86_64-unknown-linux-gnu -S -o - 2>&1 | FileCheck %s --check-prefix=NOTRAP + +// TRAP: ud2 +// NOTRAP-NOT: ud2 + +[[noreturn]] +void exit(int); + +#define NULL 0 + +static void test(void) { + int *ptr = NULL; + *ptr = 0; + exit(0); +} + +void foo() { test(); } diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c index 5871f1580d6b7..aedbef393abcc 100644 --- a/clang/test/Driver/clang_f_opts.c +++ b/clang/test/Driver/clang_f_opts.c @@ -651,3 +651,8 @@ // RUN: %clang -### --target=x86_64-pc-windows-msvc -fno-strict-aliasing %s 2>&1 | FileCheck -check-prefix=CHECK-NO-STRICT-ALIASING %s // CHECK-STRICT-ALIASING-NOT: -relaxed-aliasing // CHECK-NO-STRICT-ALIASING: -relaxed-aliasing + +// RUN: %clang -### -ftrap-unreachable %s 2>&1 | FileCheck %s -check-prefix=UNREACHABLE-TRAP +// RUN: %clang -### -fno-trap-unreachable %s 2>&1 | FileCheck %s -check-prefix=NO-UNREACHABLE-TRAP +// UNREACHABLE-TRAP: "-ftrap-unreachable" +// NO-UNREACHABLE-TRAP-NOT: "-ftrap-unreachable" >From 2ae9acd679add01182517cc29b5b9808a7a4c132 Mon Sep 17 00:00:00 2001 From: Paul Kirth <[email protected]> Date: Mon, 12 Jan 2026 11:53:59 -0800 Subject: [PATCH 2/6] Also support NoTrapAfterNoreturn --- clang/include/clang/Basic/CodeGenOptions.def | 6 ++--- clang/include/clang/Basic/CodeGenOptions.h | 6 +++++ clang/include/clang/Options/Options.td | 13 ++++++----- clang/lib/CodeGen/BackendUtil.cpp | 12 +++++++++- clang/lib/Driver/ToolChains/Clang.cpp | 5 ++--- clang/test/CodeGen/X86/unreachable-trap.c | 23 +++++++++++++++----- clang/test/Driver/clang_f_opts.c | 12 ++++++---- 7 files changed, 55 insertions(+), 22 deletions(-) diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 8aea3008ac4d1..2df1514edbdd2 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -417,6 +417,9 @@ VALUE_CODEGENOPT(TLSSize, 8, 0, Benign) /// The types of variables that we will extend the live ranges of. ENUM_CODEGENOPT(ExtendVariableLiveness, ExtendVariableLivenessKind, 2, ExtendVariableLivenessKind::None, Benign) +/// Whether we should use make unreachable trap or not. +ENUM_CODEGENOPT(TrapUnreachable, TrapUnreachableKind, 2, TrapUnreachableKind::None, Benign) + /// The default stack protector guard offset to use. VALUE_CODEGENOPT(StackProtectorGuardOffset, 32, INT_MAX, Benign) @@ -434,9 +437,6 @@ CODEGENOPT(DirectAccessExternalData, 1, 0, Benign) /// paths that reach the end of a function without executing a required return. CODEGENOPT(StrictReturn, 1, 1, Benign) -/// Whether we should use make unreachable trap or not. -CODEGENOPT(TrapUnreachable, 1, 0, Benign) - /// Whether emit pseudo probes for sample pgo profile collection. CODEGENOPT(PseudoProbeForProfiling, 1, 0, Benign) diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index 8ef0d87faaeaf..175858b9e2f81 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -126,6 +126,12 @@ class CodeGenOptions : public CodeGenOptionsBase { All, }; + enum class TrapUnreachableKind { + None, + ExceptNoreturn, + All, + }; + enum InlineAsmDialectKind { IAD_ATT, IAD_Intel, diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 6f7dd462aef05..f5f2eb0639bf6 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -4751,12 +4751,13 @@ defm strict_return : BoolFOption<"strict-return", " of a non-void function as unreachable">, PosFlag<SetTrue>>; -defm trap_unreachable - : BoolFOption<"trap-unreachable", CodeGenOpts<"TrapUnreachable">, - DefaultFalse, - PosFlag<SetTrue, [], [ClangOption, CC1Option], - "Treat unreachable instructions as traps">, - NegFlag<SetFalse>>; +def ftrap_unreachable : Joined<["-"], "ftrap-unreachable=">, + Group<f_Group>, Visibility<[ClangOption, CC1Option]>, + HelpText<"Treat unreachable instruction as traps.">, + Values<"all,except-noreturn,none">, + NormalizedValues<["All", "ExceptNoreturn", "None"]>, + NormalizedValuesScope<"CodeGenOptions::TrapUnreachableKind">, + MarshallingInfoEnum<CodeGenOpts<"TrapUnreachable">, "None">; let Flags = [TargetSpecific] in { defm ptrauth_intrinsics : OptInCC1FFlag<"ptrauth-intrinsics", "Enable pointer authentication intrinsics">; diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index dfd26c6b4a564..a8072972450f9 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -467,7 +467,17 @@ static bool initTargetOptions(const CompilerInstance &CI, Options.XCOFFReadOnlyPointers = CodeGenOpts.XCOFFReadOnlyPointers; Options.VecLib = convertDriverVectorLibraryToVectorLibrary(CodeGenOpts.getVecLib()); - Options.TrapUnreachable = CodeGenOpts.TrapUnreachable; + + switch(CodeGenOpts.getTrapUnreachable()){ + case clang::CodeGenOptions::TrapUnreachableKind::ExceptNoreturn: + Options.NoTrapAfterNoreturn = true; + LLVM_FALLTHROUGH; + case clang::CodeGenOptions::TrapUnreachableKind::All: + Options.TrapUnreachable = true; + break; + case clang::CodeGenOptions::TrapUnreachableKind::None: + break; + }; switch (CodeGenOpts.getSwiftAsyncFramePointer()) { case CodeGenOptions::SwiftAsyncFramePointerKind::Auto: diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 50c69efd754f3..4bb8a8258e3f2 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5851,9 +5851,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.addOptInFlag(CmdArgs, options::OPT_fsplit_stack, options::OPT_fno_split_stack); - Args.addOptInFlag(CmdArgs, options::OPT_ftrap_unreachable, - options::OPT_ftrap_unreachable); - // -fprotect-parens=0 is default. if (Args.hasFlag(options::OPT_fprotect_parens, options::OPT_fno_protect_parens, false)) @@ -5868,6 +5865,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.addOptInFlag(CmdArgs, options::OPT_fatomic_ignore_denormal_mode, options::OPT_fno_atomic_ignore_denormal_mode); + Args.addLastArg(CmdArgs, options::OPT_ftrap_unreachable); + if (Arg *A = Args.getLastArg(options::OPT_fextend_args_EQ)) { const llvm::Triple::ArchType Arch = TC.getArch(); if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) { diff --git a/clang/test/CodeGen/X86/unreachable-trap.c b/clang/test/CodeGen/X86/unreachable-trap.c index bea34e80dd873..e7f2adc3f9f9b 100644 --- a/clang/test/CodeGen/X86/unreachable-trap.c +++ b/clang/test/CodeGen/X86/unreachable-trap.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 %s -O1 -triple=x86_64-unknown-linux-gnu -ftrap-unreachable -S -o - 2>&1 | FileCheck %s --check-prefix=TRAP -// RUN: %clang_cc1 %s -O1 -triple=x86_64-unknown-linux-gnu -S -o - 2>&1 | FileCheck %s --check-prefix=NOTRAP +// RUN: %clang_cc1 %s -O1 -triple=x86_64-unknown-linux-gnu -ftrap-unreachable=all -S -o - 2>&1 | FileCheck %s --check-prefixes=TRAP,COMMON +// RUN: %clang_cc1 %s -O1 -triple=x86_64-unknown-linux-gnu -ftrap-unreachable=except-noreturn -S -o - 2>&1 | FileCheck %s --check-prefixes=NORETURN,COMMON +// RUN: %clang_cc1 %s -O1 -triple=x86_64-unknown-linux-gnu -ftrap-unreachable=none -S -o - 2>&1 | FileCheck %s --check-prefixes=NOTRAP,COMMON -// TRAP: ud2 // NOTRAP-NOT: ud2 [[noreturn]] @@ -9,10 +9,23 @@ void exit(int); #define NULL 0 -static void test(void) { +[[gnu::noinline]] +[[noreturn]] +void a() { +// COMMON-LABEL: a: +// TRAP: ud2 +// NORETURN: ud2 int *ptr = NULL; *ptr = 0; exit(0); } -void foo() { test(); } +[[gnu::noinline]] +[[noreturn]] + void b() { +// COMMON-LABEL: b: +// COMMON: call{{.*}} exit +// TRAP: ud2 +// NORETURN-NOT: ud2 + exit(0); +} diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c index aedbef393abcc..68db27a2f63d2 100644 --- a/clang/test/Driver/clang_f_opts.c +++ b/clang/test/Driver/clang_f_opts.c @@ -652,7 +652,11 @@ // CHECK-STRICT-ALIASING-NOT: -relaxed-aliasing // CHECK-NO-STRICT-ALIASING: -relaxed-aliasing -// RUN: %clang -### -ftrap-unreachable %s 2>&1 | FileCheck %s -check-prefix=UNREACHABLE-TRAP -// RUN: %clang -### -fno-trap-unreachable %s 2>&1 | FileCheck %s -check-prefix=NO-UNREACHABLE-TRAP -// UNREACHABLE-TRAP: "-ftrap-unreachable" -// NO-UNREACHABLE-TRAP-NOT: "-ftrap-unreachable" +// RUN: %clang -### -ftrap-unreachable=all %s 2>&1 | FileCheck %s -check-prefix=UNREACHABLE-TRAP-ALL +// RUN: %clang -### -ftrap-unreachable=none %s 2>&1 | FileCheck %s -check-prefix=UNREACHABLE-TRAP-NONE +// RUN: %clang -### -ftrap-unreachable=except-noreturn %s 2>&1 | FileCheck %s -check-prefix=UNREACHABLE-TRAP-EXCEPT-NORETURN +// RUN: %clang -### %s 2>&1 | FileCheck %s -check-prefix=UNREACHABLE-TRAP-EMPTY +// UNREACHABLE-TRAP-ALL: "-ftrap-unreachable=all" +// UNREACHABLE-TRAP-EXCEPT-NORETURN: "-ftrap-unreachable=except-noreturn" +// UNREACHABLE-TRAP-NONE: "-ftrap-unreachable=none" +// UNREACHABLE-TRAP-EMPTY-NOT: -ftrap-unreachable >From 0c42530916027af9d5e9a43366991da66c267bf3 Mon Sep 17 00:00:00 2001 From: Paul Kirth <[email protected]> Date: Mon, 12 Jan 2026 13:08:51 -0800 Subject: [PATCH 3/6] Fix formatting --- clang/include/clang/Options/Options.td | 16 +++++++++------- clang/lib/CodeGen/BackendUtil.cpp | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index f5f2eb0639bf6..58cb5c5ed7e99 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -4751,13 +4751,15 @@ defm strict_return : BoolFOption<"strict-return", " of a non-void function as unreachable">, PosFlag<SetTrue>>; -def ftrap_unreachable : Joined<["-"], "ftrap-unreachable=">, - Group<f_Group>, Visibility<[ClangOption, CC1Option]>, - HelpText<"Treat unreachable instruction as traps.">, - Values<"all,except-noreturn,none">, - NormalizedValues<["All", "ExceptNoreturn", "None"]>, - NormalizedValuesScope<"CodeGenOptions::TrapUnreachableKind">, - MarshallingInfoEnum<CodeGenOpts<"TrapUnreachable">, "None">; +def ftrap_unreachable + : Joined<["-"], "ftrap-unreachable=">, + Group<f_Group>, + Visibility<[ClangOption, CC1Option]>, + HelpText<"Treat unreachable instruction as traps.">, + Values<"all,except-noreturn,none">, + NormalizedValues<["All", "ExceptNoreturn", "None"]>, + NormalizedValuesScope<"CodeGenOptions::TrapUnreachableKind">, + MarshallingInfoEnum<CodeGenOpts<"TrapUnreachable">, "None">; let Flags = [TargetSpecific] in { defm ptrauth_intrinsics : OptInCC1FFlag<"ptrauth-intrinsics", "Enable pointer authentication intrinsics">; diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index a8072972450f9..78e94fb9bfc31 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -468,7 +468,7 @@ static bool initTargetOptions(const CompilerInstance &CI, Options.VecLib = convertDriverVectorLibraryToVectorLibrary(CodeGenOpts.getVecLib()); - switch(CodeGenOpts.getTrapUnreachable()){ + switch (CodeGenOpts.getTrapUnreachable()) { case clang::CodeGenOptions::TrapUnreachableKind::ExceptNoreturn: Options.NoTrapAfterNoreturn = true; LLVM_FALLTHROUGH; >From 7df580508c4b369164de32b521e590645239b1ab Mon Sep 17 00:00:00 2001 From: Paul Kirth <[email protected]> Date: Tue, 13 Jan 2026 13:17:51 -0800 Subject: [PATCH 4/6] Fix release notes and help text --- clang/docs/ReleaseNotes.rst | 2 ++ clang/include/clang/Options/Options.td | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 557e231a938d9..dac039623b38b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -147,6 +147,8 @@ New Compiler Flags reduced BMI only for a C++20 importable module unit. Previously the users can only generate the reduced BMI as a by-product, e.g, an object files or a full BMI. +- New option ``-ftrap-unreachable`` added to enable the existing backend option: TrapUnreachable. + This behavior is off by default (e.g. no change in the compiler's behavior) for now. Deprecated Compiler Flags ------------------------- diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 58cb5c5ed7e99..b83a4638071ee 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -4755,7 +4755,7 @@ def ftrap_unreachable : Joined<["-"], "ftrap-unreachable=">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>, - HelpText<"Treat unreachable instruction as traps.">, + HelpText<"Replace ``llvm.unreachable`` instructions with traps, when it is supported and profitable.">, Values<"all,except-noreturn,none">, NormalizedValues<["All", "ExceptNoreturn", "None"]>, NormalizedValuesScope<"CodeGenOptions::TrapUnreachableKind">, >From f067d343160891aed25e535ad7da6ac1e3d9b701 Mon Sep 17 00:00:00 2001 From: Paul Kirth <[email protected]> Date: Thu, 12 Feb 2026 09:18:31 -0800 Subject: [PATCH 5/6] Fix punctuation in option description --- clang/include/clang/Options/Options.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index b83a4638071ee..27c6642dc2f54 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -4755,7 +4755,7 @@ def ftrap_unreachable : Joined<["-"], "ftrap-unreachable=">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>, - HelpText<"Replace ``llvm.unreachable`` instructions with traps, when it is supported and profitable.">, + HelpText<"Replace ``llvm.unreachable`` instructions with traps, when it is supported and profitable">, Values<"all,except-noreturn,none">, NormalizedValues<["All", "ExceptNoreturn", "None"]>, NormalizedValuesScope<"CodeGenOptions::TrapUnreachableKind">, >From aa02129d5c03fc43d459ae16a37804f53ba84a91 Mon Sep 17 00:00:00 2001 From: Paul Kirth <[email protected]> Date: Thu, 12 Feb 2026 10:33:56 -0800 Subject: [PATCH 6/6] Make sure options are passed to the linker in LTO --- clang/lib/Driver/ToolChains/CommonArgs.cpp | 29 ++++++++++++++++++++++ clang/test/Driver/clang_f_opts.c | 12 ++++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 284dbc2a11fd6..12ce754877e44 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -847,6 +847,20 @@ static void getWebAssemblyTargetFeatures(const Driver &D, options::OPT_m_wasm_Features_Group); } +static clang::CodeGenOptions::TrapUnreachableKind +getTrapUnreachable(const llvm::opt::ArgList &Args) { + if (const Arg *A = Args.getLastArg(options::OPT_ftrap_unreachable)) { + StringRef V = A->getValue(); + if (V == "none") + return CodeGenOptions::TrapUnreachableKind::None; + if (V == "except-noreturn") + return CodeGenOptions::TrapUnreachableKind::ExceptNoreturn; + if (V == "all") + return CodeGenOptions::TrapUnreachableKind::All; + } + return CodeGenOptions::TrapUnreachableKind::None; +} + void tools::getTargetFeatures(const Driver &D, const llvm::Triple &Triple, const ArgList &Args, ArgStringList &CmdArgs, bool ForAS, bool IsAux) { @@ -1392,6 +1406,21 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args, CmdArgs.push_back( Args.MakeArgString(Twine(PluginOptPrefix) + "-time-passes")); + if (Args.hasArg(options::OPT_ftrap_unreachable)) { + switch (getTrapUnreachable(Args)) { + case clang::CodeGenOptions::TrapUnreachableKind::None: + break; + case clang::CodeGenOptions::TrapUnreachableKind::ExceptNoreturn: + CmdArgs.push_back( + Args.MakeArgString(Twine(PluginOptPrefix) + "--no-trap-after-noreturn")); + LLVM_FALLTHROUGH; + case clang::CodeGenOptions::TrapUnreachableKind::All: + CmdArgs.push_back( + Args.MakeArgString(Twine(PluginOptPrefix) + "--trap-unreachable")); + break; + } + } + addDTLTOOptions(ToolChain, Args, CmdArgs); } diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c index 68db27a2f63d2..b576ac72fd948 100644 --- a/clang/test/Driver/clang_f_opts.c +++ b/clang/test/Driver/clang_f_opts.c @@ -652,11 +652,15 @@ // CHECK-STRICT-ALIASING-NOT: -relaxed-aliasing // CHECK-NO-STRICT-ALIASING: -relaxed-aliasing -// RUN: %clang -### -ftrap-unreachable=all %s 2>&1 | FileCheck %s -check-prefix=UNREACHABLE-TRAP-ALL -// RUN: %clang -### -ftrap-unreachable=none %s 2>&1 | FileCheck %s -check-prefix=UNREACHABLE-TRAP-NONE -// RUN: %clang -### -ftrap-unreachable=except-noreturn %s 2>&1 | FileCheck %s -check-prefix=UNREACHABLE-TRAP-EXCEPT-NORETURN -// RUN: %clang -### %s 2>&1 | FileCheck %s -check-prefix=UNREACHABLE-TRAP-EMPTY +// RUN: %clang -### -flto -ftrap-unreachable=all %s 2>&1 | FileCheck %s -check-prefix=UNREACHABLE-TRAP-ALL +// RUN: %clang -### -flto -ftrap-unreachable=none %s 2>&1 | FileCheck %s -check-prefix=UNREACHABLE-TRAP-NONE +// RUN: %clang -### -flto -ftrap-unreachable=except-noreturn %s 2>&1 | FileCheck %s -check-prefix=UNREACHABLE-TRAP-EXCEPT-NORETURN +// RUN: %clang -### -flto %s 2>&1 | FileCheck %s -check-prefix=UNREACHABLE-TRAP-EMPTY // UNREACHABLE-TRAP-ALL: "-ftrap-unreachable=all" +// UNREACHABLE-TRAP-ALL: "-plugin-opt=--trap-unreachable" // UNREACHABLE-TRAP-EXCEPT-NORETURN: "-ftrap-unreachable=except-noreturn" +// UNREACHABLE-TRAP-EXCEPT-NORETURN: "-plugin-opt=--no-trap-after-noreturn" +// UNREACHABLE-TRAP-EXCEPT-NORETURN-SAME: "-plugin-opt=--trap-unreachable" // UNREACHABLE-TRAP-NONE: "-ftrap-unreachable=none" // UNREACHABLE-TRAP-EMPTY-NOT: -ftrap-unreachable +// UNREACHABLE-TRAP-EMPTY-NOT: "-plugin-opt=--trap-unreachable" _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
