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
Int CToReactor<int32_t>::cast(int32_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); }
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
// Long CToReactor<uint64_t>::cast(uint64_t v) { return type(v); }
......
......@@ -86,14 +86,40 @@ namespace rr
// For T types that have a CToReactorT<> specialization,
// CToReactorPtrT<T>::type resolves to Pointer< CToReactorT<T> >, otherwise
// CToReactorPtrT<T>::type resolves to Pointer<Byte>.
template<typename T, typename ENABLE = void> struct CToReactorPtrT { using type = Pointer<Byte>; };
template<typename T> using CToReactorPtr = typename CToReactorPtrT<T>::type;
template<typename T, typename ENABLE = void> struct CToReactorPtrT
{
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 >
{
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.
// For T types that have a CToReactorT<> specialization,
// CToReactorT<T*>::type resolves to Pointer< CToReactorT<T> >, otherwise
......@@ -106,22 +132,6 @@ namespace rr
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.
template<typename T>
struct CToReactor<T, typename std::enable_if<std::is_enum<T>::value>::type>
......
......@@ -17,25 +17,51 @@
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>
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);
}
// 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>
CToReactorPtr<typename std::remove_pointer<T>::type>
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>
CToReactorT<typename std::underlying_type<T>::type>
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
......
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