Skip to content

Regression: engine-thrown Error/TypeError getCode() crashes — code property uninitialized (Zend/zend_exceptions.c) #22945

Description

@PurHur

Category

bug · php-src-strict · Throwable / Error materialization

Problem

User throw new TypeError('…') / throw new Error('…', N) initializes $code (getCode works). Engine-bridged throwables from the VM (undefined method, TypeError on args, DivisionByZeroError from /) leave ExceptionSupport::PROP_CODE unset. Throwable::getCode() then fatals on Variable::$integer uninitialized instead of returning 0.

Repro Zend 8.2+ VM (2026-07-24)
try { (new stdClass)->nope(); } catch (Error $e) { echo $e->getCode(); } 0 Fatal: Typed property PHPCompiler\VM\Variable::$integer must not be accessed before initialization
try { $f=fn(int $x)=>0; $f('a'); } catch (TypeError $e) { echo $e->getCode(); } 0 same Fatal
try { 1/0; } catch (DivisionByZeroError $e) { echo $e->getCode(); } 0 same Fatal
try { throw new TypeError('t'); } catch (TypeError $e) { echo $e->getCode(); } 0 0 (OK — ctor path)

Root cause: BuiltinExceptionSupport::materializeThrowable() / materializeDivisionByZeroError() stamp message/file/line but never ->int(0) on PROP_CODE (unlike Exception::__construct / materializeJsonException).

php-src reference

PHP implementation target

  • lib/VM/BuiltinExceptionSupport.phpmaterializeThrowable() + materializeDivisionByZeroError() (and any sibling materializers missing code) must set PROP_CODE to 0 (or the bridged native code)
  • lib/VM/Builtin/ExceptionGetCode.php — already copies property; fix is at materialize
  • PHP-in-PHP only; no new C

Repro

./script/docker-exec.sh -- bash -lc 'cat >/tmp/engine_getcode.php <<'"'"'PHP'"'"'
<?php
ini_set("display_errors", "1");
error_reporting(E_ALL);
foreach ([
  "undef" => fn() => (new stdClass)->nope(),
  "type" => function () { $f = function (int $x) {}; $f("a"); },
  "div" => fn() => 1/0,
] as $name => $fn) {
  try { $fn(); }
  catch (Throwable $e) {
    echo $name, " ", get_class($e), " code=", $e->getCode(), "\n";
  }
}
PHP
php /tmp/engine_getcode.php
php bin/vm.php /tmp/engine_getcode.php'

Done when

  • Engine-thrown Error / TypeError / DivisionByZeroError / ArithmeticError: getCode() returns 0 (or Zend code) without secondary fatal
  • User-thrown throw new TypeError / throw new Error('x', 7) still match Zend
  • Compliance .phpt under test/compliance/cases/; php-src-strict; no php-compiler-strict shortcut

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:vmVirtual machinebugSomething 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