[libcxx-commits] [libcxx] [libc++] Define behaviour for calling target() and target_type() on -fno-rtti std::functions (PR #209471)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jul 14 06:11:15 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

<details>
<summary>Changes</summary>



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


2 Files Affected:

- (modified) libcxx/include/__functional/function.h (+6-6) 
- (added) libcxx/test/extensions/libcxx/utilities/function.objects/func.wrap/func.wrap.func/rtti_mixing.sh.cpp (+33) 


``````````diff
diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h
index 90072e9528484..8160759724d96 100644
--- a/libcxx/include/__functional/function.h
+++ b/libcxx/include/__functional/function.h
@@ -145,10 +145,8 @@ class __base<_Rp(_ArgTypes...)> {
   virtual void destroy() _NOEXCEPT            = 0;
   virtual void destroy_deallocate() _NOEXCEPT = 0;
   virtual _Rp operator()(_ArgTypes&&...)      = 0;
-#  if _LIBCPP_HAS_RTTI
-  virtual const void* target(const type_info&) const _NOEXCEPT = 0;
-  virtual const std::type_info& target_type() const _NOEXCEPT  = 0;
-#  endif // _LIBCPP_HAS_RTTI
+  virtual const void* target(const type_info&) const _NOEXCEPT { return nullptr; }
+  virtual const std::type_info* target_type() const _NOEXCEPT { return nullptr; }
 };
 _LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
 
@@ -182,7 +180,7 @@ class __func<_Fp, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> {
       return std::addressof(__func_);
     return nullptr;
   }
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL const std::type_info& target_type() const _NOEXCEPT override { return typeid(_Fp); }
+  _LIBCPP_HIDE_FROM_ABI_VIRTUAL const std::type_info* target_type() const _NOEXCEPT override { return &typeid(_Fp); }
 #  endif // _LIBCPP_HAS_RTTI
 };
 
@@ -316,7 +314,9 @@ class __value_func<_Rp(_ArgTypes...)> {
   _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT {
     if (__f_ == nullptr)
       return typeid(void);
-    return __f_->target_type();
+    if (auto __ptr = __f_->target_type())
+      return *__ptr;
+    return typeid(void);
   }
 
   template <typename _Tp>
diff --git a/libcxx/test/extensions/libcxx/utilities/function.objects/func.wrap/func.wrap.func/rtti_mixing.sh.cpp b/libcxx/test/extensions/libcxx/utilities/function.objects/func.wrap/func.wrap.func/rtti_mixing.sh.cpp
new file mode 100644
index 0000000000000..9a6eda694eee8
--- /dev/null
+++ b/libcxx/test/extensions/libcxx/utilities/function.objects/func.wrap/func.wrap.func/rtti_mixing.sh.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// Ensure that passing std::functions across -fno-rtti/-frtti boundaries works.
+
+#include <cassert>
+#include <functional>
+#include <typeinfo>
+
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -frtti -o %t.tu1.o
+// RUN: %{cxx} %s %{flags} %{compile_flags} -c -DNO_RTTI -fno-rtti -o %t.tu2.o
+// RUN: %{cxx} %t.tu1.o %t.tu2.o %{flags} %{link_flags} -o %t.exe
+// RUN: %{exec} %t.exe
+
+std::function<void()> get_func();
+
+#ifdef NO_RTTI
+std::function<void()> get_func() {
+  return get_func;
+}
+#else
+int main(int, char**) {
+  assert(!get_func().target<int>());
+  assert(get_func().target_type() == typeid(void));
+
+  return 0;
+}
+#endif

``````````

</details>


https://github.com/llvm/llvm-project/pull/209471


More information about the libcxx-commits mailing list