From 38bee72e4045fd0a21a6e1ed0e4aa8bc5b2c75f6 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 17 Feb 2018 14:50:20 +0100 Subject: [PATCH] Fix DCE of throwing NEWs --- ext/opcache/Optimizer/escape_analysis.c | 7 ++++- ext/opcache/tests/invalid_new_dce.phpt | 40 +++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/invalid_new_dce.phpt diff --git a/ext/opcache/Optimizer/escape_analysis.c b/ext/opcache/Optimizer/escape_analysis.c index a1378721ab..66866e8b24 100644 --- a/ext/opcache/Optimizer/escape_analysis.c +++ b/ext/opcache/Optimizer/escape_analysis.c @@ -177,9 +177,14 @@ static int is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, in /* objects with destructors should escape */ if (opline->op1_type == IS_CONST) { zend_class_entry *ce = get_class_entry(script, Z_STR_P(CRT_CONSTANT_EX(op_array, opline, opline->op1, ssa->rt_constants)+1)); + uint32_t forbidden_flags = ZEND_ACC_INHERITED + /* These flags will always cause an exception */ + | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS + | ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT; if (ce && !ce->create_object && !ce->constructor && !ce->destructor && !ce->__get && !ce->__set && - !(ce->ce_flags & ZEND_ACC_INHERITED)) { + !(ce->ce_flags & forbidden_flags) && + (ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { return 1; } } diff --git a/ext/opcache/tests/invalid_new_dce.phpt b/ext/opcache/tests/invalid_new_dce.phpt new file mode 100644 index 0000000000..8f44b80f10 --- /dev/null +++ b/ext/opcache/tests/invalid_new_dce.phpt @@ -0,0 +1,40 @@ +--TEST-- +Throwings NEWs should not be DCEd +--INI-- +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- +getMessage(), "\n"; } +try { test2(); } catch (Error $e) { echo $e->getMessage(), "\n"; } +try { test3(); } catch (Error $e) { echo $e->getMessage(), "\n"; } +try { test4(); } catch (Error $e) { echo $e->getMessage(), "\n"; } + +?> +--EXPECT-- +Cannot instantiate abstract class Foo +Cannot instantiate interface Bar +Cannot instantiate trait Baz +Cannot declare self-referencing constant 'Abc::BAR' -- 2.40.0