Commit f9bfdfa2 by Jonathan Wakely Committed by Jonathan Wakely

PR libstdc++/90220 Fix std::any_cast for function pointers

	PR libstdc++/90220 (partial)
	* include/std/any (any_cast<T>(any*), any_cast<T>(const any*)): Do
	not attempt ill-formed static_cast to pointers to non-object types.
	* testsuite/20_util/any/misc/any_cast.cc: Test std::any_cast with
	function types.

From-SVN: r270538
parent de6ae2ce
2019-04-24 Jonathan Wakely <jwakely@redhat.com> 2019-04-24 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/90220 (partial)
* include/std/any (any_cast<T>(any*), any_cast<T>(const any*)): Do
not attempt ill-formed static_cast to pointers to non-object types.
* testsuite/20_util/any/misc/any_cast.cc: Test std::any_cast with
function types.
* testsuite/20_util/variant/run.cc: Catch exception by reference to * testsuite/20_util/variant/run.cc: Catch exception by reference to
prevent -Wcatch-value warning. prevent -Wcatch-value warning.
......
...@@ -532,16 +532,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -532,16 +532,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _ValueType> template<typename _ValueType>
inline const _ValueType* any_cast(const any* __any) noexcept inline const _ValueType* any_cast(const any* __any) noexcept
{ {
if (__any) if constexpr (is_object_v<_ValueType>)
return static_cast<_ValueType*>(__any_caster<_ValueType>(__any)); if (__any)
return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
return nullptr; return nullptr;
} }
template<typename _ValueType> template<typename _ValueType>
inline _ValueType* any_cast(any* __any) noexcept inline _ValueType* any_cast(any* __any) noexcept
{ {
if (__any) if constexpr (is_object_v<_ValueType>)
return static_cast<_ValueType*>(__any_caster<_ValueType>(__any)); if (__any)
return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
return nullptr; return nullptr;
} }
// @} // @}
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <any> #include <any>
#include <string> #include <string>
#include <utility>
#include <cstring> #include <cstring>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
...@@ -121,6 +122,38 @@ void test05() ...@@ -121,6 +122,38 @@ void test05()
VERIFY( p == nullptr ); VERIFY( p == nullptr );
} }
void test06()
{
// The contained value of a std::any is always an object type,
// but std::any_cast does not forbid checking for function types.
any a(1);
void (*p1)() = any_cast<void()>(&a);
VERIFY( p1 == nullptr );
int (*p2)(int) = any_cast<int(int)>(&a);
VERIFY( p2 == nullptr );
int (*p3)() = any_cast<int()>(&std::as_const(a));
VERIFY( p3 == nullptr );
try {
any_cast<int(&)()>(a);
VERIFY( false );
} catch (const std::bad_any_cast&) {
}
try {
any_cast<int(&)()>(std::move(a));
VERIFY( false );
} catch (const std::bad_any_cast&) {
}
try {
any_cast<int(&)()>(std::as_const(a));
VERIFY( false );
} catch (const std::bad_any_cast&) {
}
}
int main() int main()
{ {
test01(); test01();
...@@ -128,4 +161,5 @@ int main() ...@@ -128,4 +161,5 @@ int main()
test03(); test03();
test04(); test04();
test05(); test05();
test06();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment