Skip to content

P-007 POOL004: object-level (cross-member) pooled-view-in-a-field escape #205

Description

@PhysShell

Follow-up split out of #198 (P-007 Pool/Span). Deliberate deferral — recorded with evidence, per #198's "a deliberate deferral beats a soft false positive."

The uncovered shape

A pooled buffer's view is cached into a field, and that view field is read after the buffer is Returned in a different member:

sealed class ViewEscapeField : IDisposable
{
    private byte[] _buf;
    private Memory<byte> _view;
    public void Setup(int n) { _buf = ArrayPool<byte>.Shared.Rent(n); _view = _buf.AsMemory(0, n); } // bounded view -> field
    public void Done()  => ArrayPool<byte>.Shared.Return(_buf);   // release
    public byte[] Late() => _view.ToArray();                      // reads the field view AFTER the return
    public void Dispose() { }
}

Verified against the current extractor + core (dotnet run … --flow-localspython -m ownlang ownir): nothing fires. The view is bounded (so no POOL005/OWN025 over-read), and the use-after-return (POOL004/OWN002) is never surfaced because the Return and the field-view read live in different members.

Why it is deferred, not fixed

Whether this is a bug depends on the caller's method-call order, which a per-method + field pass cannot see:

  • Setup → Done → Late — use-after-return (the bug).
  • Setup → Late → Done — perfectly fine.

Flagging it unconditionally would be a soft false positive (P-007 §Non-goals: whole-program/interprocedural Span/Memory escape is out of v0 scope). It needs interprocedural / whole-program ordering (or a conservative "view field outlives a class-wide Return with no ordering proof" heuristic that would have to clear the corpus zero-FP gate).

What #198 did deliver

The materialization side is covered and now pinned: a full-length view stored into a field (_view = _buf.AsMemory()) is caught at the store as an OWN025 over-read (corpus arraypool-view-into-field-overread). This issue is only the bounded-view object-level escape left past that boundary.

Done when

The cross-member field-view-after-Return escape is caught (POOL004 → OWN002) with a corpus bad/ok pair, without any new false positive on the existing corpus (the Setup → Late → Done order and every current ok-fixture stay silent).

Refs: docs/proposals/P-007-arraypool-span.md; corpus/real-world/arraypool-view-into-field-overread/notes.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions