Skip to content

Consider existence of EETypes and metadata for typeof checks#107347

Merged
MichalStrehovsky merged 6 commits intodotnet:mainfrom
MichalStrehovsky:fix107300
Sep 10, 2024
Merged

Consider existence of EETypes and metadata for typeof checks#107347
MichalStrehovsky merged 6 commits intodotnet:mainfrom
MichalStrehovsky:fix107300

Conversation

@MichalStrehovsky
Copy link
Copy Markdown
Member

@MichalStrehovsky MichalStrehovsky commented Sep 4, 2024

Fixes #107300.

The problem was that when we optimize typeof(Foo) == somevalue checks, we were looking at the presence of a constructed MethodTable of Foo in the whole program view. If it didn't exist, we'd declare the equality comparison can't succeed. There is however an edge case where someone could obtain a System.Type representing a type by browsing the reflection metadata. Such System.Type might not have a workable constructed MethodTable, but should still compare equal to the typeof.

An example of when this could happen is when the type is used in a custom attribute metadata blob - such type may even have no MethodTable at all.

The fix is to look not just at MethodTable but also at the metadata for the type.

Cc @dotnet/ilc-contrib

@MichalStrehovsky
Copy link
Copy Markdown
Member Author

/azp run runtime-nativeaot-outerloop

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@MichalStrehovsky MichalStrehovsky marked this pull request as ready for review September 5, 2024 11:23
Copy link
Copy Markdown
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.

The PR title describes an older approach right?

// This will likely remain true because anyone can call Object.GetType on a constructed type.
// If the type cannot generate metadata, we only condition on the MethodTable itself.
if (!_factory.MetadataManager.IsReflectionBlocked(typeEqualityCheckType)
&& typeEqualityCheckType.GetTypeDefinition() is MetadataType typeEqualityCheckMetadataType)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why is this condition different than the CanGenerateMetadata check above?

If having a constructed MethodTable implies having metadata, could the check in SubstitutedILProvider only look for metadata, instead of looking for both the constructed MethodTabla and metadata?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The reflection-free mode wouldn't have any metadata because we never generate any there. In that case, the comparison will only succeed if there's a MethodTable.

When scanning, we're not sure what generates and what doesn't generate metadata yet, so we check IsReflectionBlocked (would never generate metadata). In the scanning phase, it's equivalent to CanGenerateMetadata. Could have used that too, but this is more explicit.

@MichalStrehovsky MichalStrehovsky changed the title Consider necessary EETypes with metadata constructed Consider existence of EETypes and metadata for typeof checks Sep 9, 2024
@MichalStrehovsky
Copy link
Copy Markdown
Member Author

/azp run runtime-nativeaot-outerloop

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@MichalStrehovsky MichalStrehovsky merged commit a817006 into dotnet:main Sep 10, 2024
@MichalStrehovsky MichalStrehovsky deleted the fix107300 branch September 10, 2024 07:22
@MichalStrehovsky
Copy link
Copy Markdown
Member Author

/backport to release/9.0

@github-actions
Copy link
Copy Markdown
Contributor

Started backporting to release/9.0: https://github.com/dotnet/runtime/actions/runs/10787848434

jtschuster pushed a commit to jtschuster/runtime that referenced this pull request Sep 17, 2024
…107347)

The problem was that when we optimize `typeof(Foo) == somevalue` checks, we were looking at the presence of a constructed `MethodTable` of `Foo` in the whole program view. If it didn't exist, we'd declare the equality comparison can't succeed. There is however an edge case where someone could obtain a `System.Type` representing a type by browsing the reflection metadata. Such `System.Type` might not have a workable constructed `MethodTable`, but should still compare equal to the `typeof`.

An example of when this could happen is when the type is used in a custom attribute metadata blob - such type may even have no `MethodTable` at all.

The fix is to look not just at `MethodTable` but also at the metadata for the type.
sirntar pushed a commit to sirntar/runtime that referenced this pull request Sep 30, 2024
…107347)

The problem was that when we optimize `typeof(Foo) == somevalue` checks, we were looking at the presence of a constructed `MethodTable` of `Foo` in the whole program view. If it didn't exist, we'd declare the equality comparison can't succeed. There is however an edge case where someone could obtain a `System.Type` representing a type by browsing the reflection metadata. Such `System.Type` might not have a workable constructed `MethodTable`, but should still compare equal to the `typeof`.

An example of when this could happen is when the type is used in a custom attribute metadata blob - such type may even have no `MethodTable` at all.

The fix is to look not just at `MethodTable` but also at the metadata for the type.
@github-actions github-actions bot locked and limited conversation to collaborators Oct 10, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[NativeAOT] NativeAOT .NET 9 preview 7 apps hang due to generating infinite loops for certain typeof comparisons

2 participants