X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=parser.c;h=1ccaffa3625d2fba62ba1ac93cb871fa4f31c230;hb=af5549239a48c4a63fb1e591f10731151df80e0f;hp=7bfb77fd813fc93f3a425f12e49f6f065f694b50;hpb=2322197e2feedc950e3aa0e7fd9fc38ad9fd7971;p=cparser diff --git a/parser.c b/parser.c index 7bfb77f..1ccaffa 100644 --- a/parser.c +++ b/parser.c @@ -134,6 +134,9 @@ static struct obstack temp_obst; static source_position_t null_position = { NULL, 0 }; +/** special symbol used for anonymous entities. */ +static const symbol_t *sym_anonymous = NULL; + /* symbols for Microsoft extended-decl-modifier */ static const symbol_t *sym_align = NULL; static const symbol_t *sym_allocate = NULL; @@ -3129,33 +3132,38 @@ static void finish_struct_type(compound_type_t *type) { if (! struct_decl->init.complete) return; - il_size_t size = 0; - il_size_t new_size; - il_alignment_t alignment = 1; - bool need_pad = false; + il_size_t size = 0; + il_size_t offset; + il_alignment_t alignment = 1; + bool need_pad = false; declaration_t *entry = struct_decl->scope.declarations; for (; entry != NULL; entry = entry->next) { if (entry->namespc != NAMESPACE_NORMAL) continue; - type_t *m_type = skip_typeref(entry->type); - il_alignment_t m_alignment = m_type->base.alignment; - - new_size = (size + m_alignment - 1) & -m_alignment; + type_t *m_type = skip_typeref(entry->type); + if (! is_type_valid(m_type)) { + /* simply ignore errors here */ + continue; + } + il_alignment_t m_alignment = m_type->base.alignment; if (m_alignment > alignment) alignment = m_alignment; - if (new_size > size) + + offset = (size + m_alignment - 1) & -m_alignment; + + if (offset > size) need_pad = true; - entry->offset = new_size; - size = new_size + m_type->base.size; + entry->offset = offset; + size = offset + m_type->base.size; } if (type->base.alignment != 0) { alignment = type->base.alignment; } - new_size = (size + alignment - 1) & -alignment; - if (new_size > size) + offset = (size + alignment - 1) & -alignment; + if (offset > size) need_pad = true; if (warning.padded && need_pad) { @@ -3168,7 +3176,7 @@ static void finish_struct_type(compound_type_t *type) { type, struct_decl->symbol); } - type->base.size = new_size; + type->base.size = offset; type->base.alignment = alignment; } @@ -3192,6 +3200,8 @@ static void finish_union_type(compound_type_t *type) { continue; type_t *m_type = skip_typeref(entry->type); + if (! is_type_valid(m_type)) + continue; entry->offset = 0; if (m_type->base.size > size) @@ -5511,12 +5521,40 @@ static void parse_external_declaration(void) } static type_t *make_bitfield_type(type_t *base_type, expression_t *size, - source_position_t *source_position) + source_position_t *source_position, + const symbol_t *symbol) { type_t *type = allocate_type_zero(TYPE_BITFIELD, source_position); - type->bitfield.base_type = base_type; - type->bitfield.size = size; + type->bitfield.base_type = base_type; + type->bitfield.size_expression = size; + + il_size_t bit_size; + type_t *skipped_type = skip_typeref(base_type); + if (!is_type_integer(skipped_type)) { + errorf(HERE, "bitfield base type '%T' is not an integer type", + base_type); + bit_size = 0; + } else { + bit_size = skipped_type->base.size * 8; + } + + if (is_constant_expression(size)) { + long v = fold_constant(size); + + if (v < 0) { + errorf(source_position, "negative width in bit-field '%Y'", + symbol); + } else if (v == 0) { + errorf(source_position, "zero width for bit-field '%Y'", + symbol); + } else if (bit_size > 0 && (il_size_t)v > bit_size) { + errorf(source_position, "width of '%Y' exceeds its type", + symbol); + } else { + type->bitfield.bit_size = v; + } + } return type; } @@ -5568,12 +5606,8 @@ static void parse_compound_declarators(declaration_t *struct_declaration, type_t *base_type = specifiers->type; expression_t *size = parse_constant_expression(); - if (!is_type_integer(skip_typeref(base_type))) { - errorf(HERE, "bitfield base type '%T' is not an integer type", - base_type); - } - - type_t *type = make_bitfield_type(base_type, size, &source_position); + type_t *type = make_bitfield_type(base_type, size, + &source_position, sym_anonymous); declaration = allocate_declaration_zero(); declaration->namespc = NAMESPACE_NORMAL; @@ -5593,12 +5627,8 @@ static void parse_compound_declarators(declaration_t *struct_declaration, next_token(); expression_t *size = parse_constant_expression(); - if (!is_type_integer(type)) { - errorf(HERE, "bitfield base type '%T' is not an integer type", - orig_type); - } - - type_t *bitfield_type = make_bitfield_type(orig_type, size, &source_position); + type_t *bitfield_type = make_bitfield_type(orig_type, size, + &source_position, declaration->symbol); declaration->type = bitfield_type; } else { /* TODO we ignore arrays for now... what is missing is a check @@ -6050,11 +6080,9 @@ static expression_t *parse_reference(void) declaration_t *declaration = get_declaration(symbol, NAMESPACE_NORMAL); if (declaration == NULL) { - if (look_ahead(1)->type == '(') { + if (!strict_mode && look_ahead(1)->type == '(') { /* an implicitly declared function */ - if (strict_mode) { - errorf(HERE, "unknown symbol '%Y' found.", symbol); - } else if (warning.implicit_function_declaration) { + if (warning.implicit_function_declaration) { warningf(HERE, "implicit declaration of function '%Y'", symbol); } @@ -7597,6 +7625,9 @@ static type_t *semantic_arithmetic(type_t *type_left, type_t *type_right) { /* TODO: handle complex + imaginary types */ + type_left = get_unqualified_type(type_left); + type_right = get_unqualified_type(type_right); + /* § 6.3.1.8 Usual arithmetic conversions */ if (type_left == type_long_double || type_right == type_long_double) { return type_long_double; @@ -8651,7 +8682,7 @@ static statement_t *parse_case_statement(void) statement->case_label.last_case = val; if (val < statement->case_label.first_case) { - statement->case_label.is_empty = true; + statement->case_label.is_empty_range = true; warningf(pos, "empty range specified"); } } @@ -8667,7 +8698,7 @@ static statement_t *parse_case_statement(void) /* Check for duplicate case values */ case_label_statement_t *c = &statement->case_label; for (case_label_statement_t *l = current_switch->first_case; l != NULL; l = l->next) { - if (l->is_bad || l->is_empty || l->expression == NULL) + if (l->is_bad || l->is_empty_range || l->expression == NULL) continue; if (c->last_case < l->first_case || c->first_case > l->last_case) @@ -9818,6 +9849,8 @@ void parse(void) */ void init_parser(void) { + sym_anonymous = symbol_table_insert(""); + if (c_mode & _MS) { /* add predefined symbols for extended-decl-modifier */ sym_align = symbol_table_insert("align");