Skip to content

Language: warnings inside functions/methods/closures cite call site — Zend inner opline (Zend/zend_execute.c) #32040

Description

@PurHur

Category

Language · php-src-strict / diagnostics / nested frames

Problem

Engine warnings and deprecations raised inside a user function, method, or closure cite the call site (f();, $obj->m(), $fn();) instead of the inner opcode line Zend reports. Top-level scripts already report the operator line (control). Encapsed-string top-level drift is a separate issue (#32034).

Probed 2026-08-18 @ 87cba84dc2 — Zend 8.2.32 vs php bin/vm.php / php bin/jit.php.

Repro Zend 8.2.32 VM/JIT
function f(){ echo $missing; } f(); — $missing on line 7, call on line 10 Warning line 7 Warning line 10
class C { function go(){ echo $missing; } } (new C)->go(); — inner 9, call 13 line 9 line 13
$fn = function(){ echo 5.5 % 2; }; $fn(); — % on line 6, $fn() on line 8 Deprecated line 6 Deprecated line 8
same % at file scope line 5 line 5 ✓

error_get_last()['line'] follows the same wrong call-site line for unsileced undefined-variable inside a closure.

php-src reference

PHP implementation target

  • lib/VM.php — when emitting E_WARNING / E_DEPRECATED from an opcode inside a called frame, use that opcode's sourceLocation->startLine, not the caller's DO_FCALL / FUNCCALL line (related skip comment around call-site line immediates, Regression: __destruct deferred on reassignment / $obj=null — unset() OK (zend_objects.c, re-#6456) #23484)
  • lib/Compiler.php — ensure function/method/closure opcodes keep their own startLine rather than inheriting the call node
  • lib/JIT.php / AOT — same user-site line on the matching paths
  • No new runtime/*.c

Repro

./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_gap_undef_var_function_line.php'
./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_gap_undef_var_method_line.php'
./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_gap_mod_float_closure_line.php'
./script/docker-exec.sh -- bash -lc 'php test/repro/maintainer_gap_undef_var_function_line.php'  # Zend baseline
<?php
error_reporting(E_ALL);
function inner(): void
{
    echo $missing, "\n"; // Zend: this line; VM: the inner() call below
}
inner();

Done when

  • VM/JIT: undefined-variable Warning inside functions, methods, and closures cites the inner fetch line (Zend)
  • VM/JIT: float % int E_DEPRECATED inside a closure cites the % line (Zend); file-scope unchanged
  • error_get_last()['line'] matches the Warning line for the unsileced closure case
  • Compliance .phpt under test/compliance/cases/language/
  • php-src-strict; no php-compiler-strict shortcut

Activity

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 / JITarea: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