From 3ed57f7f1c2f5cfaa0c62eaf4f94bb928c59dfa1 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Thu, 14 May 2009 17:45:01 +0000 Subject: [PATCH 1/1] next iteration of kr handling after a discussion with Christoph [r25955] --- parser.c | 66 ++++++++++++++++++++++++++++++++++++-------------------- type_t.h | 1 - 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/parser.c b/parser.c index 07886f4..dd50d4c 100644 --- a/parser.c +++ b/parser.c @@ -4766,10 +4766,6 @@ static void parse_kr_declaration_list(entity_t *entity) if (!type->function.kr_style_parameters) return; - entity_t *proto_type = get_entity(entity->base.symbol, NAMESPACE_NORMAL); - if (proto_type != NULL && proto_type->kind != ENTITY_FUNCTION) - proto_type = NULL; - add_anchor_token('{'); /* push function parameters */ @@ -4811,8 +4807,26 @@ decl_list_end: function_parameter_t *parameters = NULL; function_parameter_t **anchor = ¶meters; + /* did we have an earlier prototype? */ + entity_t *proto_type = get_entity(entity->base.symbol, NAMESPACE_NORMAL); + if (proto_type != NULL && proto_type->kind != ENTITY_FUNCTION) + proto_type = NULL; + + function_parameter_t *proto_parameter = NULL; + if (proto_type != NULL) { + type_t *proto_type_type = proto_type->declaration.type; + proto_parameter = proto_type_type->function.parameters; + } else { + /* §6.9.1.7: A K&R style parameter list does NOT act as a function + * prototype */ + new_type->function.unspecified_parameters = true; + } + + bool need_incompatible_warning = false; parameter = entity->function.parameters.entities; - for (; parameter != NULL; parameter = parameter->base.next) { + for (; parameter != NULL; parameter = parameter->base.next, + proto_parameter = + proto_parameter == NULL ? NULL : proto_parameter->next) { if (parameter->kind != ENTITY_PARAMETER) continue; @@ -4834,31 +4848,38 @@ decl_list_end: semantic_parameter_incomplete(parameter); - /* - * we need the default promoted types for the function type - */ - if (proto_type == NULL) - parameter_type = get_default_promoted_type(parameter_type); + /* we need the default promoted types for the function type */ + type_t *promoted = get_default_promoted_type(parameter_type); - function_parameter_t *const parameter = - allocate_parameter(parameter_type); + /* gcc special: if the type of the prototype matches the unpromoted + * type don't promote */ + if (!strict_mode && proto_parameter != NULL + && !types_compatible(proto_parameter->type, promoted) + && types_compatible(proto_parameter->type, parameter_type)) { + /* don't promote */ + need_incompatible_warning = true; + } else { + parameter_type = promoted; + } + function_parameter_t *const parameter + = allocate_parameter(parameter_type); *anchor = parameter; anchor = ¶meter->next; } new_type->function.parameters = parameters; - if (proto_type != NULL) { - /* compatibility with the prototype will be checked later ... */ - new_type->function.prototyped = true; - } else { - /* §6.9.1.7: A K&R style parameter list does NOT act as a function - * prototype */ - new_type->function.unspecified_parameters = true; - } - new_type = identify_new_type(new_type); + if (warning.other && need_incompatible_warning) { + type_t *proto_type_type = proto_type->declaration.type; + warningf(HERE, + "declaration '%#T' is incompatible with '%#T' (declared %P)", + proto_type_type, proto_type->base.symbol, + new_type, entity->base.symbol, + &proto_type->base.source_position); + } + entity->declaration.type = new_type; rem_anchor_token('{'); @@ -5680,8 +5701,7 @@ static void parse_external_declaration(void) /* §6.7.5.3:14 a function definition with () means no * parameters (and not unspecified parameters) */ if (type->function.unspecified_parameters && - type->function.parameters == NULL && - !type->function.kr_style_parameters) { + type->function.parameters == NULL) { type_t *copy = duplicate_type(type); copy->function.unspecified_parameters = false; type = identify_new_type(copy); diff --git a/type_t.h b/type_t.h index 2efe6b7..fb03da9 100644 --- a/type_t.h +++ b/type_t.h @@ -144,7 +144,6 @@ struct function_type_t { bool variadic : 1; bool unspecified_parameters : 1; bool kr_style_parameters : 1; - bool prototyped : 1; }; struct compound_type_t { -- 2.20.1