From 45a536fc7cdda856447d0aaff98eeded3bb894de Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Tue, 4 May 2010 18:21:00 +0000 Subject: [PATCH] - Added check for abstract class abstract class foo { } class T { use foo; } // T cannot use foo - it is not a trait - Added check for trait on NEW trait a { } new a; // Cannot instantiate trait a # Tests for errors comming soon :) --- Zend/zend_compile.c | 2 +- Zend/zend_vm_def.h | 4 +++- Zend/zend_vm_execute.h | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index b4e7f0fe459..312581552b1 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -4518,7 +4518,7 @@ void zend_do_implements_trait(znode *trait_name TSRMLS_DC) /* {{{ */ opline->opcode = ZEND_ADD_TRAIT; SET_NODE(opline->op1, &CG(implementing_class)); zend_resolve_class_name(trait_name, &opline->extended_value, 0 TSRMLS_CC); - opline->extended_value = (opline->extended_value & ~ZEND_FETCH_CLASS_MASK) | ZEND_FETCH_CLASS_TRAIT; + opline->extended_value = ZEND_FETCH_CLASS_TRAIT; opline->op2_type = IS_CONST; opline->op2.constant = zend_add_class_name_literal(CG(active_op_array), &trait_name->u.constant TSRMLS_CC); CG(active_class_entry)->num_traits++; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index e17c6de9f3b..a53a35f9035 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3230,6 +3230,8 @@ ZEND_VM_HANDLER(68, ZEND_NEW, ANY, ANY) if (EX_T(opline->op1.var).class_entry->ce_flags & ZEND_ACC_INTERFACE) { class_type = "interface"; + } else if (EX_T(opline->op1.var).class_entry->ce_flags & ZEND_ACC_TRAIT) { + class_type = "trait"; } else { class_type = "abstract class"; } @@ -4663,7 +4665,7 @@ ZEND_VM_HANDLER(154, ZEND_ADD_TRAIT, ANY, ANY) opline->extended_value TSRMLS_CC); if (trait) { - if (!(trait->ce_flags & ZEND_ACC_TRAIT)) { + if (!((trait->ce_flags & ~ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) & ZEND_ACC_TRAIT)) { zend_error_noreturn(E_ERROR, "%s cannot use %s - it is not a trait", ce->name, trait->name); } zend_do_implement_trait(ce, trait TSRMLS_CC); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 1e086c667f9..217ddef8d1d 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -520,6 +520,8 @@ static int ZEND_FASTCALL ZEND_NEW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (EX_T(opline->op1.var).class_entry->ce_flags & ZEND_ACC_INTERFACE) { class_type = "interface"; + } else if (EX_T(opline->op1.var).class_entry->ce_flags & ZEND_ACC_TRAIT) { + class_type = "trait"; } else { class_type = "abstract class"; } @@ -691,7 +693,7 @@ static int ZEND_FASTCALL ZEND_ADD_TRAIT_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) opline->extended_value TSRMLS_CC); if (trait) { - if (!(trait->ce_flags & ZEND_ACC_TRAIT)) { + if (!((trait->ce_flags & ~ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) & ZEND_ACC_TRAIT)) { zend_error_noreturn(E_ERROR, "%s cannot use %s - it is not a trait", ce->name, trait->name); } zend_do_implement_trait(ce, trait TSRMLS_CC);