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

Reply via email to