Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Implement checking for Requires* on attributes for NativeAOT #83550

Merged
merged 3 commits into from
Mar 27, 2023

Conversation

vitek-karas
Copy link
Member

Any of the RUC/RDC/RAF attributes can be added to an attribute (either the type or the .ctor or properties). The compiler needs to check for these and produce warnings if such attribute is instantiated somewhere.

This was added to "Dataflow" existing class, while it's not exactly data flow, adding a new abstraction didn't seem worth it.

Also does a simple dedupe of RUC/RDC/RAF checks in some places.

Adapt the tests to the new behavior. The most notable change is that NativeAOT will only look at attributes for reflection enabled members, so had to modify the tests to reflection access basically everything.

Contributes to #82447

Any of the RUC/RDC/RAF attributes can be added to an attribute (either the type or the .ctor or properties). The compiler needs to check for these and produce warnings if such attribute is instantiated somewhere.

This was added to "Dataflow" existing class, while it's not exactly data flow, adding a new abstraction didn't seem worth it.

Also does a simple dedupe of RUC/RDC/RAF checks in some places.

Adapt the tests to the new behavior. The most notable change is that NativeAOT will only look at attributes for reflection enabled members, so had to modify the tests to reflection access basically everything.
@ghost
Copy link

ghost commented Mar 16, 2023

Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas
See info in area-owners.md if you want to be subscribed.

Issue Details

Any of the RUC/RDC/RAF attributes can be added to an attribute (either the type or the .ctor or properties). The compiler needs to check for these and produce warnings if such attribute is instantiated somewhere.

This was added to "Dataflow" existing class, while it's not exactly data flow, adding a new abstraction didn't seem worth it.

Also does a simple dedupe of RUC/RDC/RAF checks in some places.

Adapt the tests to the new behavior. The most notable change is that NativeAOT will only look at attributes for reflection enabled members, so had to modify the tests to reflection access basically everything.

Contributes to #82447

Author: vitek-karas
Assignees: vitek-karas
Labels:

area-NativeAOT-coreclr

Milestone: 8.0.0

// Accessing the members to test via direct calls/access is not enough
// in NativeAOT custom attributes are only looked at if the member is
// reflection enabled - so there has to be a reflection access to it somewhere.
// On the other hand the analyzer reports RDC/RAF only on direct access. So we need to have "both"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume that we ideally want linker/analyzer not to warn on direct access either - is that right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This goes to the larger discussion on how should linker treat attributes. Currently we're very conservative in that we keep all instantiations pretty much everywhere. NativeAOT is also conservative, but less so, it will keep all attributes but only on reflectable entities.

I do agree that it would make sense to change linker to behave more like NativeAOT - which is aligned with the long term goal of linker optimizing non-reflectable entities more. Currently we only remove parameter names for non-reflectable methods, we already have issues and ides for example to remove field names for non-reflectable fields and so on. Removing attributes on these would also fall into that bucket.

Ideally we would be able to remove unused attributes, which means the same behavior as NativeAOT, but also only keep attributes which are actually asked for. But that is pretty hard to track correctly - basically GetCustomAttributes API would have to be RUC and intrinsic. That would probably break lot of things.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It occurs to me also that warning only on attributes on members accessed via reflection introduces a weird kind of non-local behavior. If unrelated code starts reflecting on a method which has such an attribute, that method starts giving a warning without any indication of what caused the change. Normally cases like this would warn on the reflection access site. So maybe there are advantages to the linker/analyzer behavior.

Use GetDisplayName for anything is supported by that extension method - this fixes wrong origin printed out for property/event (we would print out 'PropertyPseudoDescriptor').

Mapping IL offset to source file/line number - if the PDB specifies that line as "hidden", then don't use it, instead look for the begining of the method - so first non-hidden sequence point in the method's body.
This is a copy of the logic implemented in illink already.
@vitek-karas
Copy link
Member Author

I added fixes around warning location display - mainly because with this change some of it can now actually happen:

Use GetDisplayName for anything is supported by that extension method - this fixes wrong origin printed out for property/event (we would print out 'PropertyPseudoDescriptor').

Mapping IL offset to source file/line number - if the PDB specifies that line as "hidden", then don't use it, instead look for the begining of the method - so first non-hidden sequence point in the method's body.
This is a copy of the logic implemented in illink already.

@vitek-karas
Copy link
Member Author

@sbomer - Could you please take a look at the changes?

Copy link
Member

@sbomer sbomer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

}

// If the warning comes from hidden line (compiler generated code typically)
// search for any sequence point with non-hidden line number and report that as a best effort.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know all the cases where hidden line numbers might be emitted - but should this maybe find the last sequence point with non-hidden line number that still is <= ilOffset, if it exists, and the first subsequent sequence point with non-hidden line number, if not?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a way doing that can lead to more confusion. If the warning is in the compiler generated portion of the method, then "assigning" it to something "close by" is as wrong as assigning it to pretty much any other part of the method - mainly because we have no idea how the method is split between compiler generated and user code. So pointing to the method as a whole feels like a good compromise.

If we do find a case where this would improve experience I'm not against doing it, in all tools at once.

@vitek-karas vitek-karas merged commit 9b38f2a into dotnet:main Mar 27, 2023
@vitek-karas vitek-karas deleted the RequiresOnAttribute branch March 27, 2023 11:28
@ghost ghost locked as resolved and limited conversation to collaborators Apr 26, 2023
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants