validation
authorMichael Wallner <mike@php.net>
Fri, 7 Jul 2017 07:30:05 +0000 (09:30 +0200)
committerMichael Wallner <mike@php.net>
Fri, 7 Jul 2017 07:30:05 +0000 (09:30 +0200)
src/types/decl_arg.c
src/types/decl_struct.c
src/types/decl_type.c
src/types/decl_type.h
src/types/num_exp.c

index bec8ddc77f1132c87a140c4232aa326aac62e0d0..61aacef3641ad2b0b205449273a9a86b8d3e25b3 100644 (file)
@@ -95,11 +95,13 @@ void psi_decl_arg_dump(int fd, struct psi_decl_arg *arg, unsigned level)
 bool psi_decl_arg_validate(struct psi_data *data, struct psi_decl_arg *arg,
                struct psi_validate_stack *type_stack)
 {
-       if (!psi_decl_type_validate(data, arg->type, type_stack)) {
-               data->error(data, arg->type->token, PSI_WARNING,
-                               "Cannot use '%s' as type for '%s': %s", arg->type->name,
-                               arg->var->name, data->last_error);
-               return false;
+       if (!psi_decl_type_validate(data, arg->type, arg->var->pointer_level, type_stack)) {
+                if (!arg->var->pointer_level) {
+                       data->error(data, arg->type->token, PSI_WARNING,
+                                       "Cannot use '%s' as type for '%s'%s%s", arg->type->name,
+                                       arg->var->name, *data->last_error ? ": " : "", data->last_error);
+                       return false;
+                }
        }
        return true;
 }
@@ -120,29 +122,27 @@ bool psi_decl_arg_validate_typedef(struct psi_data *data,
                                        "Type '%s' cannot be aliased to 'void'", def->type->name);
                        return false;
                }
-       } else if (!def->var->pointer_level) {
-               if (!psi_decl_type_validate(data, def->type, type_stack)) {
-                       const char *pre;
-
-                       switch (def->type->type) {
-                       case PSI_T_STRUCT:
-                               pre = "struct ";
-                               break;
-                       case PSI_T_UNION:
-                               pre = "union ";
-                               break;
-                       case PSI_T_ENUM:
-                               pre = "enum ";
-                               break;
-                       default:
-                               pre = "";
-                               break;
-                       }
-                       data->error(data, def->token, PSI_WARNING,
-                                       "Type '%s' cannot be aliased to '%s%s': %s", def->var->name, pre,
-                                       def->type->name, data->last_error);
-                       return false;
+       } else if (!psi_decl_type_validate(data, def->type, def->var->pointer_level, type_stack)) {
+               const char *pre;
+
+               switch (def->type->type) {
+               case PSI_T_STRUCT:
+                       pre = "struct ";
+                       break;
+               case PSI_T_UNION:
+                       pre = "union ";
+                       break;
+               case PSI_T_ENUM:
+                       pre = "enum ";
+                       break;
+               default:
+                       pre = "";
+                       break;
                }
+               data->error(data, def->token, PSI_WARNING,
+                               "Type '%s' cannot be aliased to '%s%s'%s%s", def->var->name, pre,
+                               def->type->name, *data->last_error ? ": " : "", data->last_error);
+               return false;
        }
 
        return true;
index 973f6333537163134e900ceda726596858c60720..cc7cc69871700fdb7313ce511858573cdbedbcdd 100644 (file)
@@ -128,7 +128,7 @@ bool psi_decl_struct_validate(struct psi_data *data, struct psi_decl_struct *s,
                        }
                } else {
                        if (i) {
-                               if (prev_arg->layout->bfw && darg->layout->bfw) {
+                               if (prev_arg->layout && prev_arg->layout->bfw && darg->layout && darg->layout->bfw) {
                                        struct psi_decl_type *real = NULL;
                                        size_t max_bfw = 8 * psi_decl_type_get_size(prev_arg->type, &real);
 
index 73e89595a36717288a516697d37908a96cab1777..afab9e307cae40995b9bd14abb91e6336d0f6a1b 100644 (file)
@@ -101,9 +101,9 @@ size_t psi_decl_type_get_size(struct psi_decl_type *dtyp,
 
        switch (var_typ->type) {
        case PSI_T_STRUCT:
-               return var_typ->real.strct->size;
+               return var_typ->real.strct ? var_typ->real.strct->size : 0;
        case PSI_T_UNION:
-               return var_typ->real.unn->size;
+               return var_typ->real.unn ? var_typ->real.unn->size : 0;
        default:
                return psi_t_size(var_typ->type);
        }
@@ -118,7 +118,7 @@ bool psi_decl_type_get_alias(struct psi_decl_type *type, struct psi_plist *defs)
        if (type->real.def) {
                return true;
        }
-       if (defs)
+       if (defs) {
                while (psi_plist_get(defs, i++, &def)) {
                        if (def->type->type != type->type
                                        && !strcmp(def->var->name, type->name)) {
@@ -126,6 +126,7 @@ bool psi_decl_type_get_alias(struct psi_decl_type *type, struct psi_plist *defs)
                                return true;
                        }
                }
+       }
        for (stdtyp = &psi_std_types[0]; stdtyp->type_tag; ++stdtyp) {
                if (!strcmp(type->name, stdtyp->alias ?: stdtyp->type_name)) {
                        type->type = stdtyp->type_tag;
@@ -213,7 +214,7 @@ bool psi_decl_type_get_decl(struct psi_decl_type *type, struct psi_plist *decls)
 }
 
 bool psi_decl_type_validate(struct psi_data *data, struct psi_decl_type *type,
-               struct psi_validate_stack *type_stack)
+               bool is_pointer, struct psi_validate_stack *type_stack)
 {
        if (psi_decl_type_is_weak(type)) {
                if (!psi_decl_type_get_alias(type, data->types)) {
@@ -224,7 +225,7 @@ bool psi_decl_type_validate(struct psi_data *data, struct psi_decl_type *type,
                }
                if (type->real.def) {
                        return psi_decl_type_validate(data, type->real.def->type,
-                                       type_stack);
+                                       is_pointer, type_stack);
                }
                return true;
        }
@@ -234,6 +235,8 @@ bool psi_decl_type_validate(struct psi_data *data, struct psi_decl_type *type,
                if (!psi_decl_type_get_struct(type, data->structs)) {
                        if (psi_validate_stack_has_struct(type_stack, type->name)) {
                                type->real.strct = psi_validate_stack_get_struct(type_stack, type->name);
+                       } else if (is_pointer) {
+                               return true;
                        } else {
                                data->error(data, type->token, PSI_WARNING,
                                                "Unknown struct '%s'", type->name);
@@ -248,6 +251,8 @@ bool psi_decl_type_validate(struct psi_data *data, struct psi_decl_type *type,
                if (!psi_decl_type_get_union(type, data->unions)) {
                        if (psi_validate_stack_has_union(type_stack, type->name)) {
                                type->real.unn = psi_validate_stack_get_union(type_stack, type->name);
+                       } else if (is_pointer) {
+                               return true;
                        } else {
                                data->error(data, type->token, PSI_WARNING,
                                                "Unknown union '%s'", type->name);
@@ -330,7 +335,7 @@ void psi_decl_type_dump(int fd, struct psi_decl_type *t, unsigned level)
                                }
                        }
                        --level;
-                       dprintf(fd, "%s} ", psi_t_indent(level));
+                       dprintf(fd, "%s\n} ", psi_t_indent(level));
                        return;
                }
                break;
index a31f317f206e5f8a241389d097fa4c4b69d875f5..4e56a23f9baec03a35b4d69eb01673722251d087 100644 (file)
@@ -58,7 +58,7 @@ struct psi_decl_type *psi_decl_type_init(token_t type, const char *name);
 struct psi_decl_type *psi_decl_type_copy(struct psi_decl_type *src);
 void psi_decl_type_free(struct psi_decl_type **type_ptr);
 void psi_decl_type_dump(int fd, struct psi_decl_type *t, unsigned level);
-bool psi_decl_type_validate(struct psi_data *data, struct psi_decl_type *type, struct psi_validate_stack *type_stack);
+bool psi_decl_type_validate(struct psi_data *data, struct psi_decl_type *type, bool is_pointer, struct psi_validate_stack *type_stack);
 
 bool psi_decl_type_validate_args(struct psi_data *data, struct psi_decl_type *decl_type, token_t type, void *current);
 
index 91ff887311979e625942ada7fc16828cc8fe3797..69d21e05d7fa5489b4152a77efddeb95550df846 100644 (file)
@@ -431,7 +431,7 @@ bool psi_num_exp_validate(struct psi_data *data, struct psi_num_exp *exp,
 
        case PSI_T_CAST:
                return psi_num_exp_validate(data, exp->data.c.num, impl, cb_decl, current_let, current_set, current_enum)
-                               && psi_decl_type_validate(data, exp->data.c.typ, NULL);
+                               && psi_decl_type_validate(data, exp->data.c.typ, 0, NULL);
                break;
 
        case PSI_T_NOT: