X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=parser.c;h=37190b014b901a84f7f75dd8c718dd5d49f80773;hb=f7f1fcc7021a3c622316b6415c16f83d0a64ae4a;hp=d07dd21d880917c20957036d9de1251948c87bc5;hpb=f894ab556ac1b28843b78f95de1ee399574408fd;p=cparser diff --git a/parser.c b/parser.c index d07dd21..37190b0 100644 --- a/parser.c +++ b/parser.c @@ -1833,11 +1833,10 @@ static void descend_into_subtype(type_path_t *path) top->type = top_type; if (is_type_compound(top_type)) { - compound_t *compound = top_type->compound.compound; - entity_t *entry = compound->members.entities; + compound_t *const compound = top_type->compound.compound; + entity_t *const entry = skip_unnamed_bitfields(compound->members.entities); if (entry != NULL) { - assert(entry->kind == ENTITY_COMPOUND_MEMBER); top->v.compound_entry = &entry->declaration; path->top_type = entry->declaration.type; } else { @@ -1977,7 +1976,7 @@ static void advance_current_object(type_path_t *path, size_t top_path_level) } else if (is_type_struct(type)) { declaration_t *entry = top->v.compound_entry; - entity_t *next_entity = entry->base.next; + entity_t *const next_entity = skip_unnamed_bitfields(entry->base.next); if (next_entity != NULL) { assert(is_declaration(next_entity)); entry = &next_entity->declaration; @@ -4105,8 +4104,15 @@ entity_t *record_entity(entity_t *entity, const bool is_definition) goto finish; } if (previous_entity->kind == ENTITY_TYPEDEF) { - /* TODO: C++ allows this for exactly the same type */ - errorf(pos, "redefinition of '%N' (declared %P)", entity, ppos); + type_t *const type = skip_typeref(entity->typedefe.type); + type_t *const prev_type + = skip_typeref(previous_entity->typedefe.type); + /* gcc extension redef in system headers is allowed */ + if ((!(c_mode & _CXX) && !pos->is_system_header) + || !types_compatible(type, prev_type)) { + errorf(pos, "redefinition of '%N' (declared %P)", + entity, ppos); + } goto finish; } @@ -4186,7 +4192,7 @@ warn_redundant_declaration: ; merge_in_attributes(decl, prev_decl->attributes); } else if (!is_definition && is_type_valid(prev_type) && - strcmp(ppos->input_name, "") != 0) { + !pos->is_system_header) { warningf(WARN_REDUNDANT_DECLS, pos, "redundant declaration for '%Y' (declared %P)", symbol, ppos); } } else if (current_function == NULL) { @@ -6187,7 +6193,8 @@ static entity_t *parse_qualified_identifier(void) if (entity == NULL) { if (!strict_mode && token.kind == '(') { /* an implicitly declared function */ - warningf(WARN_IMPLICIT_FUNCTION_DECLARATION, &pos, "implicit declaration of function '%Y'", symbol); + warningf(WARN_IMPLICIT_FUNCTION_DECLARATION, &pos, + "implicit declaration of function '%Y'", symbol); entity = create_implicit_function(symbol, &pos); } else { errorf(&pos, "unknown identifier '%Y' found.", symbol); @@ -7193,32 +7200,25 @@ static void check_call_argument(type_t *expected_type, /** * Handle the semantic restrictions of builtin calls */ -static void handle_builtin_argument_restrictions(call_expression_t *call) { - switch (call->function->reference.entity->function.btk) { - case bk_gnu_builtin_return_address: - case bk_gnu_builtin_frame_address: { +static void handle_builtin_argument_restrictions(call_expression_t *call) +{ + entity_t *entity = call->function->reference.entity; + switch (entity->function.btk) { + case BUILTIN_FIRM: + switch (entity->function.b.firm_builtin_kind) { + case ir_bk_return_address: + case ir_bk_frame_address: { /* argument must be constant */ call_argument_t *argument = call->arguments; if (is_constant_expression(argument->expression) == EXPR_CLASS_VARIABLE) { errorf(&call->base.source_position, - "argument of '%Y' must be a constant expression", - call->function->reference.entity->base.symbol); - } - break; - } - case bk_gnu_builtin_object_size: - if (call->arguments == NULL) - break; - - call_argument_t *arg = call->arguments->next; - if (arg != NULL && is_constant_expression(arg->expression) == EXPR_CLASS_VARIABLE) { - errorf(&call->base.source_position, - "second argument of '%Y' must be a constant expression", + "argument of '%Y' must be a constant expression", call->function->reference.entity->base.symbol); } break; - case bk_gnu_builtin_prefetch: + } + case ir_bk_prefetch: /* second and third argument must be constant if existent */ if (call->arguments == NULL) break; @@ -7228,22 +7228,37 @@ static void handle_builtin_argument_restrictions(call_expression_t *call) { if (rw != NULL) { if (is_constant_expression(rw->expression) == EXPR_CLASS_VARIABLE) { errorf(&call->base.source_position, - "second argument of '%Y' must be a constant expression", - call->function->reference.entity->base.symbol); + "second argument of '%Y' must be a constant expression", + call->function->reference.entity->base.symbol); } locality = rw->next; } if (locality != NULL) { if (is_constant_expression(locality->expression) == EXPR_CLASS_VARIABLE) { errorf(&call->base.source_position, - "third argument of '%Y' must be a constant expression", - call->function->reference.entity->base.symbol); + "third argument of '%Y' must be a constant expression", + call->function->reference.entity->base.symbol); } locality = rw->next; } break; default: break; + } + + case BUILTIN_OBJECT_SIZE: + if (call->arguments == NULL) + break; + + call_argument_t *arg = call->arguments->next; + if (arg != NULL && is_constant_expression(arg->expression) == EXPR_CLASS_VARIABLE) { + errorf(&call->base.source_position, + "second argument of '%Y' must be a constant expression", + call->function->reference.entity->base.symbol); + } + break; + default: + break; } } @@ -7339,7 +7354,7 @@ static expression_t *parse_call_expression(expression_t *expression) if (expression->kind == EXPR_REFERENCE) { reference_expression_t *reference = &expression->reference; if (reference->entity->kind == ENTITY_FUNCTION && - reference->entity->function.btk != bk_none) + reference->entity->function.btk != BUILTIN_NONE) handle_builtin_argument_restrictions(call); }