Skip to content
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

[CoreCLR] Implement support for UnsafeAccessorAttribute #86161

Closed
6 tasks done
AaronRobinsonMSFT opened this issue May 12, 2023 · 6 comments
Closed
6 tasks done

[CoreCLR] Implement support for UnsafeAccessorAttribute #86161

AaronRobinsonMSFT opened this issue May 12, 2023 · 6 comments
Milestone

Comments

@AaronRobinsonMSFT
Copy link
Member

AaronRobinsonMSFT commented May 12, 2023

Implement #81741 for CoreCLR.

See Mono work item - #86040
See NativeAOT work item - #86438

@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label May 12, 2023
@ghost ghost added the untriaged New issue has not been triaged by the area owner label May 12, 2023
@AaronRobinsonMSFT AaronRobinsonMSFT added area-VM-coreclr and removed untriaged New issue has not been triaged by the area owner needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels May 12, 2023
@AaronRobinsonMSFT AaronRobinsonMSFT added this to the 8.0.0 milestone May 12, 2023
@AaronRobinsonMSFT AaronRobinsonMSFT changed the title [CoreCLR] Implement support for UnsafeAccesorAttribute [CoreCLR] Implement support for UnsafeAccessorAttribute May 15, 2023
@vitek-karas
Copy link
Member

@AaronRobinsonMSFT do you want us to create a separate issue for NativeAOT support, or do you want to track that here as well?

Similar for crossgen - not sure if it needs to do anything, but at the very least it needs testing.

@AaronRobinsonMSFT
Copy link
Member Author

AaronRobinsonMSFT commented May 18, 2023

do you want us to create a separate issue for NativeAOT support, or do you want to track that here as well?

Possibly? I haven't thought too much about the needs in NativeAOT. My assumption is the compiler should be able to peer through at codegen time and emit the code. However, I suppose the stub needs to be generated. Hmmm yeah, a new issue is probably helpful for tracking at least.

@MichalStrehovsky
Copy link
Member

NativeAOT work is probably the same as crossgen work if we want this for crossgen. Some thought for crossgen is needed because R2R only guarantees same versionability as the source IL and accessing privates goes beyond what we consider binary breaks for IL.

@MichalStrehovsky
Copy link
Member

Oh I take that back, it's likely not possible in crossgen now because crossgen doesn't (AFAIK) have a way to manufacture new tokens and we'd likely need new ones for this

vitek-karas added a commit that referenced this issue Jul 18, 2023
The core of the change is that `UnsafeAccessor` creates a code dependency from the accessor method to the target specified by the attribute. The trimmer needs to follow this dependency and preserve the target. Additionally, because the trimmer operates at the IL level, it needs to make sure that the target will keep its name and some other properties intact (so that the runtime implementation of the `UnsafeAccessor` can still work).

Implementation choices:
* The trimmer will mark the target as "accessed via reflection", this is a simple way to make sure that name and other properties about the target are preserved. This could be optimized in the future, but the savings are probably not that interesting.
* The implementation ran into a problem when trying to precisely match the signature overload resolution. Due to Cecil issues and the fact that Cecil's resolution algorithm is not extensible, it was not possible to match the runtime's behavior without adding lot more complexity (currently it seems we would have to reimplement method resolution in the trimmer). So, to simplify the implementation, trimmer will mark all methods of a given name. This means it will mark more than necessary. This is fixable by adding more complexity to the code base if we think there's a good reason for it.
* Due to the above choices, there are some behavioral differences:
  * Trimmer will warn if the target has data flow annotations, always. There's no way to "fix" this in the code without a suppression.
  * Trimmer will produce different warning codes even if there is a true data flow mismatch - this is because it treats the access as "reflection access" which produces different warning codes from direct access.
  * These differences are fixable, but it was not deemed necessary right now.
* We decided that analyzer will not react to the attribute at all, and thus will not produce any diagnostics around it.

The guiding reason to keep the implementation simple is that we don't expect the unsafe accessor to be used by developers directly, instead we assume that vast majority of its usages will be from source generators. So, developer UX is not as important.

Test changes:
* Adds directed tests for the marking behavior
* Adds tests to verify that `Requires*` attributes behave correctly
* Adds tests to verify that data flow annotations behave as expected (described above)
* The tests are effectively a second validation of the NativeAOT implementation as they cover NativeAOT as well.

Fixes in CoreCLR/NativeAOT:
This change fixes one bug in the CoreCLR/NativeAOT implementation, unsafe accessor on a instance method of a value type must use "by-ref" parameter for the `this` parameter. Without the "by-ref" the accessor is considered invalid and will throw.
This change also adds some tests to the CoreCLR/NativeAOT test suite.

Part of #86161.
Related to #86438.
Feature design in #81741.
@jkotas
Copy link
Member

jkotas commented Jul 25, 2023

Open a new tracking issue for the generics support and close this one as completed?

@AaronRobinsonMSFT
Copy link
Member Author

Open a new tracking issue for the generics support and close this one as completed?

Yep, that was the plan. Someone is pushing on this earlier than anticipated ;-)

@ghost ghost locked as resolved and limited conversation to collaborators Aug 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants