Skip to content

Commit e3ef5f2

Browse files
authored
[HLSL] Add bounds checks for the HLSL fmod vector arguments and return types (#131035)
Fixes #131024. - Fixes template for scalar and vector `fmod` intrinsic overloads - Fixes `fmod` Sema test
1 parent 6f659b0 commit e3ef5f2

File tree

3 files changed

+53
-17
lines changed

3 files changed

+53
-17
lines changed

clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,7 @@ constexpr vector<T, L> reflect_vec_impl(vector<T, L> I, vector<T, L> N) {
5858
#endif
5959
}
6060

61-
template <typename T>
62-
constexpr enable_if_t<is_same<float, T>::value || is_same<half, T>::value, T>
63-
fmod_impl(T X, T Y) {
61+
template <typename T> constexpr T fmod_impl(T X, T Y) {
6462
#if !defined(__DIRECTX__)
6563
return __builtin_elementwise_fmod(X, Y);
6664
#else

clang/lib/Headers/hlsl/hlsl_intrinsics.h

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,19 +129,33 @@ const inline float distance(__detail::HLSL_FIXED_VECTOR<float, N> X,
129129
/// Return the floating-point remainder of the x parameter divided by the y
130130
/// parameter.
131131

132+
template <typename T>
132133
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
133-
const inline half fmod(half X, half Y) { return __detail::fmod_impl(X, Y); }
134+
const inline __detail::enable_if_t<__detail::is_arithmetic<T>::Value &&
135+
__detail::is_same<half, T>::value,
136+
T> fmod(T X, T Y) {
137+
return __detail::fmod_impl(X, Y);
138+
}
134139

135-
const inline float fmod(float X, float Y) { return __detail::fmod_impl(X, Y); }
140+
template <typename T>
141+
const inline __detail::enable_if_t<
142+
__detail::is_arithmetic<T>::Value && __detail::is_same<float, T>::value, T>
143+
fmod(T X, T Y) {
144+
return __detail::fmod_impl(X, Y);
145+
}
136146

137147
template <int N>
138148
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
139-
const inline vector<half, N> fmod(vector<half, N> X, vector<half, N> Y) {
149+
const inline __detail::HLSL_FIXED_VECTOR<half, N> fmod(
150+
__detail::HLSL_FIXED_VECTOR<half, N> X,
151+
__detail::HLSL_FIXED_VECTOR<half, N> Y) {
140152
return __detail::fmod_vec_impl(X, Y);
141153
}
142154

143155
template <int N>
144-
const inline vector<float, N> fmod(vector<float, N> X, vector<float, N> Y) {
156+
const inline __detail::HLSL_FIXED_VECTOR<float, N>
157+
fmod(__detail::HLSL_FIXED_VECTOR<float, N> X,
158+
__detail::HLSL_FIXED_VECTOR<float, N> Y) {
145159
return __detail::fmod_vec_impl(X, Y);
146160
}
147161

clang/test/SemaHLSL/BuiltIns/fmod-errors.hlsl

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,55 @@
33
float test_no_second_arg(float2 p0) {
44
return fmod(p0);
55
// expected-error@-1 {{no matching function for call to 'fmod'}}
6-
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 1 was provided}}
7-
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 1 was provided}}
6+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
7+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
88
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
99
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 1 was provided}}
1010
}
1111

1212
float test_too_many_arg(float2 p0) {
1313
return fmod(p0, p0, p0);
1414
// expected-error@-1 {{no matching function for call to 'fmod'}}
15-
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
16-
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
15+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}}
16+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}}
1717
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}}
1818
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 2 arguments, but 3 were provided}}
1919
}
2020

2121
float test_double_inputs(double p0, double p1) {
2222
return fmod(p0, p1);
23-
// expected-error@-1 {{call to 'fmod' is ambiguous}}
24-
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
25-
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
23+
// expected-error@-1 {{no matching function for call to 'fmod'}}
24+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
25+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
26+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
27+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
2628
}
2729

2830
float test_int_inputs(int p0, int p1) {
2931
return fmod(p0, p1);
30-
// expected-error@-1 {{call to 'fmod' is ambiguous}}
31-
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
32-
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function}}
32+
// expected-error@-1 {{no matching function for call to 'fmod'}}
33+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
34+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
35+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
36+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
37+
}
38+
39+
float1 test_vec1_inputs(float1 p0, float1 p1) {
40+
return fmod(p0, p1);
41+
// expected-error@-1 {{no matching function for call to 'fmod'}}
42+
// 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>>'}}
43+
// 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>>'}}
44+
// 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>'}}
45+
// 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>'}}
46+
}
47+
48+
typedef float float5 __attribute__((ext_vector_type(5)));
49+
50+
float5 test_vec5_inputs(float5 p0, float5 p1) {
51+
return fmod(p0, p1);
52+
// expected-error@-1 {{no matching function for call to 'fmod'}}
53+
// 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>>'}}
54+
// 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>>'}}
55+
// 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>'}}
56+
// 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>'}}
3357
}

0 commit comments

Comments
 (0)