From fc068bea049381894fdd2ea990fe30dabe7c5d2f Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Mon, 2 Jun 2008 13:45:39 +0000 Subject: [PATCH] fix handling of kr style functions [r19932] --- ast2firm.c | 12 ++++++-- parser.c | 84 ++++++++++++++++++++++++++++---------------------- parsetest/kr.c | 1 + 3 files changed, 58 insertions(+), 39 deletions(-) diff --git a/ast2firm.c b/ast2firm.c index c09a7c5..b16000b 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -4864,16 +4864,22 @@ static void initialize_function_parameters(declaration_t *declaration) continue; } + ir_type *param_irtype = get_method_param_type(function_irtype, n); + ir_mode *param_mode = get_type_mode(param_irtype); + + long pn = n; + ir_node *value = new_r_Proj(irg, start_block, args, param_mode, pn); + ir_mode *mode = get_ir_mode(parameter->type); - long pn = n; - ir_node *proj = new_r_Proj(irg, start_block, args, mode, pn); + value = create_conv(NULL, value, mode); + value = do_strict_conv(NULL, value); parameter->declaration_kind = DECLARATION_KIND_LOCAL_VARIABLE; parameter->v.value_number = next_value_number_function; set_irg_loc_description(current_ir_graph, next_value_number_function, parameter); ++next_value_number_function; - set_value(parameter->v.value_number, proj); + set_value(parameter->v.value_number, value); } } diff --git a/parser.c b/parser.c index e41e0c6..c007479 100644 --- a/parser.c +++ b/parser.c @@ -3815,11 +3815,15 @@ static declaration_t *internal_record_declaration( const symbol_t *const symbol = declaration->symbol; const namespace_t namespc = (namespace_t)declaration->namespc; + assert(declaration->symbol != NULL); + declaration_t *previous_declaration = get_declaration(symbol, namespc); + type_t *const orig_type = declaration->type; type_t *const type = skip_typeref(orig_type); if (is_type_function(type) && type->function.unspecified_parameters && - warning.strict_prototypes) { + warning.strict_prototypes && + previous_declaration == NULL) { warningf(&declaration->source_position, "function declaration '%#T' is not a prototype", orig_type, declaration->symbol); @@ -3829,9 +3833,6 @@ static declaration_t *internal_record_declaration( check_type_of_main(declaration, &type->function); } - assert(declaration->symbol != NULL); - declaration_t *previous_declaration = get_declaration(symbol, namespc); - assert(declaration != previous_declaration); if (previous_declaration != NULL) { if (previous_declaration->parent_scope == scope) { @@ -4158,6 +4159,20 @@ static void parse_declaration(parsed_declaration_func finished_declaration) } } +static type_t *get_default_promoted_type(type_t *orig_type) +{ + type_t *result = orig_type; + + type_t *type = skip_typeref(orig_type); + if(is_type_integer(type)) { + result = promote_integer(type); + } else if(type == type_float) { + result = type_double; + } + + return result; +} + static void parse_kr_declaration_list(declaration_t *declaration) { type_t *type = skip_typeref(declaration->type); @@ -4216,6 +4231,11 @@ static void parse_kr_declaration_list(declaration_t *declaration) semantic_parameter(parameter_declaration); parameter_type = parameter_declaration->type; + /* + * we need the default promoted types for the function type + */ + parameter_type = get_default_promoted_type(parameter_type); + function_parameter_t *function_parameter = obstack_alloc(type_obst, sizeof(function_parameter[0])); memset(function_parameter, 0, sizeof(function_parameter[0])); @@ -4231,7 +4251,7 @@ static void parse_kr_declaration_list(declaration_t *declaration) /* § 6.9.1.7: A K&R style parameter list does NOT act as a function * prototype */ - new_type->function.parameters = parameters; + new_type->function.parameters = parameters; new_type->function.unspecified_parameters = true; type = typehash_insert(new_type); @@ -5839,17 +5859,20 @@ static expression_t *parse_call_expression(unsigned precedence, rem_anchor_token(')'); expect(')'); - if(function_type != NULL) { - function_parameter_t *parameter = function_type->parameters; - call_argument_t *argument = call->arguments; + if(function_type == NULL) + return result; + + function_parameter_t *parameter = function_type->parameters; + call_argument_t *argument = call->arguments; + if (!function_type->unspecified_parameters) { for( ; parameter != NULL && argument != NULL; parameter = parameter->next, argument = argument->next) { type_t *expected_type = parameter->type; /* TODO report scope in error messages */ expression_t *const arg_expr = argument->expression; type_t *const res_type = semantic_assign(expected_type, arg_expr, - "function call", - &arg_expr->base.source_position); + "function call", + &arg_expr->base.source_position); if (res_type == NULL) { /* TODO improve error message */ errorf(&arg_expr->base.source_position, @@ -5859,35 +5882,24 @@ static expression_t *parse_call_expression(unsigned precedence, argument->expression = create_implicit_cast(argument->expression, expected_type); } } - /* too few parameters */ - if(parameter != NULL) { + + if (parameter != NULL) { errorf(HERE, "too few arguments to function '%E'", expression); - } else if(argument != NULL) { - /* too many parameters */ - if(!function_type->variadic - && !function_type->unspecified_parameters) { - errorf(HERE, "too many arguments to function '%E'", expression); - } else { - /* do default promotion */ - for( ; argument != NULL; argument = argument->next) { - type_t *type = argument->expression->base.type; - - type = skip_typeref(type); - if(is_type_integer(type)) { - type = promote_integer(type); - } else if(type == type_float) { - type = type_double; - } + } else if (argument != NULL && !function_type->variadic) { + errorf(HERE, "too many arguments to function '%E'", expression); + } + } - argument->expression - = create_implicit_cast(argument->expression, type); - } + check_format(&result->call); - check_format(&result->call); - } - } else { - check_format(&result->call); - } + /* do default promotion */ + for( ; argument != NULL; argument = argument->next) { + type_t *type = argument->expression->base.type; + + type = get_default_promoted_type(type); + + argument->expression + = create_implicit_cast(argument->expression, type); } return result; diff --git a/parsetest/kr.c b/parsetest/kr.c index 24c6a8c..3ab68c4 100644 --- a/parsetest/kr.c +++ b/parsetest/kr.c @@ -1,3 +1,4 @@ +int printf(const char *str, ...); int a(first, second, third) float second; -- 2.20.1