Fix assertion in ref-count optimization
MemElim may transform the source of a DecRefNZ into a constant, so we shouldn't assert that it's coming from an IncRef.
Esse commit está contido em:
@@ -165,10 +165,13 @@ initInstructions(const BlockList& blocks, DceState& state) {
|
||||
}
|
||||
if (inst.getOpcode() == DecRefNZ) {
|
||||
auto* srcInst = inst.getSrc(0)->getInstruction();
|
||||
assert(srcInst->getOpcode() == IncRef);
|
||||
assert(state[srcInst].isDead()); // IncRef isn't essential so it should
|
||||
// be dead here
|
||||
state[srcInst].setDecRefNZed();
|
||||
Opcode srcOpc = srcInst->getOpcode();
|
||||
if (srcOpc != DefConst) {
|
||||
assert(srcInst->getOpcode() == IncRef);
|
||||
assert(state[srcInst].isDead()); // IncRef isn't essential so it should
|
||||
// be dead here
|
||||
state[srcInst].setDecRefNZed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,6 +579,12 @@ void MemMap::processInstruction(IRInstruction* inst, bool isPseudoMain) {
|
||||
SSATmp* ref = inst->getSrc(0);
|
||||
Type ty = inst->getSrc(0)->getType();
|
||||
|
||||
if (ref->isConst()) {
|
||||
// cannot be ref-counted
|
||||
inst->convertToNop();
|
||||
break;
|
||||
}
|
||||
|
||||
// decref of a string has no side effects
|
||||
if (ty.isString()) {
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
function foo(&$x, $y) {
|
||||
$x = array(1,2);
|
||||
$y = $x;
|
||||
return $y;
|
||||
}
|
||||
|
||||
$x = 0;
|
||||
$y = 0;
|
||||
var_dump(foo($x, $y));
|
||||
var_dump($x);
|
||||
@@ -0,0 +1,12 @@
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(1)
|
||||
[1]=>
|
||||
int(2)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(1)
|
||||
[1]=>
|
||||
int(2)
|
||||
}
|
||||
Referência em uma Nova Issue
Bloquear um usuário