Gabriel B. has submitted this change. (
https://gem5-review.googlesource.com/c/public/gem5/+/67453?usp=email )
Change subject: base: Strengthen safe_cast and make it work for reference
types
......................................................................
base: Strengthen safe_cast and make it work for reference types
safe_cast now supports the exact same types as dynamic_cast would. In
particular, it now supports l-value references and rejects r-value
references.
The non-debug version has also been updated to make it build only in
the same cases as the debug version of safe_cast would.
Change-Id: I86692561c169b1ad063000c990a52ea80c6637ca
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67453
Reviewed-by: Giacomo Travaglini <giacomo.travagl...@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travagl...@arm.com>
Tested-by: kokoro <noreply+kok...@google.com>
---
M src/base/cast.hh
1 file changed, 47 insertions(+), 5 deletions(-)
Approvals:
Giacomo Travaglini: Looks good to me, approved; Looks good to me, approved
kokoro: Regressions pass
diff --git a/src/base/cast.hh b/src/base/cast.hh
index cdc3c62..01464d9 100644
--- a/src/base/cast.hh
+++ b/src/base/cast.hh
@@ -30,6 +30,8 @@
#define __BASE_CAST_HH__
#include <cassert>
+#include <type_traits>
+#include "base/logging.hh"
namespace gem5
{
@@ -44,10 +46,20 @@
template <class T, class U>
inline T
-safe_cast(U ptr)
+safe_cast(U&& ref_or_ptr)
{
- T ret = dynamic_cast<T>(ptr);
- assert(ret);
+ /*
+ * srd::forward used in conjunction with forwarding references
(template T
+ * + T&&) ensures that dynamic_cast will see the exact same type that
was
+ * passed to safe_cast (a.k.a., perfect forwarding).
+ *
+ * Not using std::forward would make safe_cast compile with references
to
+ * temporary objects and thus return a dangling reference.
+ */
+ T ret = dynamic_cast<T>(std::forward<U>(ref_or_ptr));
+ if constexpr (std::is_pointer_v<T>) {
+ gem5_assert(ret);
+ }
return ret;
}
@@ -59,9 +71,19 @@
template <class T, class U>
inline T
-safe_cast(U ptr)
+safe_cast(U&& ref_or_ptr)
{
- return static_cast<T>(ptr);
+ /*
+ * safe_cast should be reserved to polymorphic types while static_cast
is
+ * also allowed for non-polymorphic types. It could make safe_cast
able to
+ * compile in a non-debug build and fail in a debug build.
+ */
+ static_assert(std::is_polymorphic_v<
+ std::remove_pointer_t<
+ std::remove_reference_t<
+ U>>
+ >);
+ return static_cast<T>(std::forward<U>(ref_or_ptr));
}
#endif
--
To view, visit
https://gem5-review.googlesource.com/c/public/gem5/+/67453?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I86692561c169b1ad063000c990a52ea80c6637ca
Gerrit-Change-Number: 67453
Gerrit-PatchSet: 4
Gerrit-Owner: Gabriel B. <gabriel.bus...@arteris.com>
Gerrit-Reviewer: Bobby Bruce <bbr...@ucdavis.edu>
Gerrit-Reviewer: Daniel Carvalho <oda...@yahoo.com.br>
Gerrit-Reviewer: Gabriel B. <gabriel.bus...@arteris.com>
Gerrit-Reviewer: Giacomo Travaglini <giacomo.travagl...@arm.com>
Gerrit-Reviewer: kokoro <noreply+kok...@google.com>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org