Skip to content

In php 7.3, Sparse Conditional Constant Propogation may skip over dynamically added __get() or __set() #116

@TysonAndre

Description

@TysonAndre

With certain opcache settings (php -d opcache.optimization_level=-1 -d opcache.opt_debug_level=0x20020000 -l script.php), fn would get optimized down to return 2;.

  • Not familiar with what dead/redundant code elimination php 7.2 has.
<?php
class C { 
	public $i;
}

function fn(int $x) {
	$c = new C;
	$c->i = 1;
	if($x) {
		$a = [1, 2, 3];
	} else {
		$a = [3, 2, 1];
	}
	return $a[$c->i];
	$c->i++;
	return $x;
}
fn(1);
SCCP Values for "fn":
    #4.X3 = {}
    #5.CV1($c) = {}
    #6.CV1($c) = {"i" => int(1)}
    #7.CV2($a) = array(...)
    #8.CV2($a) = array(...)
    #9.CV2($a) = [1 => int(2)]
    #10.X4 = int(1)
    #11.X3 = int(2)

fn: ; (lines=2, args=1, vars=1, tmps=0)
    ; (after optimizer)
    ; script.php:6-17
L0:     CV0($x) = RECV 1
L1:     RETURN int(2)

This will be regression from older versions of PHP, where __get and __set could be added dynamically and they would work as expected.

Possible solution:

  • Refuse to add/remove __get/__set based on opcache presence and opcache optimization flags used. Continue allowing modification.
  • Refuse to add/remove __construct/__destruct based on opcache presence and opcache optimization flags. Continue allowing modification.

Depending on how aggressive function/method inlining becomes in PHP 7.3, users may have issues with methods similar to how constants behave within classes

  • May affect self::static_method(), final methods, and methods called within final classes.
  • constructors with empty bodies?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions