-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Address warnings for possibly null array elements #41046
Conversation
while (Unsafe.IsAddressLessThan(ref leftRef, ref nextToLastRef) && (leftRef = ref Unsafe.Add(ref leftRef, 1)) == null) ; | ||
while (Unsafe.IsAddressGreaterThan(ref rightRef, ref zeroRef) && (rightRef = ref Unsafe.Add(ref rightRef, -1)) == null) ; | ||
while (Unsafe.IsAddressLessThan(ref leftRef!, ref nextToLastRef) && (leftRef = ref Unsafe.Add(ref leftRef, 1)) == null) ; | ||
while (Unsafe.IsAddressGreaterThan(ref rightRef!, ref zeroRef) && (rightRef = ref Unsafe.Add(ref rightRef, -1)) == null) ; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not understanding why the compiler flags this. Why does the compiler think these methods could assign null to the ref?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe the warning is for the value of ref
argument when the method is called. On the second time through the loop, leftRef
is assumed to be null
based on && (leftRef = ...) == null
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Is the right fix here then to actually annotate both arguments with [AllowNull]? (That would apply to all members of Unsafe that accept multiple ref Ts and only care about the address, not the actual value, e.g. AreSame, ByteOffset, IsAddressGreaterThan, IsAddressLessThan, and in both the public Unsafe.cs ref as well as the internal implementation in corelib.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the right fix here then to actually annotate both arguments with [AllowNull]?
The methods in Unsafe
simply take an unconstrained T
which seems like it should be sufficient for all callers. Should the leftRef
, etc. locals be declared as ref T?
here instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the
leftRef
, etc. locals be declared asref T?
here instead?
Perhaps not. That would just move the warnings to the initializers of those locals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the leftRef, etc. locals be declared as ref T? here instead?
Wouldn't that be a problem if a T t;
were passed in, with the compiler then complaining that the implementation might assign null to it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the leftRef, etc. locals be declared as ref T? here instead?
Perhaps not. That would just move the warnings to the initializers of those locals.
Right, hence my question about [AllowNull]. Does that make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is similar to the Volatile.Read
APIs, where ideally we could change ref T
to in T
, but that would be a breaking API change.
Thanks, @cston. Once this goes in, it should be ported to release/5.0 to unblock updating the compiler there as well. Thanks! |
Yes, adding |
/backport to release/5.0 |
Started backporting to release/5.0: https://github.com/dotnet/runtime/actions/runs/217132032 |
As of dotnet/roslyn#46405, the C# compiler considers constraint types for conversions involving type parameter types.
A warning is reported for the following for instance:
This results in several new warnings building dotnet/runtime (see dotnet/roslyn#46577).