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:
Drew Paroski
2013-07-25 01:56:20 -07:00
commit de Sara Golemon
commit 64b284d281
3 arquivos alterados com 18 adições e 5 exclusões
+11 -5
Ver Arquivo
@@ -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