From f5bf767c37dd316c2ecb2c7318d041b34c38ab13 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Mon, 4 Aug 2025 14:02:00 +0100 Subject: [PATCH] Use `nint` for native-sized integers in `Interlocked` * Fix CA2020: Prevent behavioral change --- .../src/System/Threading/Interlocked.cs | 48 +++++++++---------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs index 3f74b53818ffcb..81b47297b83e1e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs @@ -192,25 +192,23 @@ public static float Exchange(ref float location1, float value) public static double Exchange(ref double location1, double value) => Unsafe.BitCast(Exchange(ref Unsafe.As(ref location1), Unsafe.BitCast(value))); - /// Sets a platform-specific handle or pointer to a specified value and returns the original value, as an atomic operation. + /// Sets a native-sized signed integer to a specified value and returns the original value, as an atomic operation. /// The variable to set to the specified value. /// The value to which the parameter is set. /// The original value of . /// The address of location1 is a null pointer. [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IntPtr Exchange(ref IntPtr location1, IntPtr value) + public static nint Exchange(ref nint location1, nint value) { -#pragma warning disable CA2020 // Prevent from behavioral change #if TARGET_64BIT - return (IntPtr)Interlocked.Exchange(ref Unsafe.As(ref location1), (long)value); + return (nint)Exchange(ref Unsafe.As(ref location1), (long)value); #else - return (IntPtr)Exchange(ref Unsafe.As(ref location1), (int)value); + return (nint)Exchange(ref Unsafe.As(ref location1), (int)value); #endif -#pragma warning restore CA2020 } - /// Sets a platform-specific handle or pointer to a specified value and returns the original value, as an atomic operation. + /// Sets a native-sized unsigned integer to a specified value and returns the original value, as an atomic operation. /// The variable to set to the specified value. /// The value to which the parameter is set. /// The original value of . @@ -218,12 +216,12 @@ public static IntPtr Exchange(ref IntPtr location1, IntPtr value) [Intrinsic] [CLSCompliant(false)] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UIntPtr Exchange(ref UIntPtr location1, UIntPtr value) + public static nuint Exchange(ref nuint location1, nuint value) { #if TARGET_64BIT - return (UIntPtr)Interlocked.Exchange(ref Unsafe.As(ref location1), (long)value); + return (nuint)Exchange(ref Unsafe.As(ref location1), (long)value); #else - return (UIntPtr)Exchange(ref Unsafe.As(ref location1), (int)value); + return (nuint)Exchange(ref Unsafe.As(ref location1), (int)value); #endif } @@ -441,40 +439,38 @@ public static float CompareExchange(ref float location1, float value, float comp public static double CompareExchange(ref double location1, double value, double comparand) => Unsafe.BitCast(CompareExchange(ref Unsafe.As(ref location1), Unsafe.BitCast(value), Unsafe.BitCast(comparand))); - /// Compares two platform-specific handles or pointers for equality and, if they are equal, replaces the first one. - /// The destination , whose value is compared with the value of and possibly replaced by . - /// The that replaces the destination value if the comparison results in equality. - /// The that is compared to the value at . + /// Compares two native-sized signed integers for equality and, if they are equal, replaces the first one. + /// The destination, whose value is compared with the value of and possibly replaced by . + /// The value that replaces the destination value if the comparison results in equality. + /// The value that is compared to the value at . /// The original value in . /// The address of is a null pointer. [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IntPtr CompareExchange(ref IntPtr location1, IntPtr value, IntPtr comparand) + public static nint CompareExchange(ref nint location1, nint value, nint comparand) { -#pragma warning disable CA2020 // Prevent from behavioral change #if TARGET_64BIT - return (IntPtr)Interlocked.CompareExchange(ref Unsafe.As(ref location1), (long)value, (long)comparand); + return (nint)CompareExchange(ref Unsafe.As(ref location1), (long)value, (long)comparand); #else - return (IntPtr)CompareExchange(ref Unsafe.As(ref location1), (int)value, (int)comparand); + return (nint)CompareExchange(ref Unsafe.As(ref location1), (int)value, (int)comparand); #endif -#pragma warning restore CA2020 } - /// Compares two platform-specific handles or pointers for equality and, if they are equal, replaces the first one. - /// The destination , whose value is compared with the value of and possibly replaced by . - /// The that replaces the destination value if the comparison results in equality. - /// The that is compared to the value at . + /// Compares two native-sized unsigned integers for equality and, if they are equal, replaces the first one. + /// The destination, whose value is compared with the value of and possibly replaced by . + /// The value that replaces the destination value if the comparison results in equality. + /// The value that is compared to the value at . /// The original value in . /// The address of is a null pointer. [Intrinsic] [CLSCompliant(false)] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UIntPtr CompareExchange(ref UIntPtr location1, UIntPtr value, UIntPtr comparand) + public static nuint CompareExchange(ref nuint location1, nuint value, nuint comparand) { #if TARGET_64BIT - return (UIntPtr)Interlocked.CompareExchange(ref Unsafe.As(ref location1), (long)value, (long)comparand); + return (nuint)CompareExchange(ref Unsafe.As(ref location1), (long)value, (long)comparand); #else - return (UIntPtr)CompareExchange(ref Unsafe.As(ref location1), (int)value, (int)comparand); + return (nuint)CompareExchange(ref Unsafe.As(ref location1), (int)value, (int)comparand); #endif }