From 661eef88dad12a307f8f396422a73992517731ce Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Fri, 11 Nov 2022 10:38:16 +0300 Subject: [PATCH 01/16] add implementation --- .../src/Resources/Strings.resx | 18 ++++++ .../src/System/ArgumentOutOfRangeException.cs | 58 +++++++++++++++++++ .../System.Runtime/ref/System.Runtime.cs | 7 +++ 3 files changed, 83 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index 762886be5e9f3..328b027dc3b11 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -1862,6 +1862,24 @@ Year must be between 1 and 9999. + + '{0}' must be non-zero value. + + + '{0}' must be non-negative value. + + + '{0}' must be lower than or equal '{1}'. + + + '{0}' must be lower than '{1}'. + + + '{0}' must be greater than or equal '{1}'. + + + '{0}' must be greater than '{1}'. + Function does not accept floating point Not-a-Number values. diff --git a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs index 65563b20d495b..713db97069549 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs @@ -11,6 +11,9 @@ =============================================================================*/ using System.Runtime.Serialization; +using System.Runtime.CompilerServices; +using System.Diagnostics.CodeAnalysis; +using System.Numerics; namespace System { @@ -85,5 +88,60 @@ public override string Message // Gets the value of the argument that caused the exception. public virtual object? ActualValue => _actualValue; + + [DoesNotReturn] + private static void Throw(string? paramName, string message) + { + throw new ArgumentOutOfRangeException(paramName, message); + } + + public static void ThrowIfZero(T value, [CallerArgumentExpression(nameof(value))] string? paramName = null) + where T : INumberBase + { + if (T.IsZero(value)) + Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeNonZero, paramName)); + } + + public static void ThrowIfNegative(T value, [CallerArgumentExpression(nameof(value))] string? paramName = null) + where T : INumberBase + { + if (T.IsNegative(value)) + Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeNonNegative, paramName)); + } + + public static void ThrowIfNegativeOrZero(T value, [CallerArgumentExpression(nameof(value))] string? paramName = null) + where T : INumberBase + { + ThrowIfNegative(value, paramName); + ThrowIfZero(value, paramName); + } + + public static void ThrowIfGreaterThan(T value, T other, [CallerArgumentExpression(nameof(value))] string? paramName = null) + where T : IComparable + { + if (value.CompareTo(other) == 1) + Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLowerOrEqual, paramName, other)); + } + + public static void ThrowIfGreaterThanOrEqual(T value, T other, [CallerArgumentExpression(nameof(value))] string? paramName = null) + where T : IComparable + { + if (value.CompareTo(other) != -1) + Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLower, paramName, other)); + } + + public static void ThrowIfLessThan(T value, T other, [CallerArgumentExpression(nameof(value))] string? paramName = null) + where T : IComparable + { + if (value.CompareTo(other) == -1) + Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeGreaterOrEqual, paramName, other)); + } + + public static void ThrowIfLessThanOrEqual(T value, T other, [CallerArgumentExpression(nameof(value))] string? paramName = null) + where T : IComparable + { + if (value.CompareTo(other) != 1) + Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeGreater, paramName, other)); + } } } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index c26b436f41097..5789e46552e1a 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -301,6 +301,13 @@ public ArgumentOutOfRangeException(string? paramName, string? message) { } public virtual object? ActualValue { get { throw null; } } public override string Message { get { throw null; } } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } + public static void ThrowIfZero(T value, [System.Runtime.CompilerServices.CallerArgumentExpressionAttribute(nameof(value))] string? paramName = null) where T : System.Numerics.INumberBase { throw null; } + public static void ThrowIfNegative(T value, [System.Runtime.CompilerServices.CallerArgumentExpressionAttribute(nameof(value))] string? paramName = null) where T : System.Numerics.INumberBase { throw null; } + public static void ThrowIfNegativeOrZero(T value, [System.Runtime.CompilerServices.CallerArgumentExpressionAttribute(nameof(value))] string? paramName = null) where T : System.Numerics.INumberBase { throw null; } + public static void ThrowIfGreaterThan(T value, T other, [System.Runtime.CompilerServices.CallerArgumentExpressionAttribute(nameof(value))] string? paramName = null) where T : System.IComparable { throw null; } + public static void ThrowIfGreaterThanOrEqual(T value, T other, [System.Runtime.CompilerServices.CallerArgumentExpressionAttribute(nameof(value))] string? paramName = null) where T : System.IComparable { throw null; } + public static void ThrowIfLessThan(T value, T other, [System.Runtime.CompilerServices.CallerArgumentExpressionAttribute(nameof(value))] string? paramName = null) where T : System.IComparable { throw null; } + public static void ThrowIfLessThanOrEqual(T value, T other, [System.Runtime.CompilerServices.CallerArgumentExpressionAttribute(nameof(value))] string? paramName = null) where T : System.IComparable { throw null; } } public partial class ArithmeticException : System.SystemException { From 1900b3a2b46aa571b9d6dc598b4337555cbe7b09 Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Fri, 11 Nov 2022 12:16:28 +0300 Subject: [PATCH 02/16] add docs --- .../src/System/ArgumentOutOfRangeException.cs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs index 713db97069549..cdb01ad081ded 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs @@ -95,6 +95,9 @@ private static void Throw(string? paramName, string message) throw new ArgumentOutOfRangeException(paramName, message); } + /// Throws an if is zero. + /// The argument to validate as non-zero. + /// The name of the parameter with which corresponds. public static void ThrowIfZero(T value, [CallerArgumentExpression(nameof(value))] string? paramName = null) where T : INumberBase { @@ -102,6 +105,9 @@ public static void ThrowIfZero(T value, [CallerArgumentExpression(nameof(valu Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeNonZero, paramName)); } + /// Throws an if is negative. + /// The argument to validate as non-negative. + /// The name of the parameter with which corresponds. public static void ThrowIfNegative(T value, [CallerArgumentExpression(nameof(value))] string? paramName = null) where T : INumberBase { @@ -109,6 +115,9 @@ public static void ThrowIfNegative(T value, [CallerArgumentExpression(nameof( Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeNonNegative, paramName)); } + /// Throws an if is negative or zero. + /// The argument to validate as non-zero or non-negative. + /// The name of the parameter with which corresponds. public static void ThrowIfNegativeOrZero(T value, [CallerArgumentExpression(nameof(value))] string? paramName = null) where T : INumberBase { @@ -116,6 +125,10 @@ public static void ThrowIfNegativeOrZero(T value, [CallerArgumentExpression(n ThrowIfZero(value, paramName); } + /// Throws an if is greater than . + /// The argument to validate as less or equal than . + /// The value to compare with . + /// The name of the parameter with which corresponds. public static void ThrowIfGreaterThan(T value, T other, [CallerArgumentExpression(nameof(value))] string? paramName = null) where T : IComparable { @@ -123,6 +136,10 @@ public static void ThrowIfGreaterThan(T value, T other, [CallerArgumentExpres Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLowerOrEqual, paramName, other)); } + /// Throws an if is greater than or equal . + /// The argument to validate as less than . + /// The value to compare with . + /// The name of the parameter with which corresponds. public static void ThrowIfGreaterThanOrEqual(T value, T other, [CallerArgumentExpression(nameof(value))] string? paramName = null) where T : IComparable { @@ -130,6 +147,10 @@ public static void ThrowIfGreaterThanOrEqual(T value, T other, [CallerArgumen Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLower, paramName, other)); } + /// Throws an if is less than . + /// The argument to validate as greatar than or equal than . + /// The value to compare with . + /// The name of the parameter with which corresponds. public static void ThrowIfLessThan(T value, T other, [CallerArgumentExpression(nameof(value))] string? paramName = null) where T : IComparable { @@ -137,6 +158,10 @@ public static void ThrowIfLessThan(T value, T other, [CallerArgumentExpressio Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeGreaterOrEqual, paramName, other)); } + /// Throws an if is less than or equal . + /// The argument to validate as greatar than than . + /// The value to compare with . + /// The name of the parameter with which corresponds. public static void ThrowIfLessThanOrEqual(T value, T other, [CallerArgumentExpression(nameof(value))] string? paramName = null) where T : IComparable { From 39e6e81d996988c287634a223c011f3674597da6 Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Fri, 11 Nov 2022 12:26:29 +0300 Subject: [PATCH 03/16] Add some tests --- .../ArgumentOutOfRangeExceptionTests.cs | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/libraries/System.Runtime/tests/System/ArgumentOutOfRangeExceptionTests.cs b/src/libraries/System.Runtime/tests/System/ArgumentOutOfRangeExceptionTests.cs index 96d625f7ba9a3..4af30630bd7a9 100644 --- a/src/libraries/System.Runtime/tests/System/ArgumentOutOfRangeExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/ArgumentOutOfRangeExceptionTests.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Numerics; using Xunit; namespace System.Tests @@ -65,5 +66,70 @@ public static void Ctor_String_Object_String() Assert.Contains(argumentName, exception.Message); Assert.Contains(argumentValue.ToString(), exception.Message); } + + private static Action ZeroHelper(T value) where T : INumberBase => () => ArgumentOutOfRangeException.ThrowIfZero(value); + private static Action NegativeOrZeroHelper(T value) where T : INumberBase => () => ArgumentOutOfRangeException.ThrowIfNegativeOrZero(value); + private static Action GreaterThanHelper(T value, T other) where T : IComparable => () => ArgumentOutOfRangeException.ThrowIfGreaterThan(value, other); + private static Action GreaterThanOrEqualHelper(T value, T other) where T : IComparable => () => ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(value, other); + private static Action LessThanHelper(T value, T other) where T : IComparable => () => ArgumentOutOfRangeException.ThrowIfLessThan(value, other); + private static Action LessThanOrEqualHelper(T value, T other) where T : IComparable => () => ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(value, other); + + [Fact] + public static void GenericHelpers_ThrowIfZero_Throws() + { + Assert.Throws(ZeroHelper(0)); + Assert.Throws(ZeroHelper(0)); + + Assert.Throws(ZeroHelper(0.0f)); + Assert.Throws(ZeroHelper(-0.0f)); + Assert.Throws(ZeroHelper(0)); + Assert.Throws(ZeroHelper(+0.0)); + Assert.Throws(ZeroHelper(-0.0)); + } + + [Fact] + public static void GenericHelpers_ThrowIfNegativeZero_Throws() + { + Assert.Throws(NegativeOrZeroHelper(-1)); + + Assert.Throws(NegativeOrZeroHelper(-0.0f)); + Assert.Throws(NegativeOrZeroHelper(-0.0)); + } + + [Fact] + public static void GenericHelpers_ThrowIfGreaterThan_Throws() + { + Assert.Throws(GreaterThanHelper(1, 0)); + Assert.Throws(GreaterThanHelper(1, 0)); + Assert.Throws(GreaterThanHelper(1.000000001, 1)); + Assert.Throws(GreaterThanHelper(1.00001f, 1)); + } + + [Fact] + public static void GenericHelpers_ThrowIfGreaterThanOrEqual_Throws() + { + Assert.Throws(GreaterThanOrEqualHelper(1, 1)); + Assert.Throws(GreaterThanOrEqualHelper(1, 1)); + Assert.Throws(GreaterThanOrEqualHelper(1, 1)); + Assert.Throws(GreaterThanOrEqualHelper(1, 1)); + } + + [Fact] + public static void GenericHelpers_ThrowIfLessThan_Throws() + { + Assert.Throws(LessThanHelper(0, 1)); + Assert.Throws(LessThanHelper(0, 1)); + Assert.Throws(LessThanHelper(1, 1.000000001)); + Assert.Throws(LessThanHelper(1, 1.00001f)); + } + + [Fact] + public static void GenericHelpers_ThrowIfLessThanOrEqual_Throws() + { + Assert.Throws(LessThanOrEqualHelper(1, 1)); + Assert.Throws(LessThanOrEqualHelper(1, 1)); + Assert.Throws(LessThanOrEqualHelper(1, 1)); + Assert.Throws(LessThanOrEqualHelper(1, 1)); + } } } From 600b9477d01589abc91323c36f3d7e84a55e0549 Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Fri, 11 Nov 2022 16:24:47 +0300 Subject: [PATCH 04/16] Some replacements in CoreLib root namespace --- .../src/System/BitConverter.cs | 10 ++--- .../src/System/Buffer.cs | 9 ++-- .../src/System/Convert.cs | 45 +++++++------------ .../src/System/DateTime.cs | 5 +-- .../src/System/Decimal.cs | 3 +- .../src/System/String.Comparison.cs | 10 +---- .../src/System/String.Manipulation.cs | 40 +++++------------ .../src/System/String.cs | 36 +++++---------- .../src/System/Version.cs | 27 ++++------- 9 files changed, 56 insertions(+), 129 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs b/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs index 60caf8e76d275..b2c7b20887846 100644 --- a/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs @@ -657,8 +657,7 @@ public static string ToString(byte[] value, int startIndex, int length) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value); if (startIndex < 0 || startIndex >= value.Length && startIndex > 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_IndexMustBeLess); - if (length < 0) - throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_GenericPositive); + ArgumentOutOfRangeException.ThrowIfNegative(length); if (startIndex > value.Length - length) ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall, ExceptionArgument.value); @@ -667,11 +666,8 @@ public static string ToString(byte[] value, int startIndex, int length) return string.Empty; } - if (length > (int.MaxValue / 3)) - { - // (int.MaxValue / 3) == 715,827,882 Bytes == 699 MB - throw new ArgumentOutOfRangeException(nameof(length), SR.Format(SR.ArgumentOutOfRange_LengthTooLarge, int.MaxValue / 3)); - } + // (int.MaxValue / 3) == 715,827,882 Bytes == 699 MB + ArgumentOutOfRangeException.ThrowIfGreaterThan(length, (int.MaxValue / 3)); return string.Create(length * 3 - 1, (value, startIndex, length), static (dst, state) => { diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffer.cs b/src/libraries/System.Private.CoreLib/src/System/Buffer.cs index c14bd684cb017..a2e841804617c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffer.cs @@ -42,12 +42,9 @@ public static unsafe void BlockCopy(Array src, int srcOffset, Array dst, int dst } } - if (srcOffset < 0) - throw new ArgumentOutOfRangeException(nameof(srcOffset), SR.ArgumentOutOfRange_MustBeNonNegInt32); - if (dstOffset < 0) - throw new ArgumentOutOfRangeException(nameof(dstOffset), SR.ArgumentOutOfRange_MustBeNonNegInt32); - if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_MustBeNonNegInt32); + ArgumentOutOfRangeException.ThrowIfNegative(srcOffset); + ArgumentOutOfRangeException.ThrowIfNegative(dstOffset); + ArgumentOutOfRangeException.ThrowIfNegative(count); nuint uCount = (nuint)count; nuint uSrcOffset = (nuint)srcOffset; diff --git a/src/libraries/System.Private.CoreLib/src/System/Convert.cs b/src/libraries/System.Private.CoreLib/src/System/Convert.cs index e8e617cd6fa45..e0d5f7449b5f4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Convert.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Convert.cs @@ -2314,12 +2314,9 @@ public static string ToBase64String(byte[] inArray, int offset, int length, Base { ArgumentNullException.ThrowIfNull(inArray); - if (length < 0) - throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_IndexMustBeLessOrEqual); - if (offset < 0) - throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_GenericPositive); - if (offset > (inArray.Length - length)) - throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_OffsetLength); + ArgumentOutOfRangeException.ThrowIfNegative(length); + ArgumentOutOfRangeException.ThrowIfNegative(offset); + ArgumentOutOfRangeException.ThrowIfGreaterThan(offset, (inArray.Length - length)); return ToBase64String(new ReadOnlySpan(inArray, offset, length), options); } @@ -2371,19 +2368,15 @@ public static unsafe int ToBase64CharArray(byte[] inArray, int offsetIn, int len ArgumentNullException.ThrowIfNull(inArray); ArgumentNullException.ThrowIfNull(outArray); - if (length < 0) - throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_IndexMustBeLessOrEqual); - if (offsetIn < 0) - throw new ArgumentOutOfRangeException(nameof(offsetIn), SR.ArgumentOutOfRange_GenericPositive); - if (offsetOut < 0) - throw new ArgumentOutOfRangeException(nameof(offsetOut), SR.ArgumentOutOfRange_GenericPositive); + ArgumentOutOfRangeException.ThrowIfNegative(length); + ArgumentOutOfRangeException.ThrowIfNegative(offsetIn); + ArgumentOutOfRangeException.ThrowIfNegative(offsetOut); if (options < Base64FormattingOptions.None || options > Base64FormattingOptions.InsertLineBreaks) throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, (int)options), nameof(options)); int inArrayLength = inArray.Length; - if (offsetIn > (inArrayLength - length)) - throw new ArgumentOutOfRangeException(nameof(offsetIn), SR.ArgumentOutOfRange_OffsetLength); + ArgumentOutOfRangeException.ThrowIfGreaterThan(offsetIn, (inArrayLength - length)); if (inArrayLength == 0) return 0; @@ -2395,8 +2388,7 @@ public static unsafe int ToBase64CharArray(byte[] inArray, int offsetIn, int len bool insertLineBreaks = options == Base64FormattingOptions.InsertLineBreaks; int charLengthRequired = ToBase64_CalculateAndValidateOutputLength(length, insertLineBreaks); - if (offsetOut > outArrayLength - charLengthRequired) - throw new ArgumentOutOfRangeException(nameof(offsetOut), SR.ArgumentOutOfRange_OffsetOut); + ArgumentOutOfRangeException.ThrowIfGreaterThan(offsetOut, outArrayLength - charLengthRequired); if (Vector128.IsHardwareAccelerated && !insertLineBreaks && length >= Base64VectorizationLengthThreshold) { @@ -2784,14 +2776,11 @@ public static byte[] FromBase64CharArray(char[] inArray, int offset, int length) { ArgumentNullException.ThrowIfNull(inArray); - if (length < 0) - throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_IndexMustBeLessOrEqual); + ArgumentOutOfRangeException.ThrowIfNegative(length); - if (offset < 0) - throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_GenericPositive); + ArgumentOutOfRangeException.ThrowIfNegative(offset); - if (offset > inArray.Length - length) - throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_OffsetLength); + ArgumentOutOfRangeException.ThrowIfGreaterThan(offset, inArray.Length - length); if (inArray.Length == 0) { @@ -2980,12 +2969,9 @@ public static string ToHexString(byte[] inArray, int offset, int length) { ArgumentNullException.ThrowIfNull(inArray); - if (length < 0) - throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_IndexMustBeLessOrEqual); - if (offset < 0) - throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_GenericPositive); - if (offset > (inArray.Length - length)) - throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_OffsetLength); + ArgumentOutOfRangeException.ThrowIfNegative(length); + ArgumentOutOfRangeException.ThrowIfNegative(offset); + ArgumentOutOfRangeException.ThrowIfGreaterThan(offset, (inArray.Length - length)); return ToHexString(new ReadOnlySpan(inArray, offset, length)); } @@ -3000,8 +2986,7 @@ public static string ToHexString(ReadOnlySpan bytes) { if (bytes.Length == 0) return string.Empty; - if (bytes.Length > int.MaxValue / 2) - throw new ArgumentOutOfRangeException(nameof(bytes), SR.ArgumentOutOfRange_InputTooLarge); + ArgumentOutOfRangeException.ThrowIfGreaterThan(bytes.Length, int.MaxValue / 2); return HexConverter.ToString(bytes, HexConverter.Casing.Upper); } diff --git a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs index 11c566195daf8..3fd605e0e8ace 100644 --- a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs +++ b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs @@ -1700,10 +1700,7 @@ public long ToFileTimeUtc() } ticks -= FileTimeOffset; - if (ticks < 0) - { - throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_FileTimeInvalid); - } + ArgumentOutOfRangeException.ThrowIfNegative(ticks); return ticks; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Decimal.cs b/src/libraries/System.Private.CoreLib/src/System/Decimal.cs index cc7354014f489..71895a2427352 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Decimal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Decimal.cs @@ -307,8 +307,7 @@ public Decimal(ReadOnlySpan bits) // public Decimal(int lo, int mid, int hi, bool isNegative, byte scale) { - if (scale > 28) - throw new ArgumentOutOfRangeException(nameof(scale), SR.ArgumentOutOfRange_DecimalScale); + ArgumentOutOfRangeException.ThrowIfGreaterThan(scale, 28); _lo64 = (uint)lo + ((ulong)(uint)mid << 32); _hi32 = (uint)hi; _flags = ((int)scale) << 16; diff --git a/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs b/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs index 4469a15bab522..b3758d335c900 100644 --- a/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs +++ b/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs @@ -380,10 +380,7 @@ public static int Compare(string? strA, int indexA, string? strB, int indexB, in return strA == null ? -1 : 1; } - if (length < 0) - { - throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NegativeLength); - } + ArgumentOutOfRangeException.ThrowIfNegative(length); if (indexA < 0 || indexB < 0) { @@ -475,10 +472,7 @@ public static int CompareOrdinal(string? strA, int indexA, string? strB, int ind // COMPAT: Checking for nulls should become before the arguments are validated, // but other optimizations which allow us to return early should come after. - if (length < 0) - { - throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NegativeCount); - } + ArgumentOutOfRangeException.ThrowIfNegative(length); if (indexA < 0 || indexB < 0) { diff --git a/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs b/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs index 50b30cb5b01ec..b79074703451d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs @@ -558,18 +558,9 @@ private static string JoinCore(ReadOnlySpan separator, string?[] value, in { ArgumentNullException.ThrowIfNull(value); - if (startIndex < 0) - { - throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex); - } - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NegativeCount); - } - if (startIndex > value.Length - count) - { - throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_IndexCountBuffer); - } + ArgumentOutOfRangeException.ThrowIfNegative(startIndex); + ArgumentOutOfRangeException.ThrowIfNegative(count); + ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex, value.Length - count); return JoinCore(separator, new ReadOnlySpan(value, startIndex, count)); } @@ -824,8 +815,7 @@ private static string JoinCore(ReadOnlySpan separator, ReadOnlySpan oldLength - startIndex) - throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_IndexCount); + ArgumentOutOfRangeException.ThrowIfGreaterThan(count, oldLength - startIndex); if (count == 0) return this; @@ -1349,9 +1335,7 @@ public string[] Split(char[]? separator, int count, StringSplitOptions options) private string[] SplitInternal(ReadOnlySpan separators, int count, StringSplitOptions options) { - if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count), - SR.ArgumentOutOfRange_NegativeCount); + ArgumentOutOfRangeException.ThrowIfNegative(count); CheckStringSplitOptions(options); @@ -1412,11 +1396,7 @@ public string[] Split(string[]? separator, int count, StringSplitOptions options private string[] SplitInternal(string? separator, string?[]? separators, int count, StringSplitOptions options) { - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count), - SR.ArgumentOutOfRange_NegativeCount); - } + ArgumentOutOfRangeException.ThrowIfNegative(count); CheckStringSplitOptions(options); diff --git a/src/libraries/System.Private.CoreLib/src/System/String.cs b/src/libraries/System.Private.CoreLib/src/System/String.cs index 39d9153f1d172..9bf98c0d7a647 100644 --- a/src/libraries/System.Private.CoreLib/src/System/String.cs +++ b/src/libraries/System.Private.CoreLib/src/System/String.cs @@ -86,14 +86,11 @@ private static string Ctor(char[] value, int startIndex, int length) { ArgumentNullException.ThrowIfNull(value); - if (startIndex < 0) - throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex); + ArgumentOutOfRangeException.ThrowIfNegative(startIndex); - if (length < 0) - throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NegativeLength); + ArgumentOutOfRangeException.ThrowIfNegative(length); - if (startIndex > value.Length - length) - throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_IndexMustBeLessOrEqual); + ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex, value.Length - length); if (length == 0) return Empty; @@ -139,11 +136,9 @@ private static unsafe string Ctor(char* ptr) private static unsafe string Ctor(char* ptr, int startIndex, int length) { - if (length < 0) - throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NegativeLength); + ArgumentOutOfRangeException.ThrowIfNegative(length); - if (startIndex < 0) - throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex); + ArgumentOutOfRangeException.ThrowIfNegative(startIndex); char* pStart = ptr + startIndex; @@ -190,11 +185,9 @@ private static unsafe string Ctor(sbyte* value) private static unsafe string Ctor(sbyte* value, int startIndex, int length) { - if (startIndex < 0) - throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex); + ArgumentOutOfRangeException.ThrowIfNegative(startIndex); - if (length < 0) - throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NegativeLength); + ArgumentOutOfRangeException.ThrowIfNegative(length); if (value == null) { @@ -250,11 +243,9 @@ private static unsafe string Ctor(sbyte* value, int startIndex, int length, Enco if (enc == null) return new string(value, startIndex, length); - if (length < 0) - throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NeedNonNegNum); + ArgumentOutOfRangeException.ThrowIfNegative(length); - if (startIndex < 0) - throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex); + ArgumentOutOfRangeException.ThrowIfNegative(startIndex); if (value == null) { @@ -396,12 +387,9 @@ public unsafe void CopyTo(int sourceIndex, char[] destination, int destinationIn { ArgumentNullException.ThrowIfNull(destination); - if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NegativeCount); - if (sourceIndex < 0) - throw new ArgumentOutOfRangeException(nameof(sourceIndex), SR.ArgumentOutOfRange_IndexMustBeLessOrEqual); - if (count > Length - sourceIndex) - throw new ArgumentOutOfRangeException(nameof(sourceIndex), SR.ArgumentOutOfRange_IndexCount); + ArgumentOutOfRangeException.ThrowIfNegative(count); + ArgumentOutOfRangeException.ThrowIfNegative(sourceIndex); + ArgumentOutOfRangeException.ThrowIfGreaterThan(count, Length - sourceIndex); if (destinationIndex > destination.Length - count || destinationIndex < 0) throw new ArgumentOutOfRangeException(nameof(destinationIndex), SR.ArgumentOutOfRange_IndexCount); diff --git a/src/libraries/System.Private.CoreLib/src/System/Version.cs b/src/libraries/System.Private.CoreLib/src/System/Version.cs index 1c7751e6f19c4..83435447f6f39 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Version.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Version.cs @@ -26,17 +26,13 @@ public sealed class Version : ICloneable, IComparable, IComparable, IE public Version(int major, int minor, int build, int revision) { - if (major < 0) - throw new ArgumentOutOfRangeException(nameof(major), SR.ArgumentOutOfRange_Version); + ArgumentOutOfRangeException.ThrowIfNegative(major); - if (minor < 0) - throw new ArgumentOutOfRangeException(nameof(minor), SR.ArgumentOutOfRange_Version); + ArgumentOutOfRangeException.ThrowIfNegative(minor); - if (build < 0) - throw new ArgumentOutOfRangeException(nameof(build), SR.ArgumentOutOfRange_Version); + ArgumentOutOfRangeException.ThrowIfNegative(build); - if (revision < 0) - throw new ArgumentOutOfRangeException(nameof(revision), SR.ArgumentOutOfRange_Version); + ArgumentOutOfRangeException.ThrowIfNegative(revision); _Major = major; _Minor = minor; @@ -46,14 +42,11 @@ public Version(int major, int minor, int build, int revision) public Version(int major, int minor, int build) { - if (major < 0) - throw new ArgumentOutOfRangeException(nameof(major), SR.ArgumentOutOfRange_Version); + ArgumentOutOfRangeException.ThrowIfNegative(major); - if (minor < 0) - throw new ArgumentOutOfRangeException(nameof(minor), SR.ArgumentOutOfRange_Version); + ArgumentOutOfRangeException.ThrowIfNegative(minor); - if (build < 0) - throw new ArgumentOutOfRangeException(nameof(build), SR.ArgumentOutOfRange_Version); + ArgumentOutOfRangeException.ThrowIfNegative(build); _Major = major; _Minor = minor; @@ -63,11 +56,9 @@ public Version(int major, int minor, int build) public Version(int major, int minor) { - if (major < 0) - throw new ArgumentOutOfRangeException(nameof(major), SR.ArgumentOutOfRange_Version); + ArgumentOutOfRangeException.ThrowIfNegative(major); - if (minor < 0) - throw new ArgumentOutOfRangeException(nameof(minor), SR.ArgumentOutOfRange_Version); + ArgumentOutOfRangeException.ThrowIfNegative(minor); _Major = major; _Minor = minor; From 91e279e744eb587f7277f7616f2f3d0ce2dfbfcc Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Fri, 11 Nov 2022 19:07:36 +0300 Subject: [PATCH 05/16] Apply suggestions from code review Co-authored-by: Stephen Toub --- .../src/System/ArgumentOutOfRangeException.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs index cdb01ad081ded..a8b42154ab953 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs @@ -132,7 +132,7 @@ public static void ThrowIfNegativeOrZero(T value, [CallerArgumentExpression(n public static void ThrowIfGreaterThan(T value, T other, [CallerArgumentExpression(nameof(value))] string? paramName = null) where T : IComparable { - if (value.CompareTo(other) == 1) + if (value.CompareTo(other) > 0) Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLowerOrEqual, paramName, other)); } @@ -143,7 +143,7 @@ public static void ThrowIfGreaterThan(T value, T other, [CallerArgumentExpres public static void ThrowIfGreaterThanOrEqual(T value, T other, [CallerArgumentExpression(nameof(value))] string? paramName = null) where T : IComparable { - if (value.CompareTo(other) != -1) + if (value.CompareTo(other) >= 0) Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLower, paramName, other)); } @@ -154,7 +154,7 @@ public static void ThrowIfGreaterThanOrEqual(T value, T other, [CallerArgumen public static void ThrowIfLessThan(T value, T other, [CallerArgumentExpression(nameof(value))] string? paramName = null) where T : IComparable { - if (value.CompareTo(other) == -1) + if (value.CompareTo(other) < 0) Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeGreaterOrEqual, paramName, other)); } @@ -165,7 +165,7 @@ public static void ThrowIfLessThan(T value, T other, [CallerArgumentExpressio public static void ThrowIfLessThanOrEqual(T value, T other, [CallerArgumentExpression(nameof(value))] string? paramName = null) where T : IComparable { - if (value.CompareTo(other) != 1) + if (value.CompareTo(other) <= 0) Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeGreater, paramName, other)); } } From 541389f5b1ac766f5f6f3caee73436da9878ac5c Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Sun, 13 Nov 2022 23:04:33 +0300 Subject: [PATCH 06/16] Inline negativeorzero --- .../System.Private.CoreLib/src/Resources/Strings.resx | 3 +++ .../src/System/ArgumentOutOfRangeException.cs | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index 328b027dc3b11..c4ad4fce13ebd 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -1868,6 +1868,9 @@ '{0}' must be non-negative value. + + '{0}' must be non-negative and non-zero value. + '{0}' must be lower than or equal '{1}'. diff --git a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs index a8b42154ab953..56c11d373ace0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs @@ -121,8 +121,8 @@ public static void ThrowIfNegative(T value, [CallerArgumentExpression(nameof( public static void ThrowIfNegativeOrZero(T value, [CallerArgumentExpression(nameof(value))] string? paramName = null) where T : INumberBase { - ThrowIfNegative(value, paramName); - ThrowIfZero(value, paramName); + if (T.IsNegative(value) || T.IsZero(value)) + Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeNonNegativeNonZero, paramName)); } /// Throws an if is greater than . From ad4aff8f148c4594dacdf29cf51227ac9486df6b Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Sun, 13 Nov 2022 23:04:55 +0300 Subject: [PATCH 07/16] fix messages --- .../System.Private.CoreLib/src/Resources/Strings.resx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index c4ad4fce13ebd..3f0069ab734fe 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -1863,13 +1863,13 @@ Year must be between 1 and 9999. - '{0}' must be non-zero value. + '{0}' must be a non-zero value. - '{0}' must be non-negative value. + '{0}' must be a non-negative value. - '{0}' must be non-negative and non-zero value. + '{0}' must be a non-negative and non-zero value. '{0}' must be lower than or equal '{1}'. From 722f5b70af45b9348fe647fc6ac76704c2e1665a Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Sun, 13 Nov 2022 23:17:07 +0300 Subject: [PATCH 08/16] fix throwing --- .../src/System/ArgumentOutOfRangeException.cs | 54 +++++++++++++++---- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs index 56c11d373ace0..7443652209de5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs @@ -90,9 +90,45 @@ public override string Message public virtual object? ActualValue => _actualValue; [DoesNotReturn] - private static void Throw(string? paramName, string message) + private static void ThrowZero(string paramName) { - throw new ArgumentOutOfRangeException(paramName, message); + throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeNonZero, paramName)); + } + + [DoesNotReturn] + private static void ThrowNegative(string paramName) + { + throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeNonNegative, paramName)); + } + + [DoesNotReturn] + private static void ThrowNegativeOrZero(string paramName) + { + throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeNonNegativeNonZero, paramName)); + } + + [DoesNotReturn] + private static void ThrowGreater(string paramName, object other) + { + throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLowerOrEqual, paramName, other)); + } + + [DoesNotReturn] + private static void ThrowGreaterEqual(string paramName, object other) + { + throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLower, paramName, other)); + } + + [DoesNotReturn] + private static void ThrowLess(string paramName, object other) + { + throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeGreaterOrEqual, paramName, other)); + } + + [DoesNotReturn] + private static void ThrowLessEqual(string paramName, object other) + { + throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeGreater, paramName, other)); } /// Throws an if is zero. @@ -102,7 +138,7 @@ public static void ThrowIfZero(T value, [CallerArgumentExpression(nameof(valu where T : INumberBase { if (T.IsZero(value)) - Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeNonZero, paramName)); + ThrowZero(paramName); } /// Throws an if is negative. @@ -112,7 +148,7 @@ public static void ThrowIfNegative(T value, [CallerArgumentExpression(nameof( where T : INumberBase { if (T.IsNegative(value)) - Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeNonNegative, paramName)); + ThrowNegative(paramName); } /// Throws an if is negative or zero. @@ -122,7 +158,7 @@ public static void ThrowIfNegativeOrZero(T value, [CallerArgumentExpression(n where T : INumberBase { if (T.IsNegative(value) || T.IsZero(value)) - Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeNonNegativeNonZero, paramName)); + ThrowNegativeOrZero(paramName); } /// Throws an if is greater than . @@ -133,7 +169,7 @@ public static void ThrowIfGreaterThan(T value, T other, [CallerArgumentExpres where T : IComparable { if (value.CompareTo(other) > 0) - Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLowerOrEqual, paramName, other)); + ThrowGreater(paramName, other); } /// Throws an if is greater than or equal . @@ -144,7 +180,7 @@ public static void ThrowIfGreaterThanOrEqual(T value, T other, [CallerArgumen where T : IComparable { if (value.CompareTo(other) >= 0) - Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLower, paramName, other)); + ThrowGreaterEqual(paramName, other); } /// Throws an if is less than . @@ -155,7 +191,7 @@ public static void ThrowIfLessThan(T value, T other, [CallerArgumentExpressio where T : IComparable { if (value.CompareTo(other) < 0) - Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeGreaterOrEqual, paramName, other)); + ThrowLess(paramName, other); } /// Throws an if is less than or equal . @@ -166,7 +202,7 @@ public static void ThrowIfLessThanOrEqual(T value, T other, [CallerArgumentEx where T : IComparable { if (value.CompareTo(other) <= 0) - Throw(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeGreater, paramName, other)); + ThrowLessEqual(paramName, other); } } } From 3c5fe6dea3858aa419f38ccd4ddd1060d72e6dcb Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Sun, 13 Nov 2022 23:20:59 +0300 Subject: [PATCH 09/16] fix paramnames --- src/libraries/System.Private.CoreLib/src/System/Convert.cs | 2 +- src/libraries/System.Private.CoreLib/src/System/String.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Convert.cs b/src/libraries/System.Private.CoreLib/src/System/Convert.cs index e0d5f7449b5f4..3cb9c5efd00a0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Convert.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Convert.cs @@ -2986,7 +2986,7 @@ public static string ToHexString(ReadOnlySpan bytes) { if (bytes.Length == 0) return string.Empty; - ArgumentOutOfRangeException.ThrowIfGreaterThan(bytes.Length, int.MaxValue / 2); + ArgumentOutOfRangeException.ThrowIfGreaterThan(bytes.Length, int.MaxValue / 2, nameof(bytes)); return HexConverter.ToString(bytes, HexConverter.Casing.Upper); } diff --git a/src/libraries/System.Private.CoreLib/src/System/String.cs b/src/libraries/System.Private.CoreLib/src/System/String.cs index 9bf98c0d7a647..113f343f04d2c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/String.cs +++ b/src/libraries/System.Private.CoreLib/src/System/String.cs @@ -389,7 +389,7 @@ public unsafe void CopyTo(int sourceIndex, char[] destination, int destinationIn ArgumentOutOfRangeException.ThrowIfNegative(count); ArgumentOutOfRangeException.ThrowIfNegative(sourceIndex); - ArgumentOutOfRangeException.ThrowIfGreaterThan(count, Length - sourceIndex); + ArgumentOutOfRangeException.ThrowIfGreaterThan(count, Length - sourceIndex, nameof(sourceIndex)); if (destinationIndex > destination.Length - count || destinationIndex < 0) throw new ArgumentOutOfRangeException(nameof(destinationIndex), SR.ArgumentOutOfRange_IndexCount); From 65d5d235087f815254bbcdd149c0638d6ebdd13b Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Mon, 14 Nov 2022 00:34:52 +0300 Subject: [PATCH 10/16] fix nullability --- .../src/System/ArgumentOutOfRangeException.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs index 7443652209de5..a8fcbe906bad8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs @@ -90,43 +90,43 @@ public override string Message public virtual object? ActualValue => _actualValue; [DoesNotReturn] - private static void ThrowZero(string paramName) + private static void ThrowZero(string? paramName) { throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeNonZero, paramName)); } [DoesNotReturn] - private static void ThrowNegative(string paramName) + private static void ThrowNegative(string? paramName) { throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeNonNegative, paramName)); } [DoesNotReturn] - private static void ThrowNegativeOrZero(string paramName) + private static void ThrowNegativeOrZero(string? paramName) { throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeNonNegativeNonZero, paramName)); } [DoesNotReturn] - private static void ThrowGreater(string paramName, object other) + private static void ThrowGreater(string? paramName, object other) { throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLowerOrEqual, paramName, other)); } [DoesNotReturn] - private static void ThrowGreaterEqual(string paramName, object other) + private static void ThrowGreaterEqual(string? paramName, object other) { throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLower, paramName, other)); } [DoesNotReturn] - private static void ThrowLess(string paramName, object other) + private static void ThrowLess(string? paramName, object other) { throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeGreaterOrEqual, paramName, other)); } [DoesNotReturn] - private static void ThrowLessEqual(string paramName, object other) + private static void ThrowLessEqual(string? paramName, object other) { throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeGreater, paramName, other)); } From 9f81c222a83ba77a8705cd6c2f80cbf7a62a8c45 Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Mon, 14 Nov 2022 10:52:44 +0300 Subject: [PATCH 11/16] one more paramname fix --- src/libraries/System.Private.CoreLib/src/System/DateTime.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs index 3fd605e0e8ace..eb3916ee12a09 100644 --- a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs +++ b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs @@ -1700,7 +1700,7 @@ public long ToFileTimeUtc() } ticks -= FileTimeOffset; - ArgumentOutOfRangeException.ThrowIfNegative(ticks); + ArgumentOutOfRangeException.ThrowIfNegative(ticks, null); return ticks; } From 0709d8c6077b8bd1ebf5cf79b9a005f7671f6078 Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Wed, 23 Nov 2022 22:20:10 +0300 Subject: [PATCH 12/16] make private throwers generic --- .../src/System/ArgumentOutOfRangeException.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs index a8fcbe906bad8..22ab9f2cac9b7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs @@ -108,25 +108,25 @@ private static void ThrowNegativeOrZero(string? paramName) } [DoesNotReturn] - private static void ThrowGreater(string? paramName, object other) + private static void ThrowGreater(string? paramName, T other) { throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLowerOrEqual, paramName, other)); } [DoesNotReturn] - private static void ThrowGreaterEqual(string? paramName, object other) + private static void ThrowGreaterEqual(string? paramName, T other) { throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLower, paramName, other)); } [DoesNotReturn] - private static void ThrowLess(string? paramName, object other) + private static void ThrowLess(string? paramName, T other) { throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeGreaterOrEqual, paramName, other)); } [DoesNotReturn] - private static void ThrowLessEqual(string? paramName, object other) + private static void ThrowLessEqual(string? paramName, T other) { throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeGreater, paramName, other)); } From 0067cbdc84eb8612b2fa97962d5b6f8595184537 Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Thu, 24 Nov 2022 20:11:18 +0300 Subject: [PATCH 13/16] Apply suggestions from code review Co-authored-by: Dan Moseley --- .../System.Private.CoreLib/src/Resources/Strings.resx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index 3f0069ab734fe..a7784bea17472 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -1872,13 +1872,13 @@ '{0}' must be a non-negative and non-zero value. - '{0}' must be lower than or equal '{1}'. + '{0}' must be lower than or equal to '{1}'. '{0}' must be lower than '{1}'. - '{0}' must be greater than or equal '{1}'. + '{0}' must be greater than or equal to '{1}'. '{0}' must be greater than '{1}'. From b760a77df82390c6b259f6d186f9341685e6c090 Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Fri, 25 Nov 2022 01:54:16 +0300 Subject: [PATCH 14/16] apply review comments --- .../src/Resources/Strings.resx | 8 +-- .../src/System/ArgumentOutOfRangeException.cs | 4 +- .../src/System/Convert.cs | 4 +- .../src/System/Version.cs | 6 -- .../ArgumentOutOfRangeExceptionTests.cs | 57 ++++++++++--------- 5 files changed, 38 insertions(+), 41 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index a7784bea17472..7b4a0d3a4015d 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -1871,11 +1871,11 @@ '{0}' must be a non-negative and non-zero value. - - '{0}' must be lower than or equal to '{1}'. + + '{0}' must be less than or equal to '{1}'. - - '{0}' must be lower than '{1}'. + + '{0}' must be less than '{1}'. '{0}' must be greater than or equal to '{1}'. diff --git a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs index 22ab9f2cac9b7..912df39b273de 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ArgumentOutOfRangeException.cs @@ -110,13 +110,13 @@ private static void ThrowNegativeOrZero(string? paramName) [DoesNotReturn] private static void ThrowGreater(string? paramName, T other) { - throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLowerOrEqual, paramName, other)); + throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLessOrEqual, paramName, other)); } [DoesNotReturn] private static void ThrowGreaterEqual(string? paramName, T other) { - throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLower, paramName, other)); + throw new ArgumentOutOfRangeException(paramName, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeLess, paramName, other)); } [DoesNotReturn] diff --git a/src/libraries/System.Private.CoreLib/src/System/Convert.cs b/src/libraries/System.Private.CoreLib/src/System/Convert.cs index 3cb9c5efd00a0..291a8d3339f60 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Convert.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Convert.cs @@ -2316,7 +2316,7 @@ public static string ToBase64String(byte[] inArray, int offset, int length, Base ArgumentOutOfRangeException.ThrowIfNegative(length); ArgumentOutOfRangeException.ThrowIfNegative(offset); - ArgumentOutOfRangeException.ThrowIfGreaterThan(offset, (inArray.Length - length)); + ArgumentOutOfRangeException.ThrowIfGreaterThan(offset, inArray.Length - length); return ToBase64String(new ReadOnlySpan(inArray, offset, length), options); } @@ -2376,7 +2376,7 @@ public static unsafe int ToBase64CharArray(byte[] inArray, int offsetIn, int len int inArrayLength = inArray.Length; - ArgumentOutOfRangeException.ThrowIfGreaterThan(offsetIn, (inArrayLength - length)); + ArgumentOutOfRangeException.ThrowIfGreaterThan(offsetIn, inArrayLength - length); if (inArrayLength == 0) return 0; diff --git a/src/libraries/System.Private.CoreLib/src/System/Version.cs b/src/libraries/System.Private.CoreLib/src/System/Version.cs index 83435447f6f39..c672ef8d69d07 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Version.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Version.cs @@ -27,11 +27,8 @@ public sealed class Version : ICloneable, IComparable, IComparable, IE public Version(int major, int minor, int build, int revision) { ArgumentOutOfRangeException.ThrowIfNegative(major); - ArgumentOutOfRangeException.ThrowIfNegative(minor); - ArgumentOutOfRangeException.ThrowIfNegative(build); - ArgumentOutOfRangeException.ThrowIfNegative(revision); _Major = major; @@ -43,9 +40,7 @@ public Version(int major, int minor, int build, int revision) public Version(int major, int minor, int build) { ArgumentOutOfRangeException.ThrowIfNegative(major); - ArgumentOutOfRangeException.ThrowIfNegative(minor); - ArgumentOutOfRangeException.ThrowIfNegative(build); _Major = major; @@ -57,7 +52,6 @@ public Version(int major, int minor, int build) public Version(int major, int minor) { ArgumentOutOfRangeException.ThrowIfNegative(major); - ArgumentOutOfRangeException.ThrowIfNegative(minor); _Major = major; diff --git a/src/libraries/System.Runtime/tests/System/ArgumentOutOfRangeExceptionTests.cs b/src/libraries/System.Runtime/tests/System/ArgumentOutOfRangeExceptionTests.cs index 4af30630bd7a9..d8822b0457cc8 100644 --- a/src/libraries/System.Runtime/tests/System/ArgumentOutOfRangeExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/ArgumentOutOfRangeExceptionTests.cs @@ -67,6 +67,7 @@ public static void Ctor_String_Object_String() Assert.Contains(argumentValue.ToString(), exception.Message); } + private const string HelpersParamName = "value"; private static Action ZeroHelper(T value) where T : INumberBase => () => ArgumentOutOfRangeException.ThrowIfZero(value); private static Action NegativeOrZeroHelper(T value) where T : INumberBase => () => ArgumentOutOfRangeException.ThrowIfNegativeOrZero(value); private static Action GreaterThanHelper(T value, T other) where T : IComparable => () => ArgumentOutOfRangeException.ThrowIfGreaterThan(value, other); @@ -77,59 +78,61 @@ public static void Ctor_String_Object_String() [Fact] public static void GenericHelpers_ThrowIfZero_Throws() { - Assert.Throws(ZeroHelper(0)); - Assert.Throws(ZeroHelper(0)); - - Assert.Throws(ZeroHelper(0.0f)); - Assert.Throws(ZeroHelper(-0.0f)); - Assert.Throws(ZeroHelper(0)); - Assert.Throws(ZeroHelper(+0.0)); - Assert.Throws(ZeroHelper(-0.0)); + + AssertExtensions.Throws(HelpersParamName, ZeroHelper(0.0f)); + AssertExtensions.Throws(HelpersParamName, ZeroHelper(0)); + AssertExtensions.Throws(HelpersParamName, ZeroHelper(0)); + + AssertExtensions.Throws(HelpersParamName, ZeroHelper(0.0f)); + AssertExtensions.Throws(HelpersParamName, ZeroHelper(-0.0f)); + AssertExtensions.Throws(HelpersParamName, ZeroHelper(0)); + AssertExtensions.Throws(HelpersParamName, ZeroHelper(+0.0)); + AssertExtensions.Throws(HelpersParamName, ZeroHelper(-0.0)); } [Fact] public static void GenericHelpers_ThrowIfNegativeZero_Throws() { - Assert.Throws(NegativeOrZeroHelper(-1)); + AssertExtensions.Throws(HelpersParamName, NegativeOrZeroHelper(-1)); - Assert.Throws(NegativeOrZeroHelper(-0.0f)); - Assert.Throws(NegativeOrZeroHelper(-0.0)); + AssertExtensions.Throws(HelpersParamName, NegativeOrZeroHelper(-0.0f)); + AssertExtensions.Throws(HelpersParamName, NegativeOrZeroHelper(-0.0)); } [Fact] public static void GenericHelpers_ThrowIfGreaterThan_Throws() { - Assert.Throws(GreaterThanHelper(1, 0)); - Assert.Throws(GreaterThanHelper(1, 0)); - Assert.Throws(GreaterThanHelper(1.000000001, 1)); - Assert.Throws(GreaterThanHelper(1.00001f, 1)); + AssertExtensions.Throws(HelpersParamName, GreaterThanHelper(1, 0)); + AssertExtensions.Throws(HelpersParamName, GreaterThanHelper(1, 0)); + AssertExtensions.Throws(HelpersParamName, GreaterThanHelper(1.000000001, 1)); + AssertExtensions.Throws(HelpersParamName, GreaterThanHelper(1.00001f, 1)); } [Fact] public static void GenericHelpers_ThrowIfGreaterThanOrEqual_Throws() { - Assert.Throws(GreaterThanOrEqualHelper(1, 1)); - Assert.Throws(GreaterThanOrEqualHelper(1, 1)); - Assert.Throws(GreaterThanOrEqualHelper(1, 1)); - Assert.Throws(GreaterThanOrEqualHelper(1, 1)); + AssertExtensions.Throws(HelpersParamName, GreaterThanOrEqualHelper(1, 1)); + AssertExtensions.Throws(HelpersParamName, GreaterThanOrEqualHelper(1, 1)); + AssertExtensions.Throws(HelpersParamName, GreaterThanOrEqualHelper(1, 1)); + AssertExtensions.Throws(HelpersParamName, GreaterThanOrEqualHelper(1, 1)); } [Fact] public static void GenericHelpers_ThrowIfLessThan_Throws() { - Assert.Throws(LessThanHelper(0, 1)); - Assert.Throws(LessThanHelper(0, 1)); - Assert.Throws(LessThanHelper(1, 1.000000001)); - Assert.Throws(LessThanHelper(1, 1.00001f)); + AssertExtensions.Throws(HelpersParamName, LessThanHelper(0, 1)); + AssertExtensions.Throws(HelpersParamName, LessThanHelper(0, 1)); + AssertExtensions.Throws(HelpersParamName, LessThanHelper(1, 1.000000001)); + AssertExtensions.Throws(HelpersParamName, LessThanHelper(1, 1.00001f)); } [Fact] public static void GenericHelpers_ThrowIfLessThanOrEqual_Throws() { - Assert.Throws(LessThanOrEqualHelper(1, 1)); - Assert.Throws(LessThanOrEqualHelper(1, 1)); - Assert.Throws(LessThanOrEqualHelper(1, 1)); - Assert.Throws(LessThanOrEqualHelper(1, 1)); + AssertExtensions.Throws(HelpersParamName, LessThanOrEqualHelper(1, 1)); + AssertExtensions.Throws(HelpersParamName, LessThanOrEqualHelper(1, 1)); + AssertExtensions.Throws(HelpersParamName, LessThanOrEqualHelper(1, 1)); + AssertExtensions.Throws(HelpersParamName, LessThanOrEqualHelper(1, 1)); } } } From 6893695d5d3b19de50f5f5bcf98f1188b0599412 Mon Sep 17 00:00:00 2001 From: hrrrrustic Date: Fri, 25 Nov 2022 01:56:34 +0300 Subject: [PATCH 15/16] few more cleanups --- src/libraries/System.Private.CoreLib/src/System/Convert.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Convert.cs b/src/libraries/System.Private.CoreLib/src/System/Convert.cs index 291a8d3339f60..4ddd917956e19 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Convert.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Convert.cs @@ -2775,11 +2775,8 @@ private static void CopyToTempBufferWithoutWhiteSpace(ReadOnlySpan chars, public static byte[] FromBase64CharArray(char[] inArray, int offset, int length) { ArgumentNullException.ThrowIfNull(inArray); - ArgumentOutOfRangeException.ThrowIfNegative(length); - ArgumentOutOfRangeException.ThrowIfNegative(offset); - ArgumentOutOfRangeException.ThrowIfGreaterThan(offset, inArray.Length - length); if (inArray.Length == 0) @@ -2971,7 +2968,7 @@ public static string ToHexString(byte[] inArray, int offset, int length) ArgumentOutOfRangeException.ThrowIfNegative(length); ArgumentOutOfRangeException.ThrowIfNegative(offset); - ArgumentOutOfRangeException.ThrowIfGreaterThan(offset, (inArray.Length - length)); + ArgumentOutOfRangeException.ThrowIfGreaterThan(offset, inArray.Length - length); return ToHexString(new ReadOnlySpan(inArray, offset, length)); } From dd0ad2f7be8eb760ea3a68bcbdef1d4e4761255a Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Thu, 1 Dec 2022 12:03:24 -0500 Subject: [PATCH 16/16] Address my own PR feedback and use helpers in more places --- .../src/System/GC.CoreCLR.cs | 12 ++---- .../System/Reflection/Emit/MethodBuilder.cs | 3 +- .../RuntimeHelpers.CoreCLR.cs | 3 +- .../src/Resources/Strings.resx | 3 -- .../src/System/BitConverter.cs | 2 +- .../System/Buffers/ConfigurableArrayPool.cs | 17 ++------ .../TlsOverPerCoreLockedStacksArrayPool.cs | 4 +- .../src/System/DateTime.cs | 5 ++- .../System/Diagnostics/Tracing/EventPipe.cs | 10 +---- .../src/System/Numerics/Matrix4x4.cs | 37 +++++------------ .../src/System/String.Manipulation.cs | 1 - .../src/System/String.cs | 14 ++----- .../src/System/Text/Encoding.cs | 41 ++++--------------- .../System/Threading/ManualResetEventSlim.cs | 18 ++------ .../System/Threading/ReaderWriterLockSlim.cs | 3 +- .../ArgumentOutOfRangeExceptionTests.cs | 3 -- 16 files changed, 47 insertions(+), 129 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs index 082e91bc719c9..25445726f2900 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs @@ -626,14 +626,10 @@ private static bool InvokeMemoryLoadChangeNotifications() /// delegate to invoke when operation occurss internal static void RegisterMemoryLoadChangeNotification(float lowMemoryPercent, float highMemoryPercent, Action notification) { - if (highMemoryPercent < 0 || highMemoryPercent > 1.0 || highMemoryPercent <= lowMemoryPercent) - { - throw new ArgumentOutOfRangeException(nameof(highMemoryPercent)); - } - if (lowMemoryPercent < 0) - { - throw new ArgumentOutOfRangeException(nameof(lowMemoryPercent)); - } + ArgumentOutOfRangeException.ThrowIfLessThan(highMemoryPercent, 0); + ArgumentOutOfRangeException.ThrowIfGreaterThan(highMemoryPercent, 1.0); + ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(highMemoryPercent, lowMemoryPercent); + ArgumentOutOfRangeException.ThrowIfLessThan(lowMemoryPercent, 0); ArgumentNullException.ThrowIfNull(notification); lock (s_notifications) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/MethodBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/MethodBuilder.cs index a5f4fdd8ba7d5..c4892500d1746 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/MethodBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/MethodBuilder.cs @@ -652,8 +652,7 @@ public void SetSignature( public ParameterBuilder DefineParameter(int position, ParameterAttributes attributes, string? strParamName) { - if (position < 0) - throw new ArgumentOutOfRangeException(SR.ArgumentOutOfRange_ParamSequence); + ArgumentOutOfRangeException.ThrowIfNegative(position); ThrowIfGeneric(); m_containingType.ThrowIfCreated(); diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs index 14c36da882f52..86afe347af9c8 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs @@ -314,8 +314,7 @@ public static IntPtr AllocateTypeAssociatedMemory(Type type, int size) if (type is not RuntimeType rt) throw new ArgumentException(SR.Arg_MustBeType, nameof(type)); - if (size < 0) - throw new ArgumentOutOfRangeException(nameof(size)); + ArgumentOutOfRangeException.ThrowIfNegative(size); return AllocateTypeAssociatedMemory(new QCallTypeHandle(ref rt), (uint)size); } diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index 7b4a0d3a4015d..51b4292025eeb 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -2756,9 +2756,6 @@ ValueFactory attempted to access the Value property of this instance. - - The spinCount argument must be in the range 0 to {0}, inclusive. - There are too many threads currently waiting on the event. A maximum of {0} waiting threads are supported. diff --git a/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs b/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs index b2c7b20887846..f8e965bf4ed82 100644 --- a/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs @@ -667,7 +667,7 @@ public static string ToString(byte[] value, int startIndex, int length) } // (int.MaxValue / 3) == 715,827,882 Bytes == 699 MB - ArgumentOutOfRangeException.ThrowIfGreaterThan(length, (int.MaxValue / 3)); + ArgumentOutOfRangeException.ThrowIfGreaterThan(length, int.MaxValue / 3); return string.Create(length * 3 - 1, (value, startIndex, length), static (dst, state) => { diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/ConfigurableArrayPool.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/ConfigurableArrayPool.cs index 2188fc38dbb9f..13fa4a8d18835 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/ConfigurableArrayPool.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/ConfigurableArrayPool.cs @@ -21,14 +21,8 @@ internal ConfigurableArrayPool() : this(DefaultMaxArrayLength, DefaultMaxNumberO internal ConfigurableArrayPool(int maxArrayLength, int maxArraysPerBucket) { - if (maxArrayLength <= 0) - { - throw new ArgumentOutOfRangeException(nameof(maxArrayLength)); - } - if (maxArraysPerBucket <= 0) - { - throw new ArgumentOutOfRangeException(nameof(maxArraysPerBucket)); - } + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(maxArrayLength); + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(maxArraysPerBucket); // Our bucketing algorithm has a min length of 2^4 and a max length of 2^30. // Constrain the actual max used to those values. @@ -61,11 +55,8 @@ public override T[] Rent(int minimumLength) // Arrays can't be smaller than zero. We allow requesting zero-length arrays (even though // pooling such an array isn't valuable) as it's a valid length array, and we want the pool // to be usable in general instead of using `new`, even for computed lengths. - if (minimumLength < 0) - { - throw new ArgumentOutOfRangeException(nameof(minimumLength)); - } - else if (minimumLength == 0) + ArgumentOutOfRangeException.ThrowIfNegative(minimumLength); + if (minimumLength == 0) { // No need for events with the empty array. Our pool is effectively infinite // and we'll never allocate for rents and never store for returns. diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs index bffa23fc67963..fb6fccfa6df15 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs @@ -105,9 +105,9 @@ public override T[] Rent(int minimumLength) // effectively infinite for empty arrays and we'll never allocate for rents and never store for returns. return Array.Empty(); } - else if (minimumLength < 0) + else { - throw new ArgumentOutOfRangeException(nameof(minimumLength)); + ArgumentOutOfRangeException.ThrowIfNegative(minimumLength); } buffer = GC.AllocateUninitializedArray(minimumLength); diff --git a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs index eb3916ee12a09..11c566195daf8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs +++ b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs @@ -1700,7 +1700,10 @@ public long ToFileTimeUtc() } ticks -= FileTimeOffset; - ArgumentOutOfRangeException.ThrowIfNegative(ticks, null); + if (ticks < 0) + { + throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_FileTimeInvalid); + } return ticks; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipe.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipe.cs index 80f523f4ebc58..74acfef13fccf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipe.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipe.cs @@ -47,14 +47,8 @@ internal EventPipeProviderConfiguration( uint loggingLevel, string? filterData) { - if (string.IsNullOrEmpty(providerName)) - { - throw new ArgumentNullException(nameof(providerName)); - } - if (loggingLevel > 5) // 5 == Verbose, the highest value in EventPipeLoggingLevel. - { - throw new ArgumentOutOfRangeException(nameof(loggingLevel)); - } + ArgumentException.ThrowIfNullOrEmpty(providerName); + ArgumentOutOfRangeException.ThrowIfGreaterThan(loggingLevel, 5u); // 5 == Verbose, the highest value in EventPipeLoggingLevel. m_providerName = providerName; m_keywords = keywords; m_loggingLevel = loggingLevel; diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs index d0738641a3e2e..82ccbde6cdad4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix4x4.cs @@ -885,14 +885,9 @@ public static Matrix4x4 CreateOrthographicOffCenter(float left, float right, flo /// is greater than or equal to . public static Matrix4x4 CreatePerspective(float width, float height, float nearPlaneDistance, float farPlaneDistance) { - if (nearPlaneDistance <= 0.0f) - throw new ArgumentOutOfRangeException(nameof(nearPlaneDistance)); - - if (farPlaneDistance <= 0.0f) - throw new ArgumentOutOfRangeException(nameof(farPlaneDistance)); - - if (nearPlaneDistance >= farPlaneDistance) - throw new ArgumentOutOfRangeException(nameof(nearPlaneDistance)); + ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(nearPlaneDistance, 0.0f); + ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(farPlaneDistance, 0.0f); + ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(nearPlaneDistance, farPlaneDistance); Matrix4x4 result; @@ -929,17 +924,12 @@ public static Matrix4x4 CreatePerspective(float width, float height, float nearP /// is greater than or equal to . public static Matrix4x4 CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance) { - if (fieldOfView <= 0.0f || fieldOfView >= MathF.PI) - throw new ArgumentOutOfRangeException(nameof(fieldOfView)); - - if (nearPlaneDistance <= 0.0f) - throw new ArgumentOutOfRangeException(nameof(nearPlaneDistance)); + ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(fieldOfView, 0.0f); + ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(fieldOfView, MathF.PI); - if (farPlaneDistance <= 0.0f) - throw new ArgumentOutOfRangeException(nameof(farPlaneDistance)); - - if (nearPlaneDistance >= farPlaneDistance) - throw new ArgumentOutOfRangeException(nameof(nearPlaneDistance)); + ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(nearPlaneDistance, 0.0f); + ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(farPlaneDistance, 0.0f); + ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(nearPlaneDistance, farPlaneDistance); float yScale = 1.0f / MathF.Tan(fieldOfView * 0.5f); float xScale = yScale / aspectRatio; @@ -978,14 +968,9 @@ public static Matrix4x4 CreatePerspectiveFieldOfView(float fieldOfView, float as /// is greater than or equal to . public static Matrix4x4 CreatePerspectiveOffCenter(float left, float right, float bottom, float top, float nearPlaneDistance, float farPlaneDistance) { - if (nearPlaneDistance <= 0.0f) - throw new ArgumentOutOfRangeException(nameof(nearPlaneDistance)); - - if (farPlaneDistance <= 0.0f) - throw new ArgumentOutOfRangeException(nameof(farPlaneDistance)); - - if (nearPlaneDistance >= farPlaneDistance) - throw new ArgumentOutOfRangeException(nameof(nearPlaneDistance)); + ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(nearPlaneDistance, 0.0f); + ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(farPlaneDistance, 0.0f); + ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(nearPlaneDistance, farPlaneDistance); Matrix4x4 result; diff --git a/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs b/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs index 8c23b22164864..8522fd72c411f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs @@ -569,7 +569,6 @@ public static string Join(string? separator, string?[] value, int startIndex, in private static string JoinCore(ReadOnlySpan separator, string?[] value, int startIndex, int count) { ArgumentNullException.ThrowIfNull(value); - ArgumentOutOfRangeException.ThrowIfNegative(startIndex); ArgumentOutOfRangeException.ThrowIfNegative(count); ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex, value.Length - count); diff --git a/src/libraries/System.Private.CoreLib/src/System/String.cs b/src/libraries/System.Private.CoreLib/src/System/String.cs index 113f343f04d2c..971f1bbbef9fa 100644 --- a/src/libraries/System.Private.CoreLib/src/System/String.cs +++ b/src/libraries/System.Private.CoreLib/src/System/String.cs @@ -85,11 +85,8 @@ private static string Ctor(char[]? value) private static string Ctor(char[] value, int startIndex, int length) { ArgumentNullException.ThrowIfNull(value); - ArgumentOutOfRangeException.ThrowIfNegative(startIndex); - ArgumentOutOfRangeException.ThrowIfNegative(length); - ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex, value.Length - length); if (length == 0) @@ -137,7 +134,6 @@ private static unsafe string Ctor(char* ptr) private static unsafe string Ctor(char* ptr, int startIndex, int length) { ArgumentOutOfRangeException.ThrowIfNegative(length); - ArgumentOutOfRangeException.ThrowIfNegative(startIndex); char* pStart = ptr + startIndex; @@ -186,7 +182,6 @@ private static unsafe string Ctor(sbyte* value) private static unsafe string Ctor(sbyte* value, int startIndex, int length) { ArgumentOutOfRangeException.ThrowIfNegative(startIndex); - ArgumentOutOfRangeException.ThrowIfNegative(length); if (value == null) @@ -244,7 +239,6 @@ private static unsafe string Ctor(sbyte* value, int startIndex, int length, Enco return new string(value, startIndex, length); ArgumentOutOfRangeException.ThrowIfNegative(length); - ArgumentOutOfRangeException.ThrowIfNegative(startIndex); if (value == null) @@ -390,8 +384,8 @@ public unsafe void CopyTo(int sourceIndex, char[] destination, int destinationIn ArgumentOutOfRangeException.ThrowIfNegative(count); ArgumentOutOfRangeException.ThrowIfNegative(sourceIndex); ArgumentOutOfRangeException.ThrowIfGreaterThan(count, Length - sourceIndex, nameof(sourceIndex)); - if (destinationIndex > destination.Length - count || destinationIndex < 0) - throw new ArgumentOutOfRangeException(nameof(destinationIndex), SR.ArgumentOutOfRange_IndexCount); + ArgumentOutOfRangeException.ThrowIfGreaterThan(destinationIndex, destination.Length - count); + ArgumentOutOfRangeException.ThrowIfNegative(destinationIndex); Buffer.Memmove( destination: ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(destination), destinationIndex), @@ -451,8 +445,8 @@ public char[] ToCharArray() public char[] ToCharArray(int startIndex, int length) { // Range check everything. - if (startIndex < 0 || startIndex > Length || startIndex > Length - length) - throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_IndexMustBeLessOrEqual); + ArgumentOutOfRangeException.ThrowIfGreaterThan((uint)startIndex, (uint)Length, nameof(startIndex)); + ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex, Length - length); if (length <= 0) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs index a3c4a722103ed..6cca9d2396711 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Encoding.cs @@ -129,10 +129,7 @@ protected Encoding() : this(0) protected Encoding(int codePage) { // Validate code page - if (codePage < 0) - { - throw new ArgumentOutOfRangeException(nameof(codePage)); - } + ArgumentOutOfRangeException.ThrowIfNegative(codePage); // Remember code page _codePage = codePage; @@ -147,10 +144,7 @@ protected Encoding(int codePage) protected Encoding(int codePage, EncoderFallback? encoderFallback, DecoderFallback? decoderFallback) { // Validate code page - if (codePage < 0) - { - throw new ArgumentOutOfRangeException(nameof(codePage)); - } + ArgumentOutOfRangeException.ThrowIfNegative(codePage); // Remember code page _codePage = codePage; @@ -556,16 +550,9 @@ public virtual int GetByteCount(string s) public int GetByteCount(string s, int index, int count) { ArgumentNullException.ThrowIfNull(s); - - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index), - SR.ArgumentOutOfRange_NeedNonNegNum); - if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count), - SR.ArgumentOutOfRange_NeedNonNegNum); - if (index > s.Length - count) - throw new ArgumentOutOfRangeException(nameof(index), - SR.ArgumentOutOfRange_IndexCount); + ArgumentOutOfRangeException.ThrowIfNegative(index); + ArgumentOutOfRangeException.ThrowIfNegative(count); + ArgumentOutOfRangeException.ThrowIfGreaterThan(index, s.Length - count); unsafe { @@ -584,10 +571,7 @@ public int GetByteCount(string s, int index, int count) public virtual unsafe int GetByteCount(char* chars, int count) { ArgumentNullException.ThrowIfNull(chars); - - if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count), - SR.ArgumentOutOfRange_NeedNonNegNum); + ArgumentOutOfRangeException.ThrowIfNegative(count); char[] arrChar = new ReadOnlySpan(chars, count).ToArray(); @@ -654,16 +638,9 @@ public virtual byte[] GetBytes(string s) public byte[] GetBytes(string s, int index, int count) { ArgumentNullException.ThrowIfNull(s); - - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index), - SR.ArgumentOutOfRange_NeedNonNegNum); - if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count), - SR.ArgumentOutOfRange_NeedNonNegNum); - if (index > s.Length - count) - throw new ArgumentOutOfRangeException(nameof(index), - SR.ArgumentOutOfRange_IndexCount); + ArgumentOutOfRangeException.ThrowIfNegative(index); + ArgumentOutOfRangeException.ThrowIfNegative(count); + ArgumentOutOfRangeException.ThrowIfGreaterThan(index, s.Length - count); unsafe { diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ManualResetEventSlim.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ManualResetEventSlim.cs index cdcfe33ee97ac..428f6ddc4b9b2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ManualResetEventSlim.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ManualResetEventSlim.cs @@ -173,17 +173,8 @@ public ManualResetEventSlim(bool initialState) /// 0 or greater than the maximum allowed value. public ManualResetEventSlim(bool initialState, int spinCount) { - if (spinCount < 0) - { - throw new ArgumentOutOfRangeException(nameof(spinCount)); - } - - if (spinCount > SpinCountState_MaxValue) - { - throw new ArgumentOutOfRangeException( - nameof(spinCount), - SR.Format(SR.ManualResetEventSlim_ctor_SpinCountOutOfRange, SpinCountState_MaxValue)); - } + ArgumentOutOfRangeException.ThrowIfNegative(spinCount); + ArgumentOutOfRangeException.ThrowIfGreaterThan(spinCount, SpinCountState_MaxValue); // We will suppress default spin because the user specified a count. Initialize(initialState, spinCount); @@ -482,10 +473,7 @@ public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken) ThrowIfDisposed(); cancellationToken.ThrowIfCancellationRequested(); // an early convenience check - if (millisecondsTimeout < -1) - { - throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout)); - } + ArgumentOutOfRangeException.ThrowIfLessThan(millisecondsTimeout, -1); if (!IsSet) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ReaderWriterLockSlim.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ReaderWriterLockSlim.cs index 016142ded2499..9f7e7caf5c1c8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ReaderWriterLockSlim.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ReaderWriterLockSlim.cs @@ -249,8 +249,7 @@ public TimeoutTracker(TimeSpan timeout) public TimeoutTracker(int millisecondsTimeout) { - if (millisecondsTimeout < -1) - throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout)); + ArgumentOutOfRangeException.ThrowIfLessThan(millisecondsTimeout, -1); _total = millisecondsTimeout; if (_total != -1 && _total != 0) _start = Environment.TickCount; diff --git a/src/libraries/System.Runtime/tests/System/ArgumentOutOfRangeExceptionTests.cs b/src/libraries/System.Runtime/tests/System/ArgumentOutOfRangeExceptionTests.cs index d8822b0457cc8..a9c364fc514b7 100644 --- a/src/libraries/System.Runtime/tests/System/ArgumentOutOfRangeExceptionTests.cs +++ b/src/libraries/System.Runtime/tests/System/ArgumentOutOfRangeExceptionTests.cs @@ -78,8 +78,6 @@ public static void Ctor_String_Object_String() [Fact] public static void GenericHelpers_ThrowIfZero_Throws() { - - AssertExtensions.Throws(HelpersParamName, ZeroHelper(0.0f)); AssertExtensions.Throws(HelpersParamName, ZeroHelper(0)); AssertExtensions.Throws(HelpersParamName, ZeroHelper(0)); @@ -94,7 +92,6 @@ public static void GenericHelpers_ThrowIfZero_Throws() public static void GenericHelpers_ThrowIfNegativeZero_Throws() { AssertExtensions.Throws(HelpersParamName, NegativeOrZeroHelper(-1)); - AssertExtensions.Throws(HelpersParamName, NegativeOrZeroHelper(-0.0f)); AssertExtensions.Throws(HelpersParamName, NegativeOrZeroHelper(-0.0)); }