Skip to content

Parse custom attribute value blobs for dependencies and rewrite type name strings#127596

Merged
MichalStrehovsky merged 28 commits into
mainfrom
copilot/fix-custom-attribute-todos
May 18, 2026
Merged

Parse custom attribute value blobs for dependencies and rewrite type name strings#127596
MichalStrehovsky merged 28 commits into
mainfrom
copilot/fix-custom-attribute-todos

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 30, 2026

Description

CustomAttributeNode had two TODOs: it wasn't parsing the custom attribute value blob for dependencies, and it wasn't rewriting type name strings that could become stale after trimming removes type forwarders.

Dependency analysis (GetStaticDependencies)

Decodes the custom attribute blob via CustomAttributeTypeProvider and reports dependencies for:

  • typeof() arguments
  • Enum types (needed for boxing)
  • Property setters and fields referenced in named arguments
  • Non-primitive array element types

Constructor resolution uses TryGetMethod instead of try/catch, with a null constructor triggering an early return before named argument processing. GetDependenciesFromPropertySetter uses GetTypeDefinition() to correctly resolve property setters on generic attribute types. Dependency decode failures set an instance _isCorrupted flag so rewrite can avoid re-processing known-bad blobs.

Blob rewriting (WriteInternal)

RewriteCustomAttributeBlob reads the custom attribute blob manually with BlobReader, writes into writeContext.GetSharedBlobBuilder(), and rewrites only serialized type-name strings where needed (System.Type payloads and enum type names). Type-name resolution uses GetTypeByCustomAttributeTypeName(..., throwIfNotFound: false) and rewrites only when resolution succeeds, preserving unresolved serialized type names as-is.

Rewrite early-outs to copying the original blob when _isCorrupted is set or when the constructor cannot be resolved.

Type safety improvements

NodeFactory.ReflectedType, ReflectedMethod, and ReflectedField now return DependencyNode directly instead of object, since all return paths produce a DependencyNode (either a real definition node or NullDependencyNode.Instance). This removes the need for is DependencyNode pattern checks at all call sites. Similarly, the value is ImmutableArray<CustomAttributeTypedArgument<TypeDesc>> pattern check in GetDependenciesFromCustomAttributeArgument has been replaced with a hard cast, relying on the System.Reflection.Metadata contract that DecodeValue always produces ImmutableArray<...> for SzArray-typed arguments (the value is null case is already handled earlier).

Validation

  • dotnet build src/coreclr/tools/ILTrim.Core/ILTrim.Core.csproj
  • dotnet test src/coreclr/tools/ILTrim.Tests/ILTrim.Tests.csproj --filter "FullyQualifiedName~AttributesTests"
  • parallel_validation (Code Review + CodeQL)

Copilot AI and others added 2 commits April 30, 2026 04:17
…ame strings

Implement custom attribute blob parsing in CustomAttributeNode:
1. GetStaticDependencies now decodes the custom attribute value blob and
   reports dependencies for typeof() arguments, enum types, property
   setters, and fields referenced in the blob.
2. WriteInternal now re-encodes the blob with type name strings resolved
   to their definitions, handling cases where trimming drops type
   forwarders (e.g. re-encoding "System.Object, System.Runtime" to
   "System.Object, System.Private.CoreLib").

Remove 24 tests from ILTrimExpectedFailures.txt that now pass.

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/f4173cc7-fd45-4a62-9a1c-1a31c06cc85b

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
… remove unused parameter

- Catch TypeSystemException and BadImageFormatException instead of base Exception
- Add DependencyNode type alias to reduce verbose fully-qualified type names
- Remove unused isFixedArg parameter from WriteArgumentValue
- Hoist constructor resolution out of named argument loop
- Fix duplicate CustomAttributeTypeNameFormatter allocations

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/f4173cc7-fd45-4a62-9a1c-1a31c06cc85b

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

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

… BlobBuilder

Use BlobEncoder.CustomAttributeSignature with FixedArgumentsEncoder and
CustomAttributeNamedArgumentsEncoder instead of manual byte writing.
Use writeContext.GetSharedBlobBuilder() following established patterns.
Removed byte[] materialization - writes directly to shared BlobBuilder.

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/d078b767-9d76-41e5-9168-8f6651786108

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot April 30, 2026 09:04
Copilot AI requested a review from MichalStrehovsky April 30, 2026 09:05
…bute blobs

Remove CheckArgumentsForRewrite/CheckArgumentValueForRewrite that skipped
rewriting when no typeof() references were found. Always rewrite to exercise
the encoding logic and surface bugs.

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/46e2e54d-5313-4538-8274-c5cfe241e547

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
…pe.Category

- Replace early returns with cascading if/else if/else in EncodeNamedArgumentType,
  WriteLiteralValue, and WriteScalarValue.
- Switch on type.Category instead of type.UnderlyingType.Category in
  EncodeElementType, handling IsEnum and System.Type in the default case.

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/683a21bb-4e07-4219-81e8-b0a320967bd3

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 1, 2026 11:23
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/6129cc2c-9d66-4f42-876a-056fcef7f711

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Copy link
Copy Markdown
Member

@MichalStrehovsky MichalStrehovsky left a comment

Choose a reason for hiding this comment

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

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/20d7918c-7976-4a3d-882f-8aac8f4ade8b

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/f536fc71-012c-4ae8-b43e-0abb314fd4c0

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Copy link
Copy Markdown
Member

@MichalStrehovsky MichalStrehovsky left a comment

Choose a reason for hiding this comment

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

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/e2e5e7e2-e344-4277-b320-fb781514a11c

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Copy link
Copy Markdown
Member

@MichalStrehovsky MichalStrehovsky left a comment

Choose a reason for hiding this comment

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

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/47730547-daf1-4d8d-aa61-66dda42e8d3e

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Copy link
Copy Markdown
Member

@MichalStrehovsky MichalStrehovsky left a comment

Choose a reason for hiding this comment

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

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/6f52143b-ce97-4011-8d73-52d18ba9700c

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Co-authored-by: Michal Strehovský <MichalStrehovsky@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 13, 2026

@MichalStrehovsky I've opened a new pull request, #128122, to work on those changes. Once the pull request is ready, I'll request review from you.

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.

I wonder whether some of the is checks throughout this code should fail fast instead? Seems like hard casts could catch future holes if we don't expect these checks to fail. Otherwise LGTM!

Copy link
Copy Markdown
Member

@MichalStrehovsky MichalStrehovsky left a comment

Choose a reason for hiding this comment

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

Copilot AI and others added 2 commits May 16, 2026 03:34
… hard casts instead of is-checks

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/bba68476-9f61-4c82-9f8b-156ddb87c9ba

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/bba68476-9f61-4c82-9f8b-156ddb87c9ba

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-Tools-ILLink .NET linker development as well as trimming analyzers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants