X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=parser.c;h=af9b0a01e0cc52873c8db8c0ea54788c42b09103;hb=4a97f1ec4b740978acc47d3332e46e0df660aee7;hp=531d07f3150366dddf563774096fb1009b138f63;hpb=245bf2db0e274757ccdacef3834ebf9aa1aac087;p=cparser diff --git a/parser.c b/parser.c index 531d07f..af9b0a0 100644 --- a/parser.c +++ b/parser.c @@ -2325,14 +2325,14 @@ error_parse_next: len * sizeof(initializers[0])); DEL_ARR_F(initializers); - ascend_to(path, top_path_level); + ascend_to(path, top_path_level+1); return result; end_error: skip_initializers(); DEL_ARR_F(initializers); - ascend_to(path, top_path_level); + ascend_to(path, top_path_level+1); return NULL; } @@ -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); @@ -4314,64 +4334,6 @@ static void check_declarations(void) } } -/** - * check all returns vor matching type. - */ -static bool search_return_statements(statement_t *statement) { - switch(statement->kind) { - case STATEMENT_RETURN: - /* ok, found a return */ - return true; - case STATEMENT_IF: { - /* return must be found on then and else */ - if_statement_t *if_stat = &statement->ifs; - if(if_stat->true_statement != NULL && if_stat->false_statement != NULL) { - return search_return_statements(if_stat->true_statement) && - search_return_statements(if_stat->false_statement); - } - break; - } - case STATEMENT_DO_WHILE: { - do_while_statement_t *do_stmt = &statement->do_while; - if(do_stmt->body != NULL) { - if (search_return_statements(do_stmt->body)) - return true; - } - break; - } - case STATEMENT_COMPOUND: { - /* search the last statement */ - compound_statement_t *compound = &statement->compound; - statement_t *statement = compound->statements; - if(statement == NULL) - return false; - for( ; statement != NULL; statement = statement->base.next) { - if (search_return_statements(statement)) - return true; - } - break; - } - default: - break; - } - return false; -} - -/** - * Check returns of a function. - */ -static void check_return_type(declaration_t *declaration) { - function_type_t *function_type = &declaration->type->function; - type_t *ret_type = function_type->return_type; - - if (ret_type != type_void) { - if (! search_return_statements(declaration->init.statement)) { - warningf(HERE, "missing return statement at end of non-void function '%Y'", - declaration->symbol); - } - } -} - static void parse_external_declaration(void) { /* function-definitions and declarations both start with declaration @@ -4483,7 +4445,6 @@ static void parse_external_declaration(void) assert(current_function == declaration); current_function = old_current_function; label_pop_to(label_stack_top); - check_return_type(declaration); } end_of_parse_external_declaration: @@ -5898,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, @@ -5918,37 +5882,26 @@ 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); - } + /* do default promotion */ + for( ; argument != NULL; argument = argument->next) { + type_t *type = argument->expression->base.type; - check_format(&result->call); - } - } else { - check_format(&result->call); - } + type = get_default_promoted_type(type); + + argument->expression + = create_implicit_cast(argument->expression, type); } + check_format(&result->call); + return result; end_error: return create_invalid_expression(); @@ -6972,13 +6925,13 @@ static void init_expression_parsers(void) register_infix_parser(parse_EXPR_UNARY_POSTFIX_DECREMENT, T_MINUSMINUS, 30); - register_infix_parser(parse_EXPR_BINARY_MUL, '*', 16); - register_infix_parser(parse_EXPR_BINARY_DIV, '/', 16); - register_infix_parser(parse_EXPR_BINARY_MOD, '%', 16); - register_infix_parser(parse_EXPR_BINARY_SHIFTLEFT, T_LESSLESS, 16); - register_infix_parser(parse_EXPR_BINARY_SHIFTRIGHT, T_GREATERGREATER, 16); - register_infix_parser(parse_EXPR_BINARY_ADD, '+', 15); - register_infix_parser(parse_EXPR_BINARY_SUB, '-', 15); + register_infix_parser(parse_EXPR_BINARY_MUL, '*', 17); + register_infix_parser(parse_EXPR_BINARY_DIV, '/', 17); + register_infix_parser(parse_EXPR_BINARY_MOD, '%', 17); + register_infix_parser(parse_EXPR_BINARY_ADD, '+', 16); + register_infix_parser(parse_EXPR_BINARY_SUB, '-', 16); + register_infix_parser(parse_EXPR_BINARY_SHIFTLEFT, T_LESSLESS, 15); + register_infix_parser(parse_EXPR_BINARY_SHIFTRIGHT, T_GREATERGREATER, 15); register_infix_parser(parse_EXPR_BINARY_LESS, '<', 14); register_infix_parser(parse_EXPR_BINARY_GREATER, '>', 14); register_infix_parser(parse_EXPR_BINARY_LESSEQUAL, T_LESSEQUAL, 14);