Do not change the local prev_type in record_entity(). The warning about missing...
[cparser] / parser.c
index fdc92cd..2a8f269 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -42,7 +42,7 @@
 #include "adt/array.h"
 
 //#define PRINT_TOKENS
-#define MAX_LOOKAHEAD 2
+#define MAX_LOOKAHEAD 1
 
 typedef struct {
        entity_t           *old_entity;
@@ -113,7 +113,7 @@ static token_t              token;
 /** The lookahead ring-buffer. */
 static token_t              lookahead_buffer[MAX_LOOKAHEAD];
 /** Position of the next token in the lookahead buffer. */
-static int                  lookahead_bufpos;
+static size_t               lookahead_bufpos;
 static stack_entry_t       *environment_stack = NULL;
 static stack_entry_t       *label_stack       = NULL;
 static scope_t             *file_scope        = NULL;
@@ -351,7 +351,7 @@ static size_t get_entity_struct_size(entity_kind_t kind)
                [ENTITY_LOCAL_LABEL]     = sizeof(label_t),
                [ENTITY_NAMESPACE]       = sizeof(namespace_t)
        };
-       assert(kind < sizeof(sizes) / sizeof(sizes[0]));
+       assert(kind < lengthof(sizes));
        assert(sizes[kind] != 0);
        return sizes[kind];
 }
@@ -396,7 +396,7 @@ static size_t get_statement_struct_size(statement_kind_t kind)
                [STATEMENT_MS_TRY]      = sizeof(ms_try_statement_t),
                [STATEMENT_LEAVE]       = sizeof(leave_statement_t)
        };
-       assert(kind < sizeof(sizes) / sizeof(sizes[0]));
+       assert(kind < lengthof(sizes));
        assert(sizes[kind] != 0);
        return sizes[kind];
 }
@@ -443,7 +443,7 @@ static size_t get_expression_struct_size(expression_kind_t kind)
        if (kind >= EXPR_BINARY_FIRST && kind <= EXPR_BINARY_LAST) {
                return sizes[EXPR_BINARY_FIRST];
        }
-       assert(kind < sizeof(sizes) / sizeof(sizes[0]));
+       assert(kind < lengthof(sizes));
        assert(sizes[kind] != 0);
        return sizes[kind];
 }
@@ -526,7 +526,7 @@ static size_t get_type_struct_size(type_kind_t kind)
                [TYPE_TYPEDEF]         = sizeof(typedef_type_t),
                [TYPE_TYPEOF]          = sizeof(typeof_type_t),
        };
-       assert(sizeof(sizes) / sizeof(sizes[0]) == (int) TYPE_TYPEOF + 1);
+       assert(lengthof(sizes) == (int)TYPE_TYPEOF + 1);
        assert(kind <= TYPE_TYPEOF);
        assert(sizes[kind] != 0);
        return sizes[kind];
@@ -562,7 +562,7 @@ static size_t get_initializer_size(initializer_kind_t kind)
                [INITIALIZER_LIST]        = sizeof(initializer_list_t),
                [INITIALIZER_DESIGNATOR]  = sizeof(initializer_designator_t)
        };
-       assert(kind < sizeof(sizes) / sizeof(*sizes));
+       assert(kind < lengthof(sizes));
        assert(sizes[kind] != 0);
        return sizes[kind];
 }
@@ -604,7 +604,7 @@ static inline void next_token(void)
        lookahead_buffer[lookahead_bufpos] = lexer_token;
        lexer_next_token();
 
-       lookahead_bufpos = (lookahead_bufpos+1) % MAX_LOOKAHEAD;
+       lookahead_bufpos = (lookahead_bufpos + 1) % MAX_LOOKAHEAD;
 
 #ifdef PRINT_TOKENS
        print_token(stderr, &token);
@@ -615,10 +615,10 @@ static inline void next_token(void)
 /**
  * Return the next token with a given lookahead.
  */
-static inline const token_t *look_ahead(int num)
+static inline const token_t *look_ahead(size_t num)
 {
-       assert(num > 0 && num <= MAX_LOOKAHEAD);
-       int pos = (lookahead_bufpos+num-1) % MAX_LOOKAHEAD;
+       assert(0 < num && num <= MAX_LOOKAHEAD);
+       size_t pos = (lookahead_bufpos + num - 1) % MAX_LOOKAHEAD;
        return &lookahead_buffer[pos];
 }
 
@@ -4089,7 +4089,11 @@ warn_about_long_long:
        type->base.qualifiers = qualifiers;
        type->base.modifiers  = modifiers;
 
-       type = identify_new_type(type);
+       if (newtype) {
+               type = identify_new_type(type);
+       } else {
+               type = typehash_insert(type);
+       }
 
        type = handle_type_attributes(specifiers->gnu_attributes, type);
        specifiers->type = type;
@@ -5091,7 +5095,7 @@ static entity_t *record_entity(entity_t *entity, const bool is_definition)
                type_t *const orig_type = decl->type;
                assert(orig_type != NULL);
                type_t *const type      = skip_typeref(orig_type);
-               type_t *      prev_type = skip_typeref(prev_decl->type);
+               type_t *const prev_type = skip_typeref(prev_decl->type);
 
                if (!types_compatible(type, prev_type)) {
                        errorf(pos,
@@ -5110,20 +5114,14 @@ static entity_t *record_entity(entity_t *entity, const bool is_definition)
                                         prev_decl->type, symbol);
                        }
 
-                       unsigned new_storage_class = decl->storage_class;
-                       if (is_type_incomplete(prev_type)) {
-                               prev_decl->type = type;
-                               prev_type       = type;
-                       }
+                       storage_class_tag_t new_storage_class = decl->storage_class;
 
                        /* pretend no storage class means extern for function
                         * declarations (except if the previous declaration is neither
                         * none nor extern) */
                        if (entity->kind == ENTITY_FUNCTION) {
-                               if (prev_type->function.unspecified_parameters) {
+                               if (prev_type->function.unspecified_parameters)
                                        prev_decl->type = type;
-                                       prev_type       = type;
-                               }
 
                                switch (old_storage_class) {
                                case STORAGE_CLASS_NONE:
@@ -5146,6 +5144,8 @@ static entity_t *record_entity(entity_t *entity, const bool is_definition)
                                default:
                                        break;
                                }
+                       } else if (is_type_incomplete(prev_type)) {
+                               prev_decl->type = type;
                        }
 
                        if (old_storage_class == STORAGE_CLASS_EXTERN &&
@@ -5350,11 +5350,9 @@ static void check_variable_type_complete(entity_t *ent)
        if (!is_type_incomplete(type))
                return;
 
-       /* GCC allows global arrays without size and assigns them a length of one,
-        * if no different declaration follows */
-       if (is_type_array(type) &&
-                       c_mode & _GNUC      &&
-                       ent->base.parent_scope == file_scope) {
+       /* §6.9.2:2 and §6.9.2:5: At the end of the translation incomplete arrays
+        * are given length one. */
+       if (is_type_array(type) && ent->base.parent_scope == file_scope) {
                ARR_APP1(declaration_t*, incomplete_arrays, decl);
                return;
        }
@@ -6093,7 +6091,7 @@ found_break_parent:
                if (next == NULL) {
                        noreturn_candidate = false;
 
-                       type_t *const type = current_function->base.type;
+                       type_t *const type = skip_typeref(current_function->base.type);
                        assert(is_type_function(type));
                        type_t *const ret  = skip_typeref(type->function.return_type);
                        if (warning.return_type                    &&
@@ -8870,7 +8868,8 @@ static void warn_div_by_zero(binary_expression_t const *const expression)
 /**
  * Check the semantic restrictions for a div/mod expression.
  */
-static void semantic_divmod_arithmetic(binary_expression_t *expression) {
+static void semantic_divmod_arithmetic(binary_expression_t *expression)
+{
        semantic_binexpr_arithmetic(expression);
        warn_div_by_zero(expression);
 }
@@ -10075,7 +10074,8 @@ end_error:
  *
  * @param statement  the switch statement to check
  */
-static void check_enum_cases(const switch_statement_t *statement) {
+static void check_enum_cases(const switch_statement_t *statement)
+{
        const type_t *type = skip_typeref(statement->expression->base.type);
        if (! is_type_enum(type))
                return;
@@ -11356,8 +11356,8 @@ translation_unit_t *finish_parsing(void)
        return result;
 }
 
-/* GCC allows global arrays without size and assigns them a length of one,
- * if no different declaration follows */
+/* §6.9.2:2 and §6.9.2:5: At the end of the translation incomplete arrays
+ * are given length one. */
 static void complete_incomplete_arrays(void)
 {
        size_t n = ARR_LEN(incomplete_arrays);