From db130c83e15754206eee7a5315c341fc75f5a52a Mon Sep 17 00:00:00 2001 From: mwilliams Date: Wed, 17 Jul 2013 07:21:37 -0700 Subject: [PATCH] Identify direct children of yield expressions We want to be able to recognize them without knowing their context. --- hphp/compiler/analysis/alias_manager.cpp | 5 +++++ hphp/compiler/construct.h | 5 +++++ hphp/compiler/expression/expression.cpp | 1 + hphp/compiler/expression/yield_expression.cpp | 1 + hphp/test/slow/compilation/invalid_result.php | 5 +++++ hphp/test/slow/compilation/invalid_result.php.expect | 0 6 files changed, 17 insertions(+) create mode 100644 hphp/test/slow/compilation/invalid_result.php create mode 100644 hphp/test/slow/compilation/invalid_result.php.expect diff --git a/hphp/compiler/analysis/alias_manager.cpp b/hphp/compiler/analysis/alias_manager.cpp index 49400404f..bd1514648 100644 --- a/hphp/compiler/analysis/alias_manager.cpp +++ b/hphp/compiler/analysis/alias_manager.cpp @@ -36,6 +36,7 @@ #include "hphp/compiler/expression/expression.h" #include "hphp/compiler/expression/include_expression.h" #include "hphp/compiler/expression/closure_expression.h" +#include "hphp/compiler/expression/yield_expression.h" #include "hphp/compiler/statement/statement.h" #include "hphp/compiler/statement/statement_list.h" #include "hphp/compiler/statement/catch_statement.h" @@ -2115,6 +2116,7 @@ int AliasManager::collectAliasInfoRecur(ConstructPtr cs, bool unused) { } cs->clearVisited(); + cs->clearChildOfYield(); StatementPtr s = dpc(Statement, cs); if (s) { @@ -2405,6 +2407,9 @@ int AliasManager::collectAliasInfoRecur(ConstructPtr cs, bool unused) { // expressions. TODO: revisit this later m_inlineAsExpr = false; break; + case Expression::KindOfYieldExpression: + spc(YieldExpression, e)->getValueExpression()->setChildOfYield(); + break; case Expression::KindOfUnaryOpExpression: if (Option::EnableEval > Option::NoEval && spc(UnaryOpExpression, e)-> getOp() == T_EVAL) { diff --git a/hphp/compiler/construct.h b/hphp/compiler/construct.h index 4f9952b56..37a0dc68e 100644 --- a/hphp/compiler/construct.h +++ b/hphp/compiler/construct.h @@ -166,6 +166,10 @@ public: void clearKilled() { m_flags.killed = false; } bool isKilled() const { return m_flags.killed; } + void setChildOfYield() { m_flags.childOfYield = true; } + void clearChildOfYield() { m_flags.childOfYield = false; } + bool isChildOfYield() const { return m_flags.childOfYield; } + BlockScopeRawPtr getScope() const { return m_blockScope; } void setBlockScope(BlockScopeRawPtr scope) { m_blockScope = scope; } FileScopeRawPtr getFileScope() const { @@ -295,6 +299,7 @@ private: unsigned killed : 1; unsigned refCounted : 2; // high bit indicates whether its valid unsigned inited : 2; // high bit indicates whether its valid + unsigned childOfYield : 1; // parent node is yield } m_flags; }; protected: diff --git a/hphp/compiler/expression/expression.cpp b/hphp/compiler/expression/expression.cpp index 00baed55d..03e79ac49 100644 --- a/hphp/compiler/expression/expression.cpp +++ b/hphp/compiler/expression/expression.cpp @@ -70,6 +70,7 @@ ExpressionPtr Expression::replaceValue(ExpressionPtr rep) { rep->clearContext(AssignmentRHS); rep = el; } + if (isChildOfYield()) rep->setChildOfYield(); if (rep->is(KindOfSimpleVariable) && !is(KindOfSimpleVariable)) { static_pointer_cast(rep)->setAlwaysStash(); } diff --git a/hphp/compiler/expression/yield_expression.cpp b/hphp/compiler/expression/yield_expression.cpp index d1a8897cd..ddf936add 100644 --- a/hphp/compiler/expression/yield_expression.cpp +++ b/hphp/compiler/expression/yield_expression.cpp @@ -50,6 +50,7 @@ void YieldExpression::analyzeProgram(AnalysisResultPtr ar) { if (m_keyExp) { m_keyExp->analyzeProgram(ar); } + m_valExp->setChildOfYield(); m_valExp->analyzeProgram(ar); if (m_label == -1) { setLabel(getFunctionScope()->allocYieldLabel()); diff --git a/hphp/test/slow/compilation/invalid_result.php b/hphp/test/slow/compilation/invalid_result.php new file mode 100644 index 000000000..59750e542 --- /dev/null +++ b/hphp/test/slow/compilation/invalid_result.php @@ -0,0 +1,5 @@ +