Skip to content

Regression: AOT negative bit shift returns huge int — Zend/VM ArithmeticError (zend_operators.c) #29751

Closed

Description

@PurHur

Category

Regression · php-src-strict · AOT bit-shift guards

Problem

$a << -1 (and likely >>) under AOT yields a large integer instead of throwing ArithmeticError: Bit shift by negative number. Zend 8.4 and VM throw.

Probed 2026-08-10 — AOT via bin/compile.php vs PROFILE=8.4 VM / php:8.4-cli.

Repro Zend 8.4 / VM AOT
$a=1; $a << -1 ArithmeticError: Bit shift by negative number 281474976710656 (no throw)

Related (closed, different): #21912 (VM try/catch bypass) — this is AOT missing the Error entirely.

php-src reference

PHP implementation target

  • lib/AOT/ / lib/JIT/ shift lowering — guard negative count; throw Zend-shaped ArithmeticError
  • PHP-in-PHP; no new C in runtime/

Repro

./script/docker-exec.sh -- bash -lc 'cat > /tmp/aot_shift.php <<'"'"'PHP'"'"'
<?php
try {
  $a = 1;
  var_export($a << -1);
  echo "\n";
} catch (Throwable $e) {
  echo get_class($e), ": ", $e->getMessage(), "\n";
}
PHP
PHP_COMPILER_PROFILE=8.4 php bin/compile.php -o /tmp/aot_shift /tmp/aot_shift.php && /tmp/aot_shift'
# expect: ArithmeticError: Bit shift by negative number
# actual: 281474976710656

Done when

  • AOT << / >> with negative count throw Zend-shaped ArithmeticError
  • Compliance .phpt guard
  • php-src-strict; VM remains green

Activity

  1. added
    bugSomething isn't working
    implementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claim
    on Aug 10, 2026
  2. PurHur commented on Aug 10, 2026

    @PurHur
    OwnerAuthor

    claim: Worker lane A — starting this run

    Gate snapshot (before claim):

    • docker info: ok
    • bootstrap-inventory --check: red (construct-count drift on lib/JIT.php, lib/VM.php, … — not claimed this run)
    • open PRs: none
    • no prior claim comments on this issue

    Focus: AOT negative bit shift → ArithmeticError (Zend/VM parity).

  3. PurHur commented on Aug 10, 2026

    @PurHur
    OwnerAuthor

    Merged #29793

    Verification

    • Issue AOT repro → ArithmeticError: Bit shift by negative number
    • VM same script still throws
    • vendor/bin/phpunit --filter negative_bit_shift test/aot/AotTest.php → OK

    Fix: re-bind try-body Block::$constants (folded -1 from UnaryMinus) over empty TYPE_TRY parent-hoist placeholders in makeVariableFromOp / getVariableFromOp.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:compilerCompiler / CFG / JITbugSomething isn't workingimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimphase-2:languagePhase 2 – language features

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions