Commit a9f511bc by Ben Clayton

Reactor/Traits: Fix brokenness with CToReactor::cast of pointers.

The documentation states: "For T types that have a CToReactorT<> specialization, CToReactorPtrT<T>::type resolves to Pointer< CToReactorT<T> >, otherwise CToReactorPtrT<T>::type resolves to Pointer<Byte>." However, the CToReactorPtrT<T>::cast() function did not behave correctly for some Pointer<Byte> cases. Now fixed. Bug: b/143479561 Change-Id: I64387653e9edf21eb7fa91e3bcb7b76171c7bca4 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/38389Tested-by: 's avatarBen Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent 7e11f46d
...@@ -4365,8 +4365,6 @@ namespace rr ...@@ -4365,8 +4365,6 @@ namespace rr
Int CToReactor<int32_t>::cast(int32_t v) { return type(v); } Int CToReactor<int32_t>::cast(int32_t v) { return type(v); }
UInt CToReactor<uint32_t>::cast(uint32_t v) { return type(v); } UInt CToReactor<uint32_t>::cast(uint32_t v) { return type(v); }
Float CToReactor<float>::cast(float v) { return type(v); } Float CToReactor<float>::cast(float v) { return type(v); }
Pointer<Byte> CToReactor<void*>::cast(void* v) { return ConstantPointer(v); }
Pointer<Byte> CToReactor<const char*>::cast(const char* v) { return ConstantPointer(v); }
// TODO: Long has no constructor that takes a uint64_t // TODO: Long has no constructor that takes a uint64_t
// Long CToReactor<uint64_t>::cast(uint64_t v) { return type(v); } // Long CToReactor<uint64_t>::cast(uint64_t v) { return type(v); }
......
...@@ -86,14 +86,40 @@ namespace rr ...@@ -86,14 +86,40 @@ namespace rr
// For T types that have a CToReactorT<> specialization, // For T types that have a CToReactorT<> specialization,
// CToReactorPtrT<T>::type resolves to Pointer< CToReactorT<T> >, otherwise // CToReactorPtrT<T>::type resolves to Pointer< CToReactorT<T> >, otherwise
// CToReactorPtrT<T>::type resolves to Pointer<Byte>. // CToReactorPtrT<T>::type resolves to Pointer<Byte>.
template<typename T, typename ENABLE = void> struct CToReactorPtrT { using type = Pointer<Byte>; }; template<typename T, typename ENABLE = void> struct CToReactorPtrT
template<typename T> using CToReactorPtr = typename CToReactorPtrT<T>::type; {
using type = Pointer<Byte>;
static inline type cast(const T* v); // implemented in Traits.inl
};
// CToReactorPtrT specialization for T types that have a CToReactorT<>
// specialization.
template<typename T> struct CToReactorPtrT<T, typename std::enable_if< IsDefined< CToReactorT<T> >::value>::type > template<typename T> struct CToReactorPtrT<T, typename std::enable_if< IsDefined< CToReactorT<T> >::value>::type >
{ {
using type = Pointer< CToReactorT<T> >; using type = Pointer< CToReactorT<T> >;
static inline type cast(T v); // implemented in Traits.inl static inline type cast(const T* v); // implemented in Traits.inl
};
// CToReactorPtrT specialization for void*.
// Maps to Pointer<Byte> instead of Pointer<Void>.
template<> struct CToReactorPtrT<void, void>
{
using type = Pointer<Byte>;
static inline type cast(const void* v); // implemented in Traits.inl
}; };
// CToReactorPtr specialization for function pointer types.
// Maps to Pointer<Byte>.
// Drops the 'const' qualifier from the cast() method to avoid warnings
// about const having no meaning for function types.
template<typename T> struct CToReactorPtrT<T, typename std::enable_if< std::is_function<T>::value >::type >
{
using type = Pointer<Byte>;
static inline type cast(T* v); // implemented in Traits.inl
};
template<typename T> using CToReactorPtr = typename CToReactorPtrT<T>::type;
// CToReactor specialization for pointer types. // CToReactor specialization for pointer types.
// For T types that have a CToReactorT<> specialization, // For T types that have a CToReactorT<> specialization,
// CToReactorT<T*>::type resolves to Pointer< CToReactorT<T> >, otherwise // CToReactorT<T*>::type resolves to Pointer< CToReactorT<T> >, otherwise
...@@ -106,22 +132,6 @@ namespace rr ...@@ -106,22 +132,6 @@ namespace rr
static inline type cast(T v); // implemented in Traits.inl static inline type cast(T v); // implemented in Traits.inl
}; };
// CToReactor specialization for void*.
// Maps to Pointer<Byte> instead of Pointer<Void>.
template<> struct CToReactor<void*>
{
using type = Pointer<Byte>;
static type cast(void* v); // implemented in Reactor.cpp
};
// CToReactor specialization for void*.
// Maps to Pointer<Byte> instead of Pointer<Void>.
template<> struct CToReactor<const char*>
{
using type = Pointer<Byte>;
static type cast(const char* v); // implemented in Reactor.cpp
};
// CToReactor specialization for enum types. // CToReactor specialization for enum types.
template<typename T> template<typename T>
struct CToReactor<T, typename std::enable_if<std::is_enum<T>::value>::type> struct CToReactor<T, typename std::enable_if<std::is_enum<T>::value>::type>
......
...@@ -17,25 +17,51 @@ ...@@ -17,25 +17,51 @@
namespace rr namespace rr
{ {
// Non-specialized implementation of CToReactorPtrT::cast() defaults to
// returning a ConstantPointer for v.
template<typename T, typename ENABLE>
Pointer<Byte> CToReactorPtrT<T, ENABLE>::cast(const T* v)
{
return ConstantPointer(v);
}
// CToReactorPtrT specialization for T types that have a CToReactorT<>
// specialization.
template<typename T> template<typename T>
Pointer<CToReactorT<T>> Pointer<CToReactorT<T>>
CToReactorPtrT<T, typename std::enable_if< IsDefined< CToReactorT<T> >::value>::type >::cast(T v) CToReactorPtrT<T, typename std::enable_if< IsDefined< CToReactorT<T> >::value>::type >::cast(const T* v)
{ {
return type(v); return type(v);
} }
// CToReactorPtrT specialization for void*.
Pointer<Byte> CToReactorPtrT<void, void>::cast(const void* v)
{
return ConstantPointer(v);
}
// CToReactorPtrT specialization for function pointer types.
template<typename T>
Pointer<Byte>
CToReactorPtrT<T, typename std::enable_if< std::is_function<T>::value >::type>::cast(T* v)
{
return ConstantPointer(v);
}
// CToReactor specialization for pointer types.
template<typename T> template<typename T>
CToReactorPtr<typename std::remove_pointer<T>::type> CToReactorPtr<typename std::remove_pointer<T>::type>
CToReactor<T, typename std::enable_if<std::is_pointer<T>::value>::type>::cast(T v) CToReactor<T, typename std::enable_if<std::is_pointer<T>::value>::type>::cast(T v)
{ {
return type(v); return CToReactorPtrT<elem>::cast(v);
} }
// CToReactor specialization for enum types.
template<typename T> template<typename T>
CToReactorT<typename std::underlying_type<T>::type> CToReactorT<typename std::underlying_type<T>::type>
CToReactor<T, typename std::enable_if<std::is_enum<T>::value>::type>::cast(T v) CToReactor<T, typename std::enable_if<std::is_enum<T>::value>::type>::cast(T v)
{ {
return type(v); return CToReactor<underlying>::cast(v);
} }
} // namespace rr } // namespace rr
......
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