From: Matthias Braun Date: Mon, 2 Jun 2008 20:25:34 +0000 (+0000) Subject: fix kr2.c X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=412b79e2cac1e0e0682906c0f49e31eb6feab5b7;p=cparser fix kr2.c [r19947] --- diff --git a/ast2firm.c b/ast2firm.c index 9ba1227..f824251 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -357,7 +357,7 @@ static ir_type *create_method_type(const function_type_t *function_type) ++n; } - if(function_type->variadic || function_type->unspecified_parameters) { + if(function_type->variadic) { set_method_variadicity(irtype, variadicity_variadic); } diff --git a/parser.c b/parser.c index af9b0a0..79122e5 100644 --- a/parser.c +++ b/parser.c @@ -3834,101 +3834,97 @@ static declaration_t *internal_record_declaration( } assert(declaration != previous_declaration); - if (previous_declaration != NULL) { - if (previous_declaration->parent_scope == scope) { - /* can happen for K&R style declarations */ - if(previous_declaration->type == NULL) { - previous_declaration->type = declaration->type; - } - - const type_t *prev_type = skip_typeref(previous_declaration->type); - if (!types_compatible(type, prev_type)) { + if (previous_declaration != NULL + && previous_declaration->parent_scope == scope) { + /* can happen for K&R style declarations */ + if (previous_declaration->type == NULL) { + previous_declaration->type = declaration->type; + } + + const type_t *prev_type = skip_typeref(previous_declaration->type); + if (!types_compatible(type, prev_type)) { + errorf(&declaration->source_position, + "declaration '%#T' is incompatible with '%#T' (declared %P)", + orig_type, symbol, previous_declaration->type, symbol, + &previous_declaration->source_position); + } else { + unsigned old_storage_class = previous_declaration->storage_class; + if (old_storage_class == STORAGE_CLASS_ENUM_ENTRY) { errorf(&declaration->source_position, - "declaration '%#T' is incompatible with '%#T' (declared %P)", - orig_type, symbol, previous_declaration->type, symbol, - &previous_declaration->source_position); - } else { - unsigned old_storage_class = previous_declaration->storage_class; - if(old_storage_class == STORAGE_CLASS_ENUM_ENTRY) { - errorf(&declaration->source_position, - "redeclaration of enum entry '%Y' (declared %P)", - symbol, &previous_declaration->source_position); - return previous_declaration; - } + "redeclaration of enum entry '%Y' (declared %P)", + symbol, &previous_declaration->source_position); + return previous_declaration; + } - unsigned new_storage_class = declaration->storage_class; + unsigned new_storage_class = declaration->storage_class; - if(is_type_incomplete(prev_type)) { - previous_declaration->type = type; - prev_type = type; - } + if (is_type_incomplete(prev_type)) { + previous_declaration->type = type; + prev_type = type; + } - /* pretend no storage class means extern for function - * declarations (except if the previous declaration is neither - * none nor extern) */ - if (is_type_function(type)) { - switch (old_storage_class) { - case STORAGE_CLASS_NONE: - old_storage_class = STORAGE_CLASS_EXTERN; - - case STORAGE_CLASS_EXTERN: - if (is_function_definition) { - if (warning.missing_prototypes && - prev_type->function.unspecified_parameters && - !is_sym_main(symbol)) { - warningf(&declaration->source_position, - "no previous prototype for '%#T'", - orig_type, symbol); - } - } else if (new_storage_class == STORAGE_CLASS_NONE) { - new_storage_class = STORAGE_CLASS_EXTERN; - } - break; - - default: break; + /* pretend no storage class means extern for function + * declarations (except if the previous declaration is neither + * none nor extern) */ + if (is_type_function(type)) { + switch (old_storage_class) { + case STORAGE_CLASS_NONE: + old_storage_class = STORAGE_CLASS_EXTERN; + + case STORAGE_CLASS_EXTERN: + if (is_function_definition) { + if (warning.missing_prototypes && + prev_type->function.unspecified_parameters && + !is_sym_main(symbol)) { + warningf(&declaration->source_position, + "no previous prototype for '%#T'", + orig_type, symbol); + } + } else if (new_storage_class == STORAGE_CLASS_NONE) { + new_storage_class = STORAGE_CLASS_EXTERN; } + break; + + default: + break; } + } - if (old_storage_class == STORAGE_CLASS_EXTERN && - new_storage_class == STORAGE_CLASS_EXTERN) { + if (old_storage_class == STORAGE_CLASS_EXTERN && + new_storage_class == STORAGE_CLASS_EXTERN) { warn_redundant_declaration: - if (warning.redundant_decls) { - warningf(&declaration->source_position, - "redundant declaration for '%Y' (declared %P)", - symbol, &previous_declaration->source_position); - } - } else if (current_function == NULL) { - if (old_storage_class != STORAGE_CLASS_STATIC && - new_storage_class == STORAGE_CLASS_STATIC) { - errorf(&declaration->source_position, - "static declaration of '%Y' follows non-static declaration (declared %P)", - symbol, &previous_declaration->source_position); - } else { - if (old_storage_class != STORAGE_CLASS_EXTERN && !is_function_definition) { - goto warn_redundant_declaration; - } - if (new_storage_class == STORAGE_CLASS_NONE) { - previous_declaration->storage_class = STORAGE_CLASS_NONE; - previous_declaration->declared_storage_class = STORAGE_CLASS_NONE; - } - } - } else { - if (old_storage_class == new_storage_class) { - errorf(&declaration->source_position, - "redeclaration of '%Y' (declared %P)", - symbol, &previous_declaration->source_position); - } else { - errorf(&declaration->source_position, - "redeclaration of '%Y' with different linkage (declared %P)", - symbol, &previous_declaration->source_position); - } + if (warning.redundant_decls) { + warningf(&declaration->source_position, + "redundant declaration for '%Y' (declared %P)", + symbol, &previous_declaration->source_position); } + } else if (current_function == NULL) { + if (old_storage_class != STORAGE_CLASS_STATIC && + new_storage_class == STORAGE_CLASS_STATIC) { + errorf(&declaration->source_position, + "static declaration of '%Y' follows non-static declaration (declared %P)", + symbol, &previous_declaration->source_position); + } else if (old_storage_class != STORAGE_CLASS_EXTERN + && !is_function_definition) { + goto warn_redundant_declaration; + } else if (new_storage_class == STORAGE_CLASS_NONE) { + previous_declaration->storage_class = STORAGE_CLASS_NONE; + previous_declaration->declared_storage_class = STORAGE_CLASS_NONE; + } + } else if (old_storage_class == new_storage_class) { + errorf(&declaration->source_position, + "redeclaration of '%Y' (declared %P)", + symbol, &previous_declaration->source_position); + } else { + errorf(&declaration->source_position, + "redeclaration of '%Y' with different linkage (declared %P)", + symbol, &previous_declaration->source_position); } - - if (declaration->is_inline) - previous_declaration->is_inline = true; - return previous_declaration; } + + if (declaration->is_inline) + previous_declaration->is_inline = true; + return previous_declaration; } else if (is_function_definition) { if (declaration->storage_class != STORAGE_CLASS_STATIC) { if (warning.missing_prototypes && !is_sym_main(symbol)) { diff --git a/parsetest/kr2.c b/parsetest/kr2.c index 8dad25a..2854a8b 100644 --- a/parsetest/kr2.c +++ b/parsetest/kr2.c @@ -1,6 +1,6 @@ int printf(const char *str, ...); -int a(int first, float second, const char *third); +static int a(int first, float second, const char *third); int main(void) { @@ -8,7 +8,7 @@ int main(void) return 0; } -int a(first, second, third) +static int a(first, second, third) float second; const char *third; int first; diff --git a/type.c b/type.c index b595215..ac34d3d 100644 --- a/type.c +++ b/type.c @@ -861,11 +861,6 @@ bool is_type_incomplete(const type_t *type) declaration_t *declaration = enum_type->declaration; return !declaration->init.complete; } - case TYPE_BITFIELD: - return false; - - case TYPE_FUNCTION: - return true; case TYPE_ARRAY: return type->array.size_expression == NULL @@ -880,6 +875,8 @@ bool is_type_incomplete(const type_t *type) case TYPE_IMAGINARY: return type->imaginary.akind == ATOMIC_TYPE_VOID; + case TYPE_BITFIELD: + case TYPE_FUNCTION: case TYPE_POINTER: case TYPE_BUILTIN: case TYPE_ERROR: @@ -907,10 +904,10 @@ static bool function_types_compatible(const function_type_t *func1, return false; /* can parameters be compared? */ - if(func1->unspecified_parameters || func2->unspecified_parameters) + if (func1->unspecified_parameters || func2->unspecified_parameters) return true; - if(func1->variadic != func2->variadic) + if (func1->variadic != func2->variadic) return false; /* TODO: handling of unspecified parameters not correct yet */ @@ -918,7 +915,7 @@ static bool function_types_compatible(const function_type_t *func1, /* all argument types must be compatible */ function_parameter_t *parameter1 = func1->parameters; function_parameter_t *parameter2 = func2->parameters; - for( ; parameter1 != NULL && parameter2 != NULL; + for ( ; parameter1 != NULL && parameter2 != NULL; parameter1 = parameter1->next, parameter2 = parameter2->next) { type_t *parameter1_type = skip_typeref(parameter1->type); type_t *parameter2_type = skip_typeref(parameter2->type); @@ -926,11 +923,11 @@ static bool function_types_compatible(const function_type_t *func1, parameter1_type = get_unqualified_type(parameter1_type); parameter2_type = get_unqualified_type(parameter2_type); - if(!types_compatible(parameter1_type, parameter2_type)) + if (!types_compatible(parameter1_type, parameter2_type)) return false; } /* same number of arguments? */ - if(parameter1 != NULL || parameter2 != NULL) + if (parameter1 != NULL || parameter2 != NULL) return false; return true;