Skip to content

C#: Remove some unbounded TC computations#21348

Open
hvitved wants to merge 4 commits intogithub:mainfrom
hvitved:csharp/remove-tcs
Open

C#: Remove some unbounded TC computations#21348
hvitved wants to merge 4 commits intogithub:mainfrom
hvitved:csharp/remove-tcs

Conversation

@hvitved
Copy link
Contributor

@hvitved hvitved commented Feb 19, 2026

We are in some cases computing (more or less) full non-fast TCs, which can be very expensive in cases like this one.

For example, the charpred of AstNode in ControlFlowGraphImpl.qll would previously result in the following DIL:

incremental
`#ControlFlowGraphImpl::getAChild/1#000c4110Plus#bf`(
  /* Element::Element */ interned entity p, /* Element::Element */ entity result
)
{
  [base_case]
  #@top_level_exprorstmt_parentMergeTypeCall(p) and
  `ControlFlowGraphImpl::getAChild/1#000c4110`(p, result)
  [recursive_case]
  exists(/* Element::Element */ entity mid |
    `ControlFlowGraphImpl::getAChild/1#000c4110`(mid, result) and
    delta previous rec `#ControlFlowGraphImpl::getAChild/1#000c4110Plus#bf`(p,
      mid)
  ) and
  not(
    previous rec `#ControlFlowGraphImpl::getAChild/1#000c4110Plus#bf`(p, result)
  )
}

suppressTypeErrors
ControlFlowGraphImpl::AstNode#QuickEval#27f9434f(
  /* ControlFlowGraphImpl::AstNode */ interned unique entity this
)
{
  (
    ControlFlowGraphImpl::TAstNode#636d28d6(this) and
    #@top_level_exprorstmt_parentMergeTypeCall(this) and
    not(#@attributeMergeTypeCall(this))
  )
  or
  exists(/* @top_level_exprorstmt_parent */ interned entity any#expr# |
    ControlFlowGraphImpl::TAstNode#636d28d6(this) and
    `#ControlFlowGraphImpl::getAChild/1#000c4110Plus#bf`(any#expr#, this) and
    #@top_level_exprorstmt_parentMergeTypeCall(any#expr#) and
    not(#@attributeMergeTypeCall(any#expr#))
  )
}

That is, we would compute a full TC only to afterwards filter away the target column via the any#expr#.

DCA is excellent; analysis time on microsoft__CryptoNets is reduced from 1379s to 80s.

@github-actions github-actions bot added the C# label Feb 19, 2026
@hvitved hvitved force-pushed the csharp/remove-tcs branch 2 times, most recently from 3f36bbd to 3d93e01 Compare March 4, 2026 18:53
@hvitved hvitved force-pushed the csharp/remove-tcs branch from 8c9fb8c to acd6f41 Compare March 5, 2026 08:11
@hvitved hvitved changed the title C#: Remove some unnecessary TCs C#: Remove some unbounded TC computations Mar 5, 2026
@hvitved hvitved added the no-change-note-required This PR does not need a change note label Mar 5, 2026
@hvitved hvitved marked this pull request as ready for review March 5, 2026 12:01
@hvitved hvitved requested a review from a team as a code owner March 5, 2026 12:02
Copilot AI review requested due to automatic review settings March 5, 2026 12:02
Copy link
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

Reduces expensive unbounded transitive-closure (TC) computations in the C# QL libraries by replacing *-closure patterns with explicit recursive helper predicates (often pragma[nomagic]) and more targeted reachability, improving analysis performance on large projects.

Changes:

  • Introduces reusable recursive descendant helpers (e.g., pattern-expression descendants) and wires them into expression/dataflow logic.
  • Refactors CFG AstNode and control-flow reachability scope handling to avoid computing “full” TCs that are later filtered.
  • Updates guard/dereferenceability plumbing to use a dedicated recursive predicate rather than applying getNullEquivParent* inline.

Reviewed changes

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

Show a summary per file
File Description
csharp/ql/lib/semmle/code/csharp/exprs/internal/Expr.qll Adds isPatternExprDescendant helper predicate to avoid getAChildExpr*() usage.
csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll Replaces getAChildExpr+() usage in isImplicit and updates tuple construction logic to call the new helper.
csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/ControlFlowReachability.qll Refactors scope/basic-block reachability with a combined newtype and doublyBoundedFastTC.
csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll Adds isAssignExprLValueDescendant helper and replaces star-closure pattern usages with helpers.
csharp/ql/lib/semmle/code/csharp/dataflow/internal/ControlFlowReachability.qll Same reachability refactor as rangeanalysis variant to avoid non-fast TC patterns.
csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll Replaces getAChild*-based AstNode characterization with explicit recursion via astNode.
csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll Introduces dereferenceableExpr helper predicate and uses it in DereferenceableExpr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C# no-change-note-required This PR does not need a change note

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants