Print \n after $invalid statement$.
[cparser] / parser.c
index 7bfb77f..1ccaffa 100644 (file)
--- 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("<anonymous>");
+
        if (c_mode & _MS) {
                /* add predefined symbols for extended-decl-modifier */
                sym_align      = symbol_table_insert("align");