Skip to content

Claude/zen pasteur 76hfs1#31

Merged
PhysShell merged 5 commits into
mainfrom
claude/zen-pasteur-76hfs1
Jun 18, 2026
Merged

Claude/zen pasteur 76hfs1#31
PhysShell merged 5 commits into
mainfrom
claude/zen-pasteur-76hfs1

Conversation

@PhysShell

@PhysShell PhysShell commented Jun 18, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • Bug Fixes
    • Improved analysis of undisposed IDisposable resources within try/catch and try/finally, aligning results across tools and reducing false leak reports.
  • Tests
    • Updated CI leak expectations and expanded flow-local test cases, including additional try/catch leak and “must stay silent” scenarios.
  • Documentation
    • Refreshed the oracle write-up and the systemevents-console fixture README to cover new try-related leak coverage and behavior.
  • Samples
    • Added new try/catch and try/finally sample methods demonstrating clean and skipped/leak outcomes.
  • Chores
    • Upgraded the CodeQL action version used by the workflow.

claude added 4 commits June 18, 2026 03:09
…y-method recall slice)

The oracle's "Oracle only" Dispose-class bucket included plain undisposed locals the
--flow-locals detector skipped only because their method had a `try`. Lower
`try { A } [catch...] [finally { B }]` as sequential `A; B`: a local acquired in try
and disposed in finally stays balanced (silent), one never disposed leaks (now caught),
and try-methods are no longer skipped wholesale. Catch bodies aren't lowered; to stay
sound, bail (skip the method) if a catch disposes, so a release that only happens in a
catch is never missed -> no false leak.

Not yet modelled (documented next step): dispose-not-called-on-throw (disposed in try,
not finally) reads as released here — needs per-statement exceptional exits; switch/do
likewise stay skipped.

FlowLocalsSample gains TryFinallyClean (silent), TryNeverDisposed (flagged), and
CatchDisposesSkipped (soundly skipped -> silent); CI asserts each + the coverage
invariant still holds.
…y-lowering slice

Third leak in the cross-tool fixture: a FileStream never disposed, inside a try-method.
Before try/finally lowering it was "Oracle only" (Own.NET skipped any method with a
`try`); now Own.NET lowers it and should join the FileStream control in "Agree" across
Own.NET + CodeQL + Infer#. Bump the oracle sentinel to re-run.
The flow detector now lowers try/finally (sequential A;B, catch-disposes bailed for
soundness), so a plain undisposed local in a try-method is caught. The cross-tool
fixture's try-method FileStream leak moved from "Oracle only" into "Agree"
(Own.NET + Infer#), validating the slice. Note the still-deferred
dispose-not-called-on-throw (try-not-finally) + switch/do.
… CodeQL arm)

