OPcache folds FETCH_CONSTANT across later DECLARE_CONST when zend_execute_internal is set
@arnaud-lb đang làm issue này rồi.
Từ ngày 13/1/2026.
Đánh giá
Issue này chưa được đánh giá.
Mô tả
Description
OPcache folds FETCH_CONSTANT across later DECLARE_CONST when zend_execute_internal is set, changing program semantics.
When an extension sets zend_execute_internal (even to a no-op), zend_get_call_op chooses the generic ZEND_DO_FCALL for INIT_FCALL_BY_NAME. This appears to affect OPcache pass 1: in a script that calls a function before a constant is declared, OPcache replaces ZEND_FETCH_CONSTANT inside that function with the later-declared literal, changing behavior from a fatal error to printing the constant value.
Reproducer
INI:
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=-1
opcache.opt_debug_level=0x10000
Code:
<?php
printf("A=%s\n", getA());
const A = "hello";
function getA() { return A; }
Without any module: the script fatals (Undefined constant "A"), and getA keeps FETCH_CONSTANT (see bug66251).
With a module that only does:
orig_execute_internal = zend_execute_internal;
zend_execute_internal = our_own_execute_internal;
the optimizer turns getA into RETURN "hello" and the script prints A=hello.
Question
Is this behavior expected when an extension hooks zend_execute_internal?
Output (for reference).
No zend_execute_internal (before and after optimizer):
$_main:
; (lines=8, args=0, vars=0, tmps=2)
; (before optimizer)
; /bin/bug66251.php:1-6
; return [] RANGE[0..0]
0000 INIT_FCALL 2 112 string("printf")
0001 SEND_VAL string("A=%s\n") 1
0002 INIT_FCALL_BY_NAME 0 string("getA")
0003 V0 = DO_FCALL_BY_NAME
0004 SEND_VAR V0 2
0005 DO_ICALL
0006 DECLARE_CONST string("A") string("hello")
0007 RETURN int(1)
getA:
; (lines=3, args=0, vars=0, tmps=1)
; (before optimizer)
; /bin/bug66251.php:4-4
; return [] RANGE[0..0]
0000 T0 = FETCH_CONSTANT string("A")
0001 RETURN T0
0002 RETURN null
$_main:
; (lines=8, args=0, vars=0, tmps=1)
; (after optimizer)
; /bin/bug66251.php:1-6
0000 INIT_FCALL 2 112 string("printf")
0001 SEND_VAL string("A=%s\n") 1
0002 INIT_FCALL 0 96 string("geta")
0003 V0 = DO_UCALL
0004 SEND_VAR V0 2
0005 DO_ICALL
0006 DECLARE_CONST string("A") string("hello")
0007 RETURN int(1)
getA:
; (lines=2, args=0, vars=0, tmps=1)
; (after optimizer)
; /bin/bug66251.php:4-4
0000 T0 = FETCH_CONSTANT string("A")
0001 RETURN T0
zend_execute_internal is set (before and after optimizer):
$_main:
; (lines=8, args=0, vars=0, tmps=2)
; (before optimizer)
; /bin/bug66251.php:1-6
; return [] RANGE[0..0]
0000 INIT_FCALL 2 112 string("printf")
0001 SEND_VAL string("A=%s\n") 1
0002 INIT_FCALL_BY_NAME 0 string("getA")
0003 V0 = DO_FCALL
0004 SEND_VAR V0 2
0005 DO_FCALL
0006 DECLARE_CONST string("A") string("hello")
0007 RETURN int(1)
getA:
; (lines=3, args=0, vars=0, tmps=1)
; (before optimizer)
; /bin/bug66251.php:4-4
; return [] RANGE[0..0]
0000 T0 = FETCH_CONSTANT string("A")
0001 RETURN T0
0002 RETURN null
$_main:
; (lines=8, args=0, vars=0, tmps=1)
; (after optimizer)
; /bin/bug66251.php:1-6
0000 INIT_FCALL 2 112 string("printf")
0001 SEND_VAL string("A=%s\n") 1
0002 INIT_FCALL 0 80 string("geta")
0003 V0 = DO_UCALL
0004 SEND_VAR V0 2
0005 DO_FCALL
0006 DECLARE_CONST string("A") string("hello")
0007 RETURN int(1)
getA:
; (lines=1, args=0, vars=0, tmps=0)
; (after optimizer)
; /bin/bug66251.php:4-4
0000 RETURN string("hello")
PHP Version
PHP 8.5.1 (cli) (built: Dec 17 2025 08:47:15) (ZTS)
Copyright (c) The PHP Group
Zend Engine v4.5.1, Copyright (c) Zend Technologies
with Zend OPcache v8.5.1, Copyright (c), by Zend Technologies
- Ngôn ngữ chính
- C
- Star
- 40.4k
- Fork
- 8.2k
- Merge trung bình
- 2 ngày 15 giờ
- Pull request đã merge (30 ngày)
- 103
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của php/php-src
-
Bug SAPI: cli_server Status: Verified
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
-
Bug Status: Needs Triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
-
Bug Status: Needs Triage
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100
-
Bug Status: Needs Triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
Flaky hrtime.phpt test Đang mởBug Category: Tests Status: Verified
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
zephyrproject-rtos/zephyr#119726 ·
-
[Bounty proposal] fix(web): memory insights count an evening memory on the next day ($25 proposed) Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
BasedHardware/omi#15320 ·
-
[adam] AdamNet network read doesn't cap to MAX_ADAM_PACKET_LEN, overflows client receive buffers Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
FujiNetWIFI/fujinet-firmware#1649 · 2 bình luận ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
HarbourMasters/Shipwright#7229 ·
-
Error while building from source Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
riscv-software-src/riscv-isa-sim#2435 · 1 bình luận ·