[HLSL] Add bounds checks for the hlsl vector arguments and return types (#130724)

fixes #129003
- fix up sema tests
- fix up templates for scalar and vector HLSL intrinsic overloads
This commit is contained in:
Farzon Lotfi
2025-03-11 15:13:00 -04:00
committed by GitHub
parent 456fa47bab
commit 1cb1407865
6 changed files with 161 additions and 59 deletions

View File

@@ -45,6 +45,10 @@ template <typename T> struct is_arithmetic {
static const bool Value = __is_arithmetic(T);
};
template <typename T, int N>
using HLSL_FIXED_VECTOR =
vector<__detail::enable_if_t<(N > 1 && N <= 4), T>, N>;
} // namespace __detail
} // namespace hlsl
#endif //_HLSL_HLSL_DETAILS_H_

View File

@@ -23,11 +23,7 @@ constexpr vector<uint, 4> d3d_color_to_ubyte4_impl(vector<float, 4> V) {
return V.zyxw * 255.001953f;
}
template <typename T>
constexpr enable_if_t<is_same<float, T>::value || is_same<half, T>::value, T>
length_impl(T X) {
return abs(X);
}
template <typename T> constexpr T length_impl(T X) { return abs(X); }
template <typename T, int N>
constexpr enable_if_t<is_same<float, T>::value || is_same<half, T>::value, T>
@@ -39,9 +35,7 @@ length_vec_impl(vector<T, N> X) {
#endif
}
template <typename T>
constexpr enable_if_t<is_same<float, T>::value || is_same<half, T>::value, T>
distance_impl(T X, T Y) {
template <typename T> constexpr T distance_impl(T X, T Y) {
return length_impl(X - Y);
}
@@ -51,9 +45,7 @@ distance_vec_impl(vector<T, N> X, vector<T, N> Y) {
return length_vec_impl(X - Y);
}
template <typename T>
constexpr enable_if_t<is_same<float, T>::value || is_same<half, T>::value, T>
reflect_impl(T I, T N) {
template <typename T> constexpr T reflect_impl(T I, T N) {
return I - 2 * N * I * N;
}

View File

@@ -89,23 +89,31 @@ void asuint(double4, out uint4, out uint4);
/// \param X The X input value.
/// \param Y The Y input value.
template <typename T>
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
const inline half distance(half X, half Y) {
const inline __detail::enable_if_t<__detail::is_arithmetic<T>::Value &&
__detail::is_same<half, T>::value,
T> distance(T X, T Y) {
return __detail::distance_impl(X, Y);
}
const inline float distance(float X, float Y) {
template <typename T>
const inline __detail::enable_if_t<
__detail::is_arithmetic<T>::Value && __detail::is_same<float, T>::value, T>
distance(T X, T Y) {
return __detail::distance_impl(X, Y);
}
template <int N>
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
const inline half distance(vector<half, N> X, vector<half, N> Y) {
const inline half distance(__detail::HLSL_FIXED_VECTOR<half, N> X,
__detail::HLSL_FIXED_VECTOR<half, N> Y) {
return __detail::distance_vec_impl(X, Y);
}
template <int N>
const inline float distance(vector<float, N> X, vector<float, N> Y) {
const inline float distance(__detail::HLSL_FIXED_VECTOR<float, N> X,
__detail::HLSL_FIXED_VECTOR<float, N> Y) {
return __detail::distance_vec_impl(X, Y);
}
@@ -119,17 +127,29 @@ const inline float distance(vector<float, N> X, vector<float, N> Y) {
///
/// Length is based on the following formula: sqrt(x[0]^2 + x[1]^2 + ...).
template <typename T>
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
const inline half length(half X) { return __detail::length_impl(X); }
const inline float length(float X) { return __detail::length_impl(X); }
const inline __detail::enable_if_t<__detail::is_arithmetic<T>::Value &&
__detail::is_same<half, T>::value,
T> length(T X) {
return __detail::length_impl(X);
}
template <typename T>
const inline __detail::enable_if_t<
__detail::is_arithmetic<T>::Value && __detail::is_same<float, T>::value, T>
length(T X) {
return __detail::length_impl(X);
}
template <int N>
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
const inline half length(vector<half, N> X) {
const inline half length(__detail::HLSL_FIXED_VECTOR<half, N> X) {
return __detail::length_vec_impl(X);
}
template <int N> const inline float length(vector<float, N> X) {
template <int N>
const inline float length(__detail::HLSL_FIXED_VECTOR<float, N> X) {
return __detail::length_vec_impl(X);
}
@@ -173,23 +193,33 @@ constexpr vector<uint, 4> D3DCOLORtoUBYTE4(vector<float, 4> V) {
///
/// Result type and the type of all operands must be the same type.
template <typename T>
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
const inline half reflect(half I, half N) {
const inline __detail::enable_if_t<__detail::is_arithmetic<T>::Value &&
__detail::is_same<half, T>::value,
T> reflect(T I, T N) {
return __detail::reflect_impl(I, N);
}
const inline float reflect(float I, float N) {
template <typename T>
const inline __detail::enable_if_t<
__detail::is_arithmetic<T>::Value && __detail::is_same<float, T>::value, T>
reflect(T I, T N) {
return __detail::reflect_impl(I, N);
}
template <int L>
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
const inline vector<half, L> reflect(vector<half, L> I, vector<half, L> N) {
const inline __detail::HLSL_FIXED_VECTOR<half, L> reflect(
__detail::HLSL_FIXED_VECTOR<half, L> I,
__detail::HLSL_FIXED_VECTOR<half, L> N) {
return __detail::reflect_vec_impl(I, N);
}
template <int L>
const inline vector<float, L> reflect(vector<float, L> I, vector<float, L> N) {
const inline __detail::HLSL_FIXED_VECTOR<float, L>
reflect(__detail::HLSL_FIXED_VECTOR<float, L> I,
__detail::HLSL_FIXED_VECTOR<float, L> N) {
return __detail::reflect_vec_impl(I, N);
}
} // namespace hlsl

View File

@@ -3,8 +3,8 @@
float test_no_second_arg(float2 p0) {
return distance(p0);
// expected-error@-1 {{no matching function for call to 'distance'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 1 was provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 1 was provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
}
@@ -12,22 +12,46 @@ float test_no_second_arg(float2 p0) {
float test_too_many_arg(float2 p0) {
return distance(p0, p0, p0);
// expected-error@-1 {{no matching function for call to 'distance'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}}
}
float test_double_inputs(double p0, double p1) {
return distance(p0, p1);
// expected-error@-1 {{call to 'distance' is ambiguous}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
// expected-error@-1 {{no matching function for call to 'distance'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
}
float test_int_inputs(int p0, int p1) {
return distance(p0, p1);
// expected-error@-1 {{call to 'distance' is ambiguous}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
// expected-error@-1 {{no matching function for call to 'distance'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
}
float1 test_vec1_inputs(float1 p0, float1 p1) {
return distance(p0, p1);
// expected-error@-1 {{no matching function for call to 'distance'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 1>>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 1>>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with N = 1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, half>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with N = 1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, float>'}}
}
typedef float float5 __attribute__((ext_vector_type(5)));
float5 test_vec5_inputs(float5 p0, float5 p1) {
return distance(p0, p1);
// expected-error@-1 {{no matching function for call to 'distance'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 5>>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 5>>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with N = 5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, half>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with N = 5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, float>'}}
}

View File

@@ -4,8 +4,8 @@ void test_too_few_arg()
{
return length();
// expected-error@-1 {{no matching function for call to 'length'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires single argument 'X', but no arguments were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires single argument 'X', but no arguments were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires single argument 'X', but no arguments were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires single argument 'X', but no arguments were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires single argument 'X', but no arguments were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires single argument 'X', but no arguments were provided}}
}
@@ -14,40 +14,68 @@ void test_too_many_arg(float2 p0)
{
return length(p0, p0);
// expected-error@-1 {{no matching function for call to 'length'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires single argument 'X', but 2 arguments were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires single argument 'X', but 2 arguments were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires single argument 'X', but 2 arguments were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires single argument 'X', but 2 arguments were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires single argument 'X', but 2 arguments were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires single argument 'X', but 2 arguments were provided}}
}
float double_to_float_type(double p0) {
return length(p0);
// expected-error@-1 {{call to 'length' is ambiguous}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
// expected-error@-1 {{no matching function for call to 'length'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = double]: no type named 'Type' in 'hlsl::__detail::enable_if<false, double>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = double]: no type named 'Type' in 'hlsl::__detail::enable_if<false, double>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: could not match '__detail::HLSL_FIXED_VECTOR<half, N>' (aka 'vector<__detail::enable_if_t<(N > 1 && N <= 4), half>, N>') against 'double'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: could not match '__detail::HLSL_FIXED_VECTOR<float, N>' (aka 'vector<__detail::enable_if_t<(N > 1 && N <= 4), float>, N>') against 'double'}}
}
float bool_to_float_type_promotion(bool p1)
{
return length(p1);
// expected-error@-1 {{call to 'length' is ambiguous}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
// expected-error@-1 {{no matching function for call to 'length'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{andidate template ignored: substitution failure [with T = bool]: no type named 'Type' in 'hlsl::__detail::enable_if<false, bool>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{andidate template ignored: substitution failure [with T = bool]: no type named 'Type' in 'hlsl::__detail::enable_if<false, bool>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: could not match '__detail::HLSL_FIXED_VECTOR<half, N>' (aka 'vector<__detail::enable_if_t<(N > 1 && N <= 4), half>, N>') against 'bool'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: could not match '__detail::HLSL_FIXED_VECTOR<float, N>' (aka 'vector<__detail::enable_if_t<(N > 1 && N <= 4), float>, N>') against 'bool'}}
}
float length_int_to_float_promotion(int p1)
{
return length(p1);
// expected-error@-1 {{call to 'length' is ambiguous}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
// expected-error@-1 {{no matching function for call to 'length'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = int]: no type named 'Type' in 'hlsl::__detail::enable_if<false, int>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = int]: no type named 'Type' in 'hlsl::__detail::enable_if<false, int>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: could not match '__detail::HLSL_FIXED_VECTOR<half, N>' (aka 'vector<__detail::enable_if_t<(N > 1 && N <= 4), half>, N>') against 'int'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: could not match '__detail::HLSL_FIXED_VECTOR<float, N>' (aka 'vector<__detail::enable_if_t<(N > 1 && N <= 4), float>, N>') against 'int'}}
}
float2 length_int2_to_float2_promotion(int2 p1)
{
return length(p1);
// expected-error@-1 {{call to 'length' is ambiguous}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
// expected-error@-1 {{no matching function for call to 'length'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = int2]}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = int2]}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{1st parameter does not match adjusted type 'vector<int, [...]>' of argument [with N = 2]}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{1st parameter does not match adjusted type 'vector<int, [...]>' of argument [with N = 2]}}
}
float1 test_vec1_inputs(float1 p0) {
return length(p0);
// expected-error@-1 {{no matching function for call to 'length'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 1>>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 1>>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with N = 1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, half>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with N = 1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, float>'}}
}
typedef float float5 __attribute__((ext_vector_type(5)));
float5 test_vec5_inputs(float5 p0) {
return length(p0);
// expected-error@-1 {{no matching function for call to 'length'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 5>>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 5>>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with N = 5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, half>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with N = 5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, float>'}}
}

View File

@@ -3,8 +3,8 @@
float test_no_second_arg(float2 p0) {
return reflect(p0);
// expected-error@-1 {{no matching function for call to 'reflect'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 1 was provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 1 was provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
}
@@ -12,22 +12,46 @@ float test_no_second_arg(float2 p0) {
float test_too_many_arg(float2 p0) {
return reflect(p0, p0, p0);
// expected-error@-1 {{no matching function for call to 'reflect'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}}
}
float test_double_inputs(double p0, double p1) {
return reflect(p0, p1);
// expected-error@-1 {{call to 'reflect' is ambiguous}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
// expected-error@-1 {{no matching function for call to 'reflect'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
}
float test_int_inputs(int p0, int p1) {
return reflect(p0, p1);
// expected-error@-1 {{call to 'reflect' is ambiguous}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
// expected-error@-1 {{no matching function for call to 'reflect'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
}
float1 test_vec1_inputs(float1 p0, float1 p1) {
return reflect(p0, p1);
// expected-error@-1 {{no matching function for call to 'reflect'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 1>>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 1>>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with L = 1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, half>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with L = 1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, float>'}}
}
typedef float float5 __attribute__((ext_vector_type(5)));
float5 test_vec5_inputs(float5 p0, float5 p1) {
return reflect(p0, p1);
// expected-error@-1 {{no matching function for call to 'reflect'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 5>>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 5>>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with L = 5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, half>'}}
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with L = 5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, float>'}}
}