The cross-tool re-run lost CodeQL to JOB_STATUS_CONFIGURATION_ERROR ("Loaded a
configuration file for version '4.36.2', but running version '3.36.2'"): init was
github/codeql-action/init@v4 but analyze was still @V3, so init wrote a v4 config
the v3 analyze couldn't read. Bump analyze to @v4 to match. Bump the sentinel to
re-run and confirm all three tools (incl. CodeQL) return on the fixture.
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 447a353a-8ae5-4f02-b6b6-bf5a50a270ee

📥 Commits

Reviewing files that changed from the base of the PR and between 1470834 and dc983a6.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • corpus/fixtures/systemevents-console/README.md
  • frontend/roslyn/OwnSharp.Extractor/Program.cs
  • frontend/roslyn/samples/FlowLocalsSample.cs
✅ Files skipped from review due to trivial changes (1)
  • corpus/fixtures/systemevents-console/README.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/ci.yml
  • frontend/roslyn/OwnSharp.Extractor/Program.cs

📝 Walkthrough

Walkthrough

Extends the --flow-locals lowering in LowerFlowStmt to handle TryStatementSyntax by sequentially lowering the try then finally blocks while skipping methods whose catch blocks call Dispose/Close/DisposeAsync. Adds five sample methods and a corpus fixture exercising the new cases, updates CI assertions and documentation, and bumps the CodeQL analyze action to v4.

Changes

try/finally Lowering in Flow-Locals

Layer / File(s) Summary
LowerFlowStmt: TryStatementSyntax case
frontend/roslyn/OwnSharp.Extractor/Program.cs
Adds a TryStatementSyntax branch that rejects lowering when any catch block contains Dispose/Close/DisposeAsync invocations or when try contains a return and finally exists, otherwise lowers the try block followed by the finally block sequentially; updates the default bail-out comment.
FlowLocalsSample: five new try/catch methods
frontend/roslyn/samples/FlowLocalsSample.cs
Adds TryFinallyClean (dispose in finally, silent), TryNeverDisposed (no dispose, expected leak), CatchDisposesSkipped (dispose in catch, intentionally skipped), TryFinallyReturn (return in try with finally-disposal, model bails), and CatchNullCondDispose (null-conditional ?.Dispose() in catch, model skipped) to cover the supported and edge-case behaviors.
Corpus fixture: LeakInTry and README
corpus/fixtures/systemevents-console/Program.cs, corpus/fixtures/systemevents-console/README.md
Adds LeakInTry() (a FileStream allocated in try, exception swallowed in catch, never disposed) called from Main; updates README to enumerate all three leak classes with per-tool detection expectations and clarify the cross-tool oracle narrative.
CI assertions, oracle notes, and mining docs
.github/workflows/ci.yml, corpus/oracle-target.txt, docs/notes/real-world-mining.md
Extends the flow-locals CI step to assert tfLeak is reported and tfClean/tfCatch/tfRet/tfNull remain silent; revises oracle-target.txt guidance for CodeQL action/init version alignment; expands real-world-mining.md with sequential-lowering details, catch-dispose soundness exclusion, concrete FileStream examples, and deferred patterns.

CodeQL Action Version Bump

Layer / File(s) Summary
oracle.yml: codeql-action/analyze v3 → v4
.github/workflows/oracle.yml
Updates the CodeQL analyze step from github/codeql-action/analyze@v3 to @v4; all other step inputs and configuration remain unchanged.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PhysShell/Own.NET#15: This PR directly extends the --flow-locals infrastructure first introduced in PR #15, adding try/catch handling to the flow lowering machinery and updating sample/fixture code and CI assertions.
  • PhysShell/Own.NET#16: PR #16 introduced the initial flow-locals lowering with try marked as unmodelled in LowerFlowStmt; this PR extends that same code path to partially handle TryStatementSyntax with sequential try/finally lowering.

Poem

🐇 Hippity-hoppity, try blocks beware,
A rabbit has lowered your finally stair!
The catch-dispose cases we soundly skip,
But undisposed FileStream? We've got a good grip.
No leaks shall escape this flow-local snare! 🔍

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'Claude/zen pasteur 76hfs1' is a generic branch name identifier that does not describe the actual changes made in the pull request. Replace the title with a clear, descriptive summary of the main change, such as 'Add try/finally statement lowering to flow-sensitive IDisposable analysis' or similar.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 87.50% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/zen-pasteur-76hfs1

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1470834192

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

return false;
if (!LowerFlowStmt(trys.Block, tracked, nodes))
return false;
if (trys.Finally is { } fin && !LowerFlowStmt(fin.Block, tracked, nodes))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve finally cleanup on early returns

When a try block contains return, this lowers the finally body by appending it after the return op. The OwnIR CFG treats return as terminal, so a real cleanup such as try { return; } finally { stream.Dispose(); } becomes unreachable in the model and --flow-locals reports stream as leaked even though C# always runs the finally before exiting. This affects try/finally cleanup patterns with early returns.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Good catch — fixed in dc983a6. You're right: the finally release lands after the terminal return op and becomes unreachable in the sequential model, so a resource the finally disposes was falsely flagged. Until finally-before-return is modelled, I bail the method when a try-with-finally contains a return. The common try { …; return x; } finally { r.Dispose(); } is safe anyway, so skipping it is sound — no false leak, and no false negative on that shape (a real leak there is rare). Locked with a TryFinallyReturn sample that must stay silent (CI asserts it).


Generated by Claude Code

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@corpus/fixtures/systemevents-console/README.md`:
- Line 17: The line starting with `#2 is the agreement...` in the README.md file
is triggering a Markdown linting error (MD018) because `#` followed by text
without a space is being interpreted as a heading marker. Reword the sentence so
that `#2` is not at the beginning of the line (for example, by moving it to the
middle like "Leak `#2` is the agreement..."), or escape the hash character to
prevent it from being interpreted as a Markdown heading token.

In `@frontend/roslyn/OwnSharp.Extractor/Program.cs`:
- Around line 371-375: The catch block disposal detection logic in the foreach
loop iterating over trys.Catches only checks for MemberAccessExpressionSyntax
(matching patterns like x.Dispose()), but fails to detect conditional-access
patterns like x?.Dispose() which use MemberBindingExpressionSyntax. Extend the
condition that currently checks "i.Expression is MemberAccessExpressionSyntax
cm" to also handle MemberBindingExpressionSyntax cases, ensuring both expression
types are checked for the method names "Dispose", "Close", or "DisposeAsync" to
prevent false positive OWN001 diagnostics in catch-only disposal scenarios.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3f78e60e-a06e-4dab-9658-490a9d14a94b

📥 Commits

Reviewing files that changed from the base of the PR and between e8068a7 and 1470834.

📒 Files selected for processing (8)
  • .github/workflows/ci.yml
  • .github/workflows/oracle.yml
  • corpus/fixtures/systemevents-console/Program.cs
  • corpus/fixtures/systemevents-console/README.md
  • corpus/oracle-target.txt
  • docs/notes/real-world-mining.md
  • frontend/roslyn/OwnSharp.Extractor/Program.cs
  • frontend/roslyn/samples/FlowLocalsSample.cs

Comment thread corpus/fixtures/systemevents-console/README.md Outdated
Comment thread frontend/roslyn/OwnSharp.Extractor/Program.cs
…n finally + ?.Dispose catch)

Two false positives in the try/finally lowering, caught in review:

* Codex (P2): a `return` inside a try-with-finally made the finally's release
  unreachable after the terminal `return` op, so the model falsely flagged a resource
  the finally disposes (the common `try { …; return x; } finally { r.Dispose(); }`).
  Until finally-before-return is modelled, bail when a try-with-finally contains a
  return — that shape is safe anyway, so skipping it is sound.
* CodeRabbit: the catch-dispose bail only matched `x.Dispose()` (member access), not
  `x?.Dispose()` (member binding), so a catch-only conditional dispose got lowered and
  could false-flag. Match both expression shapes.

FlowLocalsSample gains TryFinallyReturn and CatchNullCondDispose (both must stay
silent); CI asserts them. Also reword the fixture README to avoid MD018 (CodeRabbit).
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.

2 participants