]> granicus.if.org Git - php/commitdiff
- Treat $this->foo inside class X as an implicit 'public $foo' if X::$foo
authorZeev Suraski <zeev@php.net>
Mon, 10 Feb 2003 12:46:58 +0000 (12:46 +0000)
committerZeev Suraski <zeev@php.net>
Mon, 10 Feb 2003 12:46:58 +0000 (12:46 +0000)
  is not explicitly declared
- Forbid multiple declaration of the same variable

Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_language_parser.y

index df345cbcb1645185534a17b2726384b57d23653d..4156e7b552db508a2e878e7ec72f4644cb095749 100644 (file)
@@ -1619,6 +1619,8 @@ static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_pro
        if (zend_hash_quick_find(&ce->properties_info, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void **) &child_info)==SUCCESS) {
                if ((child_info->flags & ZEND_ACC_PPP_MASK) > (parent_info->flags & ZEND_ACC_PPP_MASK)) {
                        zend_error(E_COMPILE_ERROR, "Access level to %s::$%s must be %s (as in class %s)%s", ce->name, hash_key->arKey, zend_visibility_string(parent_info->flags), parent_ce->name, (parent_info->flags&ZEND_ACC_PUBLIC) ? "" : " or weaker");
+               } else if (child_info->flags & ZEND_ACC_IMPLICIT_PUBLIC) {
+                       return 1; /* Inherit from the parent */
                }
                return 0;       /* Don't copy from parent */
        } else {
@@ -2209,12 +2211,18 @@ void mangle_property_name(char **dest, int *dest_length, char *src1, int src1_le
 }
 
 
-void zend_do_declare_property(znode *var_name, znode *value TSRMLS_DC)
+void zend_do_declare_property(znode *var_name, znode *value, zend_uint access_type TSRMLS_DC)
 {
        zval *property;
        zend_property_info property_info;
+       zend_property_info *existing_property_info;
        HashTable *target_symbol_table;
 
+       if (zend_hash_find(&CG(active_class_entry)->properties_info, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, (void **) &existing_property_info)==SUCCESS) {
+               if (!(existing_property_info->flags & ZEND_ACC_IMPLICIT_PUBLIC)) {
+                       zend_error(E_COMPILE_ERROR, "Cannot redeclare %s::$%s", CG(active_class_entry)->name, var_name->u.constant.value.str.val);
+               }
+       }
        ALLOC_ZVAL(property);
 
        if (value) {
@@ -2224,13 +2232,13 @@ void zend_do_declare_property(znode *var_name, znode *value TSRMLS_DC)
                property->type = IS_NULL;
        }
 
-       if (CG(access_type) & ZEND_ACC_STATIC) {
+       if (access_type & ZEND_ACC_STATIC) {
                target_symbol_table = CG(active_class_entry)->static_members;
        } else {
                target_symbol_table = &CG(active_class_entry)->default_properties;
        }
 
-       switch (CG(access_type) & ZEND_ACC_PPP_MASK) {
+       switch (access_type & ZEND_ACC_PPP_MASK) {
                case ZEND_ACC_PRIVATE: {
                                char *priv_name;
                                int priv_name_length;
@@ -2257,7 +2265,7 @@ void zend_do_declare_property(znode *var_name, znode *value TSRMLS_DC)
                        property_info.name_length = var_name->u.constant.value.str.len;
                        break;
        }
-       property_info.flags = CG(access_type);
+       property_info.flags = access_type;
        property_info.h = zend_get_hash_value(property_info.name, property_info.name_length+1);
 
        zend_hash_update(&CG(active_class_entry)->properties_info, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, &property_info, sizeof(zend_property_info), NULL);
@@ -2326,6 +2334,10 @@ void zend_do_fetch_property(znode *result, znode *object, znode *property TSRMLS
                                        break;
                        }
                        *result = opline_ptr->result;
+                       if (CG(active_class_entry)
+                               && !zend_hash_exists(&CG(active_class_entry)->properties_info, property->u.constant.value.str.val, property->u.constant.value.str.len+1)) {
+                               zend_do_declare_property(property, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_IMPLICIT_PUBLIC TSRMLS_CC);
+                       }
                        return;
                }
        }
index fa54846ed1b4418b04927039e8423b245281a736..f590044d48fd10c6da2d40e591745cd1e613d51e 100644 (file)
@@ -99,6 +99,7 @@ typedef struct _zend_brk_cont_element {
 #define ZEND_ACC_PPP_MASK  (ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE)
 
 #define ZEND_ACC_CHANGED       0x80
+#define ZEND_ACC_IMPLICIT_PUBLIC       0x100
 
 char *zend_visibility_string(zend_uint fn_flags);
 
@@ -357,7 +358,7 @@ void zend_do_default_before_statement(znode *case_list, znode *default_token TSR
 
 void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znode *parent_class_name TSRMLS_DC);
 void zend_do_end_class_declaration(znode *class_token TSRMLS_DC);
-void zend_do_declare_property(znode *var_name, znode *value TSRMLS_DC);
+void zend_do_declare_property(znode *var_name, znode *value, zend_uint access_type TSRMLS_DC);
 void zend_do_declare_class_constant(znode *var_name, znode *value TSRMLS_DC);
 
 void zend_do_fetch_property(znode *result, znode *object, znode *property TSRMLS_DC);
index 672b5f4d0492abf2f447d3f4d3664acc236452ea..2310a655af53d05c89525cfdb71f1d93dd87cbae 100644 (file)
@@ -474,10 +474,10 @@ access_modifier:
 ;
 
 class_variable_declaration:
-               class_variable_declaration ',' T_VARIABLE                                       { zend_do_declare_property(&$3, NULL TSRMLS_CC); }
-       |       class_variable_declaration ',' T_VARIABLE '=' static_scalar     { zend_do_declare_property(&$3, &$5 TSRMLS_CC); }
-       |       T_VARIABLE                                              { zend_do_declare_property(&$1, NULL TSRMLS_CC); }
-       |       T_VARIABLE '=' static_scalar    { zend_do_declare_property(&$1, &$3 TSRMLS_CC); }
+               class_variable_declaration ',' T_VARIABLE                                       { zend_do_declare_property(&$3, NULL, CG(access_type) TSRMLS_CC); }
+       |       class_variable_declaration ',' T_VARIABLE '=' static_scalar     { zend_do_declare_property(&$3, &$5, CG(access_type) TSRMLS_CC); }
+       |       T_VARIABLE                                              { zend_do_declare_property(&$1, NULL, CG(access_type) TSRMLS_CC); }
+       |       T_VARIABLE '=' static_scalar    { zend_do_declare_property(&$1, &$3, CG(access_type) TSRMLS_CC); }
 ;
 
 class_constant_declaration: