dotnet/runtime

[Analyzer] Adjust/simplify code for numeric IntPtr

Open

#74,518 opened on Aug 24, 2022

View on GitHub
 (6 comments) (1 reaction) (0 assignees)C# (5,445 forks)batch import
api-approvedarea-Metacode-analyzercode-fixerhelp wanted

Repository metrics

Stars
 (17,886 stars)
PR merge metrics
 (Avg merge 12d 11h) (661 merged PRs in 30d)

Description

Related to https://github.com/dotnet/runtime/issues/72348

With numeric IntPtr feature code simplification opportunities now available that could be suggested by this analyzer

  • U?IntPtr.Zero0 or nu?int.Zero if it would introduce ambiguity
  // Flag:
  IntPtr intPtr = IntPtr.Zero;      // or nint intPtr1 = IntPtr.Zero;
  UIntPtr uintPtr1 = UIntPtr.Zero;  // nuint uintPtr1 = UIntPtr.Zero; 

  // Violations fixed
  nint intPtr1 = 0; // or void* intPtr1 = null; if it needs to be pointer
  nuint uintPtr1 = 0;
  • new U?IntPtr(x)x or (nu?int)x if it would introduce ambiguity, or unchecked((nu?int)x) if we are in a checked context.
  // Flag:
  IntPtr intPtr1 = new IntPtr(x);
  uintPtr1 = new UIntPtr(x);

  // Fixed
  nint intPtr1 = x; 
  uintPtr1 = (nuint)x;
  • x.ToU?Int32()checked((u?int)x) or (u?int)x if we are in a checked context
  // Flag:
  int i = intPtr1.ToInt32();
  uint ui = uintPtr1.ToUInt32();

  // Fixed
  int i = (int)intPtr1;
  uint ui = (uint)uintPtr1;
  • x.ToU?Int64()(u?long)x
  // Flag:
  long longValue = intPtr1.ToInt64();
  ulong uLongValue = uintPtr1.ToUInt64();

  // Fixed
  long longValue = (long)intPtr1;
  ulong uLongValue = (ulong)uintPtr1;
  • x.ToPointer()(void*) x
  // Flag:
  void* ptr1 = intPtr1.ToPointer();
  void* ptr2 = uintPtr1.ToPointer();

  // Fixed
  void* ptr1 = (void*)intPtr1;
  void* ptr2 = (void*)uintPtr1; 

Suggested severity : "Info" Suggested category : "Style" or "Usage"

This analyzer should be triggered only if the underlying runtime supports numeric IntPtr feature, i.e. if System.Runtime.CompilerServices.RuntimeFeature.NumericIntPtr is available in corelib.

Other related questions:

  • In case the statement includes a variable declaration with U?IntPt, the type also could be converted to nu?int which also could be covered by IDE0049 should be updated to suggest converting IntPtr to nint and UIntPtr to nuint, so these scenarios might also could be added to that issue to fix all references with appropriate values.
  • Also, as @jkotas suggested it would be nice for the code-fixer to suggest replacing IntPtr with actual pointer types where the code is actually operating on pointers. It might be not easy to determine if actual pointer should be suggested instead of nu?int

CC @tannergooding @jeffhandley

Contributor guide