Skip to content

Conversation

ahatanak
Copy link
Collaborator

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

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
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Sep 25, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 25, 2025

@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-clang

Author: Akira Hatanaka (ahatanak)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/160622.diff

3 Files Affected:

  • (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (+3)
  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+11-2)
  • (added) clang/test/Driver/exception-no-rtti.cpp (+9)
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:}}

Copy link
Collaborator

@shafik shafik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like it makes sense to document this better under command line references so that users puzzled by the warning can go and pick up more details. John seemed to give a decent explanation on discourse, it may be hard to get that into a more concise form but I think we should do it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants