Skip to content

Direct owned boxed-mixed call argument with a consumed return value corrupts refcounts (heap debug: bad refcount) #604

Description

@mirchaemanuel

Summary

Passing a freshly boxed owned mixed value directly as a call argument, and consuming the
call's return value, corrupts refcounts in a loop: heap debug aborts with
Fatal error: heap debug detected bad refcount. Stdout up to that point is correct.

Found while working on #595 (PR #603); independent of that fix — the failure is byte-identical
with and without the #595 classification change (verified by reverting it and rebuilding).

Repro

<?php
function idv($x) { return $x; }
$c = 0;
for ($i = 0; $i < 20; $i++) { $r = idv($i + 1); $c = $c + $r; }
echo $c, "\n";

Compiled with --heap-debug (main 1da317551, macos-aarch64):

Fatal error: heap debug detected bad refcount

PHP 8.4 prints 210.

Bisection

  • Passing through a local first ($x = $i + 1; $r = idv($x);) → heap-clean, correct output.
  • Discarding the call result (idv($i + 1); without using the return) → clean.
  • A constant argument (idv(5)) → clean.

The trigger is specifically an owned boxed-Mixed argument temporary (here the boxed
$i + 1) whose call result is also consumed — some reference is dropped once too often
(or retained once too few) between the caller's argument-ownership handling and the return
path that forwards the same box (return $x; returns the parameter itself).

Related

https://claude.ai/code/session_01HRvbcjPHa3kAojdCjNZL5L

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    In progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions