Skip to content

Fix AOT int-to-string collision with live resource handles (#23811) - #23826

Merged
PurHur merged 1 commit into
masterfrom
agent/issue-23811-aot-int-string-resource-collision
Jul 27, 2026
Merged

Fix AOT int-to-string collision with live resource handles (#23811)#23826
PurHur merged 1 commit into
masterfrom
agent/issue-23811-aot-int-string-resource-collision

Conversation

@PurHur

@PurHur PurHur commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Summary

  • Root cause: AOT string interpolation coerces locals through boxed __value__strval::valueToString(), which called formatNativeLong() and probed the resource handle registry by numeric value. Integer 2 collided with live handle #2 and rendered as Resource id #2.
  • Fix: Boxed TYPE_NATIVE_LONG values use formatBoxedNativeLong() (plain %lld — resources in boxes are TYPE_OBJECT). Unboxed native-long coercion threads CFG operand provenance via cannotBeResourceForString() for concat/echo.
  • Guards: New differential case g07a_int_string_resource_collision.php (VM + AOT). Full g07_incdec_resource_provenance.php keeps @differential-skip-aot for the separate decrement-below-zero crash still open on this issue.

Verification

# Issue repro (Docker)
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php bin/vm.php test/repro/aot_int_string_resource_collision.php
php bin/compile.php -o /tmp/r.bin test/repro/aot_int_string_resource_collision.php && /tmp/r.bin'
# zend: 2 3 4 3
# aot:  2 3 4 3

# Differential guard
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php test/differential/cases/g07a_int_string_resource_collision.php
php bin/compile.php -o /tmp/g07a.bin test/differential/cases/g07a_int_string_resource_collision.php && /tmp/g07a.bin'
# both: 2 3 4 3

vendor/bin/phpunit --filter IncDecResourceProvenanceStringTest
# OK (2 tests)

Not covered this PR: $n = 0; $n--; $n--; still prints 0 under AOT (decrement + post-echo truncation in full g07 repro).

Closes #23811 (string rendering); decrement portion remains for follow-up on the issue.

Made with Cursor

…23811).

Boxed __value__ longs skip the handle-registry probe; native-long coercion
threads operand provenance from concat/echo so arithmetic locals format as
integers, not Resource id #N.

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

AOT: string conversion of an int renders "Resource id #N" when the value collides with a live handle

1 participant