diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2003-04-06 23:13:42 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 21:00:16 -0700 |
| commit | fbd7e42ec801e3f99ec3da1aff584ff0e3bf7dce (patch) | |
| tree | aeb08bf1fd38d4eb6039b8a8c7a66ba89231072f | |
| parent | 774d0729c4f44cb828d8ae231857c4b4393ac434 (diff) | |
| download | sparse-dev-fbd7e42ec801e3f99ec3da1aff584ff0e3bf7dce.tar.gz | |
Fix up degenerate arrays to handle the string case (which is
not an lvalue-array).
Evaluate a unary '+' as a no-op.
Make function argument evaluation actually walk the function argument
declaration list, and check the function argument types.
| -rw-r--r-- | evaluate.c | 67 |
1 files changed, 42 insertions, 25 deletions
@@ -289,17 +289,20 @@ static struct symbol *degenerate(struct expression *expr, struct symbol *ctype, sym->bit_size = BITS_IN_POINTER; sym->ctype.alignment = POINTER_ALIGNMENT; ctype = sym; - ptr = *ptr_p; - *ptr_p = ptr->unop; - /* - * This all really assumes that we got the degenerate - * array as an lvalue (ie a dereference). If that - * is not the case, then holler - because we've screwed - * up. - */ - if (!lvalue_expression(ptr)) - warn(ptr->pos, "internal error: strange degenerate array case"); + if (expr->type != EXPR_STRING) { + ptr = *ptr_p; + *ptr_p = ptr->unop; + + /* + * This all really assumes that we got the degenerate + * array as an lvalue (ie a dereference). If that + * is not the case, then holler - because we've screwed + * up. + */ + if (!lvalue_expression(ptr)) + warn(ptr->pos, "internal error: strange degenerate array case"); + } } return ctype; } @@ -905,6 +908,7 @@ static struct symbol *evaluate_preop(struct expression *expr) switch (expr->op) { case '(': + case '+': *expr = *expr->unop; return ctype; @@ -1084,19 +1088,34 @@ static struct symbol *evaluate_sizeof(struct expression *expr) return size_t_ctype; } -static int evaluate_expression_list(struct expression_list *head) +static int evaluate_arguments(struct symbol *fn, struct expression_list *head) { - if (head) { - struct ptr_list *list = (struct ptr_list *)head; - do { - int i; - for (i = 0; i < list->nr; i++) { - struct expression *expr = (struct expression *)list->list[i]; - evaluate_expression(expr); + struct expression *expr; + struct symbol_list *argument_types = fn->arguments; + struct symbol *argtype; + + PREPARE_PTR_LIST(argument_types, argtype); + FOR_EACH_PTR (head, expr) { + struct expression **p = THIS_ADDRESS(expr); + struct symbol *ctype, *target; + ctype = evaluate_expression(expr); + + if (ctype) { + if (ctype->type == SYM_ARRAY) { + ctype = degenerate(expr, ctype, p); + expr->ctype = ctype; } - } while ((list = list->next) != (struct ptr_list *)head); - } - // FIXME! + } + + target = argtype; + if (!target && ctype->bit_size < BITS_IN_INT) + target = &int_ctype; + if (target) + compatible_assignment_types(expr, target, p, ctype); + + NEXT_PTR_LIST(argument_types, argtype); + } END_FOR_EACH_PTR; + FINISH_PTR_LIST; return 1; } @@ -1202,8 +1221,6 @@ static struct symbol *evaluate_call(struct expression *expr) if (!evaluate_expression(fn)) return NULL; - if (!evaluate_expression_list(arglist)) - return NULL; ctype = fn->ctype; if (ctype->type == SYM_NODE) ctype = ctype->ctype.base_type; @@ -1213,6 +1230,8 @@ static struct symbol *evaluate_call(struct expression *expr) warn(expr->pos, "not a function"); return NULL; } + if (!evaluate_arguments(ctype, arglist)) + return NULL; args = expression_list_size(expr->args); fnargs = symbol_list_size(ctype->arguments); if (args < fnargs) @@ -1416,8 +1435,6 @@ long long get_expression_value(struct expression *expr) ctype = evaluate_expression(expr); if (!ctype || expr->type != EXPR_VALUE) { warn(expr->pos, "bad constant expression"); - show_expression(expr); - printf(": badness\n"); return 0; } |
