[clang] [darwin] Warn when using -fno-rtti with -fexceptions (PR #160622)

Akira Hatanaka via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 24 18:03:37 PDT 2025


https://github.com/ahatanak created https://github.com/llvm/llvm-project/pull/160622

On Darwin, this configuration can lead to runtime failures. clang emits RTTI objects that the exception-handling runtime treats as distinct from those emitted in system libraries. As a result, C++ catch handlers may fail to match thrown exceptions.

See also: https://discourse.llvm.org/t/exception-handling-with-rtti-disabled-on-macos/57479

Emit a warning to discourage users from combining -fexceptions and -fno-rtti on Darwin.

rdar://110666509

>From c9df1add59472725e2cefac0f1719d0f81e0f2e2 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka <ahatanak at gmail.com>
Date: Wed, 24 Sep 2025 16:38:45 -0700
Subject: [PATCH] [darwin] Warn when using -fno-rtti with -fexceptions

On Darwin, this configuration can lead to runtime failures. clang emits RTTI
objects that the exception-handling runtime treats as distinct from those
emitted in system libraries. As a result, C++ catch handlers may fail to match
thrown exceptions.

See also: https://discourse.llvm.org/t/exception-handling-with-rtti-disabled-on-macos/57479

Emit a warning to discourage users from combining -fexceptions and -fno-rtti on
Darwin.

rdar://110666509
---
 clang/include/clang/Basic/DiagnosticDriverKinds.td |  3 +++
 clang/lib/Driver/ToolChains/Clang.cpp              | 13 +++++++++++--
 clang/test/Driver/exception-no-rtti.cpp            |  9 +++++++++
 3 files changed, 23 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Driver/exception-no-rtti.cpp

diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index ceb69091b2a51..189814d715304 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -773,6 +773,9 @@ def err_cc1_unbounded_vscale_min : Error<
 
 def err_drv_using_omit_rtti_component_without_no_rtti : Error<
   "-fexperimental-omit-vtable-rtti call only be used with -fno-rtti">;
+def warn_drv_exception_without_rtti : Warning<
+  "using exceptions without RTTI is not recommended">,
+  InGroup<DiagGroup<"exception-without-rtti">>;
 
 def err_drv_ssp_missing_offset_argument : Error<
   "'%0' is used without '-mstack-protector-guard-offset', and there is no default">;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index f67454ee517bd..c868f29c9799c 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7076,9 +7076,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
 
   ToolChain::RTTIMode RTTIMode = TC.getRTTIMode();
 
-  if (KernelOrKext || (types::isCXX(InputType) &&
-                       (RTTIMode == ToolChain::RM_Disabled)))
+  if (KernelOrKext ||
+      (types::isCXX(InputType) && (RTTIMode == ToolChain::RM_Disabled))) {
     CmdArgs.push_back("-fno-rtti");
+    RTTIMode = ToolChain::RM_Disabled;
+  } else {
+    RTTIMode = ToolChain::RM_Enabled;
+  }
 
   // -fshort-enums=0 is default for all architectures except Hexagon and z/OS.
   if (Args.hasFlag(options::OPT_fshort_enums, options::OPT_fno_short_enums,
@@ -7331,6 +7335,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   if (!C.getDriver().IsCLMode())
     EH = addExceptionArgs(Args, InputType, TC, KernelOrKext, Runtime, CmdArgs);
 
+  // Warn if exceptions are enabled without enabling RTTI on Darwin as the
+  // configuration is known to cause runtime issues in some cases.
+  if (RawTriple.isOSDarwin() && EH && RTTIMode == ToolChain::RM_Disabled)
+    D.Diag(diag::warn_drv_exception_without_rtti);
+
   // Handle exception personalities
   Arg *A = Args.getLastArg(
       options::OPT_fsjlj_exceptions, options::OPT_fseh_exceptions,
diff --git a/clang/test/Driver/exception-no-rtti.cpp b/clang/test/Driver/exception-no-rtti.cpp
new file mode 100644
index 0000000000000..835c65e15ef4a
--- /dev/null
+++ b/clang/test/Driver/exception-no-rtti.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang -x c++ -### -c -target arm64-apple-ios -fno-rtti %s 2>&1 | FileCheck -check-prefix=WARN %s
+// RUN: %clang -x c++ -### -c -target x86_64-apple-macosx -fno-rtti %s 2>&1 | FileCheck -check-prefix=WARN %s
+// RUN: %clang -x c++ -### -c -target arm64-apple-ios %s 2>&1 | FileCheck -check-prefix=OK %s
+// RUN: %clang -x c++ -### -c -target x86_64-apple-macosx %s 2>&1 | FileCheck -check-prefix=OK %s
+// RUN: %clang -x c++ -### -c -target x86_64-linux-gnu -fexceptions -fno-rtti %s 2>&1 | FileCheck -check-prefix=OK %s
+// RUN: %clang -x c++ -### -c -target x86_64-pc-windows -fexceptions -fno-rtti %s 2>&1 | FileCheck -check-prefix=OK %s
+
+// WARN: warning: using exceptions without RTTI is not recommended
+// OK-NOT: {{warning:|error:}}



More information about the cfe-commits mailing list