--- /dev/null
+--TEST--
+Bug #41633.1 (self:: doesn't work for constants)
+--FILE--
+<?php
+class Foo {
+ const A = self::B;
+ const B = "ok";
+}
+echo Foo::A."\n";
+?>
+--EXPECT--
+ok
--- /dev/null
+--TEST--
+Bug #41633.2 (Undefined class constants must not be substituted by strings)
+--FILE--
+<?php
+class Foo {
+ const A = self::B;
+}
+echo Foo::A."\n";
+?>
+--EXPECTF--
+Fatal error: Undefined class constant 'self::B' in %sbug41633_2.php on line 5
zval *p = *pp;
zend_bool inline_change = (zend_bool) (zend_uintptr_t) arg;
zval const_value;
+ char *colon;
if (Z_TYPE_P(p) == IS_CONSTANT) {
int refcount;
is_ref = p->is_ref;
if (!zend_get_constant_ex(p->value.str.val, p->value.str.len, &const_value, scope TSRMLS_CC)) {
+ if ((colon = memchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p))) && colon[1] == ':') {
+ zend_error(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p));
+ }
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
p->value.str.val,
p->value.str.val);
continue;
}
if (!zend_get_constant_ex(str_index, str_index_len-1, &const_value, scope TSRMLS_CC)) {
+ if ((colon = memchr(str_index, ':', str_index_len-1)) && colon[1] == ':') {
+ zend_error(E_ERROR, "Undefined class constant '%s'", str_index);
+ }
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index);
zend_hash_move_forward(Z_ARRVAL_P(p));
continue;
ce = EX_T(opline->op1.u.var).class_entry;
if (zend_hash_find(&ce->constants_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, (void **) &value) == SUCCESS) {
+ zend_class_entry *old_scope = EG(scope);
+
+ EG(scope) = ce;
zval_update_constant(value, (void *) 1 TSRMLS_CC);
+ EG(scope) = old_scope;
EX_T(opline->result.u.var).tmp_var = **value;
zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
} else {
ce = EX_T(opline->op1.u.var).class_entry;
if (zend_hash_find(&ce->constants_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, (void **) &value) == SUCCESS) {
+ zend_class_entry *old_scope = EG(scope);
+
+ EG(scope) = ce;
zval_update_constant(value, (void *) 1 TSRMLS_CC);
+ EG(scope) = old_scope;
EX_T(opline->result.u.var).tmp_var = **value;
zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
} else {
ce = EX_T(opline->op1.u.var).class_entry;
if (zend_hash_find(&ce->constants_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, (void **) &value) == SUCCESS) {
+ zend_class_entry *old_scope = EG(scope);
+
+ EG(scope) = ce;
zval_update_constant(value, (void *) 1 TSRMLS_CC);
+ EG(scope) = old_scope;
EX_T(opline->result.u.var).tmp_var = **value;
zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
} else {