Fix silly bug when computing AttrDeepInit for a property
This diff fixes a crashing bug that can happen when multiple properties are
declared in a single statement and some of the properties are initialized
using collection literals, for example:
public $x = Set {}, $y = 1;
Esse commit está contido em:
@@ -6344,7 +6344,7 @@ PreClass::Hoistable EmitterVisitor::emitClass(Emitter& e, ClassScopePtr cNode,
|
||||
dynamic_pointer_cast<ClassVariable>((*stmts)[i])) {
|
||||
ModifierExpressionPtr mod(cv->getModifiers());
|
||||
ExpressionListPtr el(cv->getVarList());
|
||||
Attr attrs = buildAttrs(mod);
|
||||
Attr declAttrs = buildAttrs(mod);
|
||||
StringData* typeConstraint = StringData::GetStaticString(
|
||||
cv->getTypeConstraint());
|
||||
int nVars = el->getCount();
|
||||
@@ -6371,14 +6371,20 @@ PreClass::Hoistable EmitterVisitor::emitClass(Emitter& e, ClassScopePtr cNode,
|
||||
StringData* propName = StringData::GetStaticString(var->getName());
|
||||
StringData* propDoc = empty_string.get();
|
||||
TypedValue tvVal;
|
||||
// Some properties may need to be marked with the AttrDeepInit
|
||||
// attribute, while other properties should not be marked with
|
||||
// this attrbiute. We copy declAttrs into propAttrs for each loop
|
||||
// iteration so that we can safely add AttrDeepInit to propAttrs
|
||||
// without mutating the original declAttrs.
|
||||
Attr propAttrs = declAttrs;
|
||||
if (vNode) {
|
||||
if (vNode->isScalar()) {
|
||||
initScalar(tvVal, vNode);
|
||||
} else {
|
||||
tvWriteUninit(&tvVal);
|
||||
if (!(attrs & AttrStatic)) {
|
||||
if (!(declAttrs & AttrStatic)) {
|
||||
if (requiresDeepInit(vNode)) {
|
||||
attrs = (Attr)(attrs | AttrDeepInit);
|
||||
propAttrs = propAttrs | AttrDeepInit;
|
||||
}
|
||||
if (nonScalarPinitVec == nullptr) {
|
||||
nonScalarPinitVec = new NonScalarVec();
|
||||
@@ -6395,8 +6401,8 @@ PreClass::Hoistable EmitterVisitor::emitClass(Emitter& e, ClassScopePtr cNode,
|
||||
tvWriteNull(&tvVal);
|
||||
}
|
||||
bool added UNUSED =
|
||||
pce->addProperty(propName, attrs, typeConstraint, propDoc, &tvVal,
|
||||
hphpcType);
|
||||
pce->addProperty(propName, propAttrs, typeConstraint,
|
||||
propDoc, &tvVal, hphpcType);
|
||||
assert(added);
|
||||
}
|
||||
} else if (ClassConstantPtr cc =
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
class Foo {
|
||||
private $x = Set {}, $y = 1;
|
||||
}
|
||||
$obj = new Foo();
|
||||
echo "Done\n";
|
||||
@@ -0,0 +1 @@
|
||||
Done
|
||||
Referência em uma Nova Issue
Bloquear um usuário