Skip to content

Reduce CA1508 analysis cost for local-function calls - #56414

Merged
tannergooding merged 4 commits into
dotnet:mainfrom
tannergooding:tannergooding-issue-56412-investigation
Sep 29, 2026
Merged

tannergooding merged 4 commits into
dotnet:mainfrom
tannergooding:tannergooding-issue-56412-investigation

Conversation

@tannergooding

@tannergooding tannergooding commented Sep 27, 2026 •

Copy link
Copy Markdown
Member

Note

This pull request description was drafted with AI assistance.

Related to #56412.

Local-function calls were excluded from the existing interprocedural entry-state trimming, so each call cloned and reanalyzed unrelated caller state. Across many calls, that work could dominate analysis time.

Enable trimming for directly invoked local functions when their flow state is safe to analyze. Keep state reachable through captures, parameters, receiver, static state, and tracked aliases; conservatively use the full state when safety cannot be established. Distinguish trimmed call results so updates preserve tracked-state semantics, while full-state calls retain their existing replacement behavior. Memoize successfully scanned static-local bodies to avoid rescanning shared function graphs.

Also stop CA1508's enclosing-method candidate scan at nested functions, whose bodies have separate control-flow graphs. On a related 548-call reproducer, CA1508 analyzer time fell from 41.4 seconds to roughly 5–7 seconds.

Trim unrelated caller state for safe direct local-function calls and skip enclosing CA1508 analysis when only nested functions have candidates. Preserve reachable aliases and fall back to full state when indirect effects cannot be ruled out.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@tannergooding
tannergooding requested a review from a team as a code owner September 27, 2026 13:24
Copilot AI lite review requested due to automatic review settings September 27, 2026 13:24
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
2 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

One or more issues must be addressed before approval.

Review effort: Lite
Findings: 1 Low severity

Open (1)
What changed in this PR

Improves CA1508 performance by trimming local-function analysis state when safe, preserving required captures and aliases, and avoiding nested-function scans.

Changes:

  • Adds local-function state trimming and result-merging semantics.
  • Adds conservative capture, static-state, and alias analysis.
  • Expands regression coverage for value-content, null, and dispose analysis.
File Description
src/​Microsoft.CodeAnalysis.NetAnalyzers/​tests/​Microsoft.CodeAnalysis.NetAnalyzers.UnitTests/​Microsoft.NetCore.Analyzers/​Runtime/​DisposeObjectsBeforeLosingScopeTests.cs Updated as part of this pull request.
src/​Microsoft.CodeAnalysis.NetAnalyzers/​tests/​Microsoft.CodeAnalysis.NetAnalyzers.UnitTests/​Microsoft.CodeQuality.Analyzers/​Maintainability/​AvoidDeadConditionalCode_ValueContentAnalysis.cs Updated as part of this pull request.
src/​Microsoft.CodeAnalysis.NetAnalyzers/​tests/​Microsoft.CodeAnalysis.NetAnalyzers.UnitTests/​Microsoft.CodeQuality.Analyzers/​Maintainability/​AvoidDeadConditionalCode_NullAnalysis.cs Updated as part of this pull request.
src/​Microsoft.CodeAnalysis.NetAnalyzers/​src/​Utilities/​FlowAnalysis/​FlowAnalysis/​Framework/​DataFlow/​DataFlowOperationVisitor.cs Updated as part of this pull request.
src/​Microsoft.CodeAnalysis.NetAnalyzers/​src/​Utilities/​FlowAnalysis/​FlowAnalysis/​Framework/​DataFlow/​AnalysisEntityDataFlowOperationVisitor.cs Updated as part of this pull request.
src/​Microsoft.CodeAnalysis.NetAnalyzers/​src/​Utilities/​FlowAnalysis/​FlowAnalysis/​Analysis/​PointsToAnalysis/​PointsToAnalysis.PointsToDataFlowOperationVisitor.cs Updated as part of this pull request.
src/​Microsoft.CodeAnalysis.NetAnalyzers/​src/​Utilities/​FlowAnalysis/​FlowAnalysis/​Analysis/​GlobalFlowStateAnalysis/​GlobalFlowStateDataFlowOperationVisitor.cs Updated as part of this pull request.
src/​Microsoft.CodeAnalysis.NetAnalyzers/​src/​Utilities/​FlowAnalysis/​FlowAnalysis/​Analysis/​DisposeAnalysis/​DisposeAnalysis.DisposeDataFlowOperationVisitor.cs Updated as part of this pull request.
src/​Microsoft.CodeAnalysis.NetAnalyzers/​src/​Utilities/​FlowAnalysis/​FlowAnalysis/​Analysis/​CopyAnalysis/​CopyAnalysis.CopyDataFlowOperationVisitor.cs Updated as part of this pull request.
src/​Microsoft.CodeAnalysis.NetAnalyzers/​src/​Microsoft.CodeAnalysis.NetAnalyzers/​Microsoft.CodeQuality.Analyzers/​Maintainability/​AvoidDeadConditionalCode.cs Updated as part of this pull request.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reuse complete per-CFG referenced-member summaries across static local-function graphs; preserve aliases to static object roots when trimming would be unsafe.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

@Evangelink Evangelink left a comment

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.

Reviewed through 96a8741. The local-function trimming, reachable-CFG scans, shared summary caching, and deterministic regression coverage look good. Focused tests and required CI checks pass.

@tannergooding
tannergooding merged commit 300ee20 into dotnet:main Sep 29, 2026
26 checks passed
@tannergooding

Copy link
Copy Markdown
Member Author

CC. @baronfel, @marcpopMSFT

This and #56415 need weigh-in on whether we want to backport to .NET 11

The analyzers in question that were the worst offenders are generally off by default. However, if someone has them enabled such as via <AnalysisLevel>latest-all</AnalysisLevel> then they can really pessimize build times.

One of my projects had a 23 minute build time, where fixing 56415 took it down to 5 minutes and fixing this one on top took it down to 40 seconds.


They are, however, bigger changes and impact some shared analyzer infrastructure. They won't case cause more build warnings to surface and should just be a performance improvement, but they do deserve the explicit weigh-in given we're post RC2 snap and its a few hundred lines of code churn + a couple thousand lines of tests across both.

@tannergooding

Copy link
Copy Markdown
Member Author

These also impact .NET 10, but I don't think they meet the bar for it. Devs can just upgrade to the 11 package

@jeffhandley

Copy link
Copy Markdown
Member

I will support backporting this into 11.0 servicing (post-GA)

@tannergooding

Copy link
Copy Markdown
Member Author

/backport to release/11.0.2xx

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/11.0.2xx (link to workflow run)

This branch had an error being deployed

1 failed deployment
copilot-pat-pool — 96a87410 Deployed Sep 29, 2026 by tannergooding via pre_activation #6857
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants