From 848d77002c2c0451ccb76b9059cb352fabbdd8bc Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Fri, 7 Jul 2017 09:30:05 +0200 Subject: [PATCH] validation --- src/types/decl_arg.c | 54 ++++++++++++++++++++--------------------- src/types/decl_struct.c | 2 +- src/types/decl_type.c | 17 ++++++++----- src/types/decl_type.h | 2 +- src/types/num_exp.c | 2 +- 5 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/types/decl_arg.c b/src/types/decl_arg.c index bec8ddc..61aacef 100644 --- a/src/types/decl_arg.c +++ b/src/types/decl_arg.c @@ -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; diff --git a/src/types/decl_struct.c b/src/types/decl_struct.c index 973f633..cc7cc69 100644 --- a/src/types/decl_struct.c +++ b/src/types/decl_struct.c @@ -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); diff --git a/src/types/decl_type.c b/src/types/decl_type.c index 73e8959..afab9e3 100644 --- a/src/types/decl_type.c +++ b/src/types/decl_type.c @@ -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; diff --git a/src/types/decl_type.h b/src/types/decl_type.h index a31f317..4e56a23 100644 --- a/src/types/decl_type.h +++ b/src/types/decl_type.h @@ -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); diff --git a/src/types/num_exp.c b/src/types/num_exp.c index 91ff887..69d21e0 100644 --- a/src/types/num_exp.c +++ b/src/types/num_exp.c @@ -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: -- 2.30.2