[gcc/devel/omp/gcc-9] Make any_cast compare typeinfo as well as function pointers

Tobias Burnus burnus@gcc.gnu.org
Thu Mar 5 13:52:00 GMT 2020


https://gcc.gnu.org/g:c7167c1b69bb9f6b6fdc61dece62038a73fb6ba4

commit c7167c1b69bb9f6b6fdc61dece62038a73fb6ba4
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu May 23 15:18:18 2019 +0100

    Make any_cast compare typeinfo as well as function pointers
    
    It's possible for the function pointer comparison to fail even though
    the type is correct, because the function could be defined multiple
    times with different addresses when shared libraries are in use.
    
    Retain the function pointer check for the common case where the check
    succeeds, but compare typeinfo (if RTTI is enabled) if the first check
    fails.
    
    Backport from mainline
    2019-05-23  Jonathan Wakely  <jwakely@redhat.com>
    
    	* include/experimental/any (__any_caster): Use RTTI if comparing
    	addresses fails, to support non-unique addresses in shared libraries.
    	* include/std/any (__any_caster): Likewise.
    	* testsuite/experimental/any/misc/any_cast_neg.cc: Use 0 for dg-error
    	line number.
    
    From-SVN: r271559

Diff:
---
 libstdc++-v3/ChangeLog                                  |  9 +++++++++
 libstdc++-v3/include/experimental/any                   | 17 ++++++++++++-----
 libstdc++-v3/include/std/any                            | 10 ++++++++--
 .../testsuite/experimental/any/misc/any_cast_neg.cc     |  2 +-
 4 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 494cf37..177491d 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -3,6 +3,15 @@
 	Backport from mainline
 	2019-05-23  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/experimental/any (__any_caster): Use RTTI if comparing
+	addresses fails, to support non-unique addresses in shared libraries.
+	* include/std/any (__any_caster): Likewise.
+	* testsuite/experimental/any/misc/any_cast_neg.cc: Use 0 for dg-error
+	line number.
+
+	Backport from mainline
+	2019-05-23  Jonathan Wakely  <jwakely@redhat.com>
+
 	PR libstdc++/90220
 	* include/experimental/any (__any_caster): Constrain to only be
 	callable for object types. Use remove_cv_t instead of decay_t.
diff --git a/libstdc++-v3/include/experimental/any b/libstdc++-v3/include/experimental/any
index 1ba29c7..33a2d51 100644
--- a/libstdc++-v3/include/experimental/any
+++ b/libstdc++-v3/include/experimental/any
@@ -429,11 +429,18 @@ inline namespace fundamentals_v1
       // is explicitly specialized and has a no-op _S_manage function.
       using _Vp = conditional_t<__and_<__does_not_decay, __is_copyable>::value,
 				_Up, any::_Op>;
-      if (__any->_M_manager != &any::_Manager<_Vp>::_S_manage)
-	return nullptr;
-      any::_Arg __arg;
-      __any->_M_manager(any::_Op_access, __any, &__arg);
-      return __arg._M_obj;
+      // First try comparing function addresses, which works without RTTI
+      if (__any->_M_manager == &any::_Manager<_Vp>::_S_manage
+#if __cpp_rtti
+	  || __any->type() == typeid(_Tp)
+#endif
+	  )
+	{
+	  any::_Arg __arg;
+	  __any->_M_manager(any::_Op_access, __any, &__arg);
+	  return __arg._M_obj;
+	}
+      return nullptr;
     }
 
   // This overload exists so that std::any_cast<void(*)()>(a) is well-formed.
diff --git a/libstdc++-v3/include/std/any b/libstdc++-v3/include/std/any
index 8cbabdd..229c7c6 100644
--- a/libstdc++-v3/include/std/any
+++ b/libstdc++-v3/include/std/any
@@ -503,6 +503,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
   // @}
 
+  /// @cond undocumented
   template<typename _Tp>
     void* __any_caster(const any* __any)
     {
@@ -516,8 +517,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // Only copy constructible types can be used for contained values:
       else if constexpr (!is_copy_constructible_v<_Up>)
 	return nullptr;
-      // This check is equivalent to __any->type() == typeid(_Tp)
-      else if (__any->_M_manager == &any::_Manager<_Up>::_S_manage)
+      // First try comparing function addresses, which works without RTTI
+      else if (__any->_M_manager == &any::_Manager<_Up>::_S_manage
+#if __cpp_rtti
+	  || __any->type() == typeid(_Tp)
+#endif
+	  )
 	{
 	  any::_Arg __arg;
 	  __any->_M_manager(any::_Op_access, __any, &__arg);
@@ -525,6 +530,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
       return nullptr;
     }
+  /// @endcond
 
   /**
    * @brief Access the contained object.
diff --git a/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc
index 145e0be..a197388 100644
--- a/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc
+++ b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc
@@ -25,5 +25,5 @@ void test01()
   using std::experimental::any_cast;
 
   const any y(1);
-  any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 357 }
+  any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 0 }
 }



More information about the Libstdc++-cvs mailing list