/* 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;
}
}
--- /dev/null
+--TEST--
+Throwings NEWs should not be DCEd
+--INI--
+opcache.enable_cli=1
+opcache.optimization_level=-1
+--FILE--
+<?php
+
+abstract class Foo {}
+interface Bar {}
+trait Baz {}
+
+class Abc {
+ const BAR = Abc::BAR;
+}
+
+function test1() {
+ $x = new Foo;
+}
+function test2() {
+ $x = new Bar;
+}
+function test3() {
+ $x = new Baz;
+}
+function test4() {
+ $x = new Abc;
+}
+
+try { test1(); } catch (Error $e) { echo $e->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'