Do not change the local prev_type in record_entity(). The warning about missing...
[cparser] / parser.c
index 9d527dc..2a8f269 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -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];
 }
@@ -5095,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,
@@ -5114,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:
@@ -5150,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 &&
@@ -5354,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;
        }
@@ -8874,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);
 }
@@ -10079,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;
@@ -11360,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);