Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 78d93e1

Browse files
committed
Fix Exception type in Vector<T> ctor and CopyTo methods
The JIT is throwing null-reference exceptions for these methods when a null array reference is passed to them. It would be a big performance hit to have to validate that the given array is non-null, so we will match the JIT's behavior rather than the other way around.
1 parent 1e1b6f7 commit 78d93e1

File tree

11 files changed

+44
-16
lines changed

11 files changed

+44
-16
lines changed

src/System.Numerics.Vectors/src/Resources/Strings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@
126126
<data name="Arg_MultiDimArrayNotSupported" xml:space="preserve">
127127
<value>Only one-dimensional arrays are supported</value>
128128
</data>
129+
<data name="Arg_NullArgumentNullRef" xml:space="preserve">
130+
<value>The method was called with a null array argument.</value>
131+
</data>
129132
<data name="Arg_RegisterLengthOfRangeException" xml:space="preserve">
130133
<value>length must be less than</value>
131134
</data>

src/System.Numerics.Vectors/src/System/Numerics/Vector.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,8 @@ public unsafe Vector(T[] values, int index)
363363
{
364364
if (values == null)
365365
{
366-
throw new ArgumentNullException("values");
366+
// Match the JIT's exception type here. For perf, a NullReference is thrown instead of an ArgumentNull.
367+
throw new NullReferenceException(SR.Arg_NullArgumentNullRef);
367368
}
368369
if (index < 0 || (values.Length - index) < Count)
369370
{
@@ -772,7 +773,8 @@ public unsafe void CopyTo(T[] destination, int startIndex)
772773
{
773774
if (destination == null)
774775
{
775-
throw new ArgumentNullException("values");
776+
// Match the JIT's exception type here. For perf, a NullReference is thrown instead of an ArgumentNull.
777+
throw new NullReferenceException(SR.Arg_NullArgumentNullRef);
776778
}
777779
if (startIndex < 0 || startIndex >= destination.Length)
778780
{

src/System.Numerics.Vectors/src/System/Numerics/Vector.tt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ namespace System.Numerics
175175
{
176176
if (values == null)
177177
{
178-
throw new ArgumentNullException("values");
178+
// Match the JIT's exception type here. For perf, a NullReference is thrown instead of an ArgumentNull.
179+
throw new NullReferenceException(SR.Arg_NullArgumentNullRef);
179180
}
180181
if (index < 0 || (values.Length - index) < Count)
181182
{
@@ -292,7 +293,8 @@ namespace System.Numerics
292293
{
293294
if (destination == null)
294295
{
295-
throw new ArgumentNullException("values");
296+
// Match the JIT's exception type here. For perf, a NullReference is thrown instead of an ArgumentNull.
297+
throw new NullReferenceException(SR.Arg_NullArgumentNullRef);
296298
}
297299
if (startIndex < 0 || startIndex >= destination.Length)
298300
{

src/System.Numerics.Vectors/src/System/Numerics/Vector2_Intrinsics.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,18 @@ public void CopyTo(Single[] array)
6464
public void CopyTo(Single[] array, int index)
6565
{
6666
if (array == null)
67-
throw new ArgumentNullException("values");
67+
{
68+
// Match the JIT's exception type here. For perf, a NullReference is thrown instead of an ArgumentNull.
69+
throw new NullReferenceException(SR.Arg_NullArgumentNullRef);
70+
}
6871
if (index < 0 || index >= array.Length)
72+
{
6973
throw new ArgumentOutOfRangeException(SR.Format(SR.Arg_ArgumentOutOfRangeException, index));
74+
}
7075
if ((array.Length - index) < 2)
76+
{
7177
throw new ArgumentException(SR.Format(SR.Arg_ElementsInSourceIsGreaterThanDestination, index));
78+
}
7279
array[index] = X;
7380
array[index + 1] = Y;
7481
}

src/System.Numerics.Vectors/src/System/Numerics/Vector3_Intrinsics.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,18 @@ public void CopyTo(Single[] array)
7878
public void CopyTo(Single[] array, int index)
7979
{
8080
if (array == null)
81-
throw new ArgumentNullException("values");
81+
{
82+
// Match the JIT's exception type here. For perf, a NullReference is thrown instead of an ArgumentNull.
83+
throw new NullReferenceException(SR.Arg_NullArgumentNullRef);
84+
}
8285
if (index < 0 || index >= array.Length)
86+
{
8387
throw new ArgumentOutOfRangeException(SR.Format(SR.Arg_ArgumentOutOfRangeException, index));
88+
}
8489
if ((array.Length - index) < 3)
90+
{
8591
throw new ArgumentException(SR.Format(SR.Arg_ElementsInSourceIsGreaterThanDestination, index));
92+
}
8693
array[index] = X;
8794
array[index + 1] = Y;
8895
array[index + 2] = Z;

src/System.Numerics.Vectors/src/System/Numerics/Vector4_Intrinsics.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,18 @@ public void CopyTo(Single[] array)
106106
public void CopyTo(Single[] array, int index)
107107
{
108108
if (array == null)
109-
throw new ArgumentNullException("values");
109+
{
110+
// Match the JIT's exception type here. For perf, a NullReference is thrown instead of an ArgumentNull.
111+
throw new NullReferenceException(SR.Arg_NullArgumentNullRef);
112+
}
110113
if (index < 0 || index >= array.Length)
114+
{
111115
throw new ArgumentOutOfRangeException(SR.Format(SR.Arg_ArgumentOutOfRangeException, index));
116+
}
112117
if ((array.Length - index) < 4)
118+
{
113119
throw new ArgumentException(SR.Format(SR.Arg_ElementsInSourceIsGreaterThanDestination, index));
120+
}
114121
array[index] = X;
115122
array[index + 1] = Y;
116123
array[index + 2] = Z;

src/System.Numerics.Vectors/tests/GenericVectorTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ static GenericVectorTests()
4747

4848
private void TestConstructor<T>() where T : struct
4949
{
50-
Assert.Throws<ArgumentNullException>(() => new Vector<T>((T[])null));
50+
Assert.Throws<NullReferenceException>(() => new Vector<T>((T[])null));
5151

5252
T[] values = GenerateRandomValuesForVector<T>();
5353
var vector = new Vector<T>(values);
@@ -81,7 +81,7 @@ private void TestConstructor<T>() where T : struct
8181
public void ConstructorWithOffsetDouble() { TestConstructorWithOffset<Double>(); }
8282
private void TestConstructorWithOffset<T>() where T : struct
8383
{
84-
Assert.Throws<ArgumentNullException>(() => new Vector<T>((T[])null, 0));
84+
Assert.Throws<NullReferenceException>(() => new Vector<T>((T[])null, 0));
8585

8686
int offsetAmount = Util.GenerateSingleValue<int>(2, 250);
8787
T[] values = new T[offsetAmount].Concat(GenerateRandomValuesForVector<T>()).ToArray();
@@ -307,7 +307,7 @@ private void TestCopyTo<T>() where T : struct
307307
var vector = new Vector<T>(initialValues);
308308
T[] array = new T[Vector<T>.Count];
309309

310-
Assert.Throws<ArgumentNullException>(() => vector.CopyTo(null, 0));
310+
Assert.Throws<NullReferenceException>(() => vector.CopyTo(null, 0));
311311
Assert.Throws<ArgumentOutOfRangeException>(() => vector.CopyTo(array, -1));
312312
Assert.Throws<ArgumentOutOfRangeException>(() => vector.CopyTo(array, array.Length));
313313
Assert.Throws<ArgumentException>(() => vector.CopyTo(array, array.Length - 1));

src/System.Numerics.Vectors/tests/GenericVectorTests.tt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ namespace System.Numerics.Tests
4141

4242
private void TestConstructor<T>() where T : struct
4343
{
44-
Assert.Throws<ArgumentNullException>(() => new Vector<T>((T[])null));
44+
Assert.Throws<NullReferenceException>(() => new Vector<T>((T[])null));
4545

4646
T[] values = GenerateRandomValuesForVector<T>();
4747
var vector = new Vector<T>(values);
@@ -64,7 +64,7 @@ namespace System.Numerics.Tests
6464
#>
6565
private void TestConstructorWithOffset<T>() where T : struct
6666
{
67-
Assert.Throws<ArgumentNullException>(() => new Vector<T>((T[])null, 0));
67+
Assert.Throws<NullReferenceException>(() => new Vector<T>((T[])null, 0));
6868

6969
int offsetAmount = Util.GenerateSingleValue<int>(2, 250);
7070
T[] values = new T[offsetAmount].Concat(GenerateRandomValuesForVector<T>()).ToArray();
@@ -213,7 +213,7 @@ namespace System.Numerics.Tests
213213
var vector = new Vector<T>(initialValues);
214214
T[] array = new T[Vector<T>.Count];
215215

216-
Assert.Throws<ArgumentNullException>(() => vector.CopyTo(null, 0));
216+
Assert.Throws<NullReferenceException>(() => vector.CopyTo(null, 0));
217217
Assert.Throws<ArgumentOutOfRangeException>(() => vector.CopyTo(array, -1));
218218
Assert.Throws<ArgumentOutOfRangeException>(() => vector.CopyTo(array, array.Length));
219219
Assert.Throws<ArgumentException>(() => vector.CopyTo(array, array.Length - 1));

src/System.Numerics.Vectors/tests/Vector2Tests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public void Vector2CopyToTest()
2424
float[] a = new float[3];
2525
float[] b = new float[2];
2626

27-
Assert.Throws<ArgumentNullException>(() => v1.CopyTo(null, 0));
27+
Assert.Throws<NullReferenceException>(() => v1.CopyTo(null, 0));
2828
Assert.Throws<ArgumentOutOfRangeException>(() => v1.CopyTo(a, -1));
2929
Assert.Throws<ArgumentOutOfRangeException>(() => v1.CopyTo(a, a.Length));
3030
Assert.Throws<ArgumentException>(() => v1.CopyTo(a, 2));

src/System.Numerics.Vectors/tests/Vector3Tests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public void Vector3CopyToTest()
2424
float[] a = new float[4];
2525
float[] b = new float[3];
2626

27-
Assert.Throws<ArgumentNullException>(() => v1.CopyTo(null, 0));
27+
Assert.Throws<NullReferenceException>(() => v1.CopyTo(null, 0));
2828
Assert.Throws<ArgumentOutOfRangeException>(() => v1.CopyTo(a, -1));
2929
Assert.Throws<ArgumentOutOfRangeException>(() => v1.CopyTo(a, a.Length));
3030
Assert.Throws<ArgumentException>(() => v1.CopyTo(a, a.Length - 2));

0 commit comments

Comments
 (0)