From 0a70a77f42b48ca2ab4d48e4bc86542b63e25843 Mon Sep 17 00:00:00 2001 From: mwilliams Date: Thu, 18 Apr 2013 19:21:40 -0700 Subject: [PATCH] Fix an issue with exit/include/etc Various unary operators have arbitrary effects. Dont assume we know anything about locals when we see one. Fix an expect for differences in line numbers. Prevent a use of an undefined constant from being optimized away. --- hphp/compiler/analysis/alias_manager.cpp | 28 ++++++++++++++++--- .../quick/exception_destructor_3.php.expectf | 2 +- hphp/test/quick/exception_many_locals.php | 1 + 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/hphp/compiler/analysis/alias_manager.cpp b/hphp/compiler/analysis/alias_manager.cpp index 1d1de4212..e87631d9d 100644 --- a/hphp/compiler/analysis/alias_manager.cpp +++ b/hphp/compiler/analysis/alias_manager.cpp @@ -601,6 +601,10 @@ void AliasManager::cleanRefs(ExpressionPtr e, ExpressionPtrList::reverse_iterator it, ExpressionPtrList::reverse_iterator &end, int depth) { + if (e->is(Expression::KindOfUnaryOpExpression) && + e->getLocalEffects() == Expression::UnknownEffect) { + return; + } if (e->is(Expression::KindOfAssignmentExpression) || e->is(Expression::KindOfBinaryOpExpression) || e->is(Expression::KindOfUnaryOpExpression)) { @@ -752,6 +756,7 @@ void AliasManager::killLocals() { continue; case Expression::KindOfUnaryOpExpression: + if (e->getLocalEffects() == Expression::UnknownEffect) goto kill_it; cleanInterf(spc(UnaryOpExpression, e)->getExpression(), ++it, end, depth); continue; @@ -848,9 +853,14 @@ int AliasManager::checkInterf(ExpressionPtr rv, ExpressionPtr e, return testAccesses(e, rv, forLval); } + case Expression::KindOfUnaryOpExpression: + if (e->getLocalEffects() == Expression::UnknownEffect) { + isLoad = false; + return InterfAccess; + } + // fall through case Expression::KindOfAssignmentExpression: - case Expression::KindOfBinaryOpExpression: - case Expression::KindOfUnaryOpExpression: { + case Expression::KindOfBinaryOpExpression: { isLoad = false; ExpressionPtr var = e->getStoreVariable(); int access = testAccesses(var, rv, forLval); @@ -899,6 +909,10 @@ int AliasManager::checkAnyInterf(ExpressionPtr e1, ExpressionPtr e2, case Expression::KindOfAssignmentExpression: case Expression::KindOfBinaryOpExpression: case Expression::KindOfUnaryOpExpression: + if (e1->getLocalEffects() == Expression::UnknownEffect) { + isLoad = false; + return InterfAccess; + } e1 = e1->getStoreVariable(); if (!e1 || !e1->hasContext(Expression::OprLValue)) return DisjointAccess; break; @@ -1274,6 +1288,7 @@ ExpressionPtr AliasManager::canonicalizeNode( } case Expression::KindOfUnaryOpExpression: { UnaryOpExpressionPtr u = spc(UnaryOpExpression, rep); + assert(u->getOp() == T_INC || u->getOp() == T_DEC); if (Option::EliminateDeadCode) { if (u->getActualType() && u->getActualType()->isInteger()) { ExpressionPtr val = u->getExpression()->clone(); @@ -1720,7 +1735,8 @@ ExpressionPtr AliasManager::canonicalizeNode( default: break; } - always_assert(alt->getKindOf() == uop->getExpression()->getKindOf()); + always_assert(alt->getKindOf() == + uop->getExpression()->getKindOf()); uop->getExpression()->setCanonID(alt->getCanonID()); } else { uop->getExpression()->setCanonID(m_nextID++); @@ -1729,7 +1745,11 @@ ExpressionPtr AliasManager::canonicalizeNode( add(m_accessList, e); break; default: - getCanonical(e); + if (uop->getLocalEffects() == Expression::UnknownEffect) { + add(m_accessList, e); + } else { + getCanonical(e); + } break; } break; diff --git a/hphp/test/quick/exception_destructor_3.php.expectf b/hphp/test/quick/exception_destructor_3.php.expectf index d6472d14c..591201215 100644 --- a/hphp/test/quick/exception_destructor_3.php.expectf +++ b/hphp/test/quick/exception_destructor_3.php.expectf @@ -3,5 +3,5 @@ main() starting Calling foo() Calling bar() In ThrowDestruct2::__destruct() -HipHop Warning: Destructor threw an object exception: exception 'Ex2' with message 'Exception leaked out of ThrowDestruct2::__destruct()' in %a on line 37 +HipHop Warning: Destructor threw an object exception: exception 'Ex2' with message 'Exception leaked out of ThrowDestruct2::__destruct()' in %a on line %d After bar() diff --git a/hphp/test/quick/exception_many_locals.php b/hphp/test/quick/exception_many_locals.php index 88308fb17..2ae3f893b 100644 --- a/hphp/test/quick/exception_many_locals.php +++ b/hphp/test/quick/exception_many_locals.php @@ -24,6 +24,7 @@ function main() { $o7 = $o; // use callee saved $p = 5; $x = CONSTANT; + echo $x; } catch (Exception $e) { echo "Caught: " . $e->getMessage() . "\n"; }