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/+/38389 Tested-by: Ben Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Reactor/Reactor.cpp b/src/Reactor/Reactor.cpp index e217160..faa8738 100644 --- a/src/Reactor/Reactor.cpp +++ b/src/Reactor/Reactor.cpp
@@ -4365,8 +4365,6 @@ 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); }
diff --git a/src/Reactor/Traits.hpp b/src/Reactor/Traits.hpp index 4636c69..a33626b 100644 --- a/src/Reactor/Traits.hpp +++ b/src/Reactor/Traits.hpp
@@ -86,14 +86,40 @@ // 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 @@ 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>
diff --git a/src/Reactor/Traits.inl b/src/Reactor/Traits.inl index 6654344..5cd46e3 100644 --- a/src/Reactor/Traits.inl +++ b/src/Reactor/Traits.inl
@@ -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