Add get_qualified_type() and solve several problem with missing qualifiers, which...
authorChristoph Mallon <christoph.mallon@gmx.de>
Sat, 13 Sep 2008 12:33:42 +0000 (12:33 +0000)
committerChristoph Mallon <christoph.mallon@gmx.de>
Sat, 13 Sep 2008 12:33:42 +0000 (12:33 +0000)
[r21928]

parser.c
type.c
type.h

index 299abac..ffc742f 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -5848,7 +5848,10 @@ type_t *revert_automatic_type_conversion(const expression_t *expression)
 {
        switch (expression->kind) {
                case EXPR_REFERENCE: return expression->reference.declaration->type;
-               case EXPR_SELECT:    return expression->select.compound_entry->type;
+
+               case EXPR_SELECT:
+                       return get_qualified_type(expression->select.compound_entry->type,
+                                                 expression->base.type->base.qualifiers);
 
                case EXPR_UNARY_DEREFERENCE: {
                        const expression_t *const value = expression->unary.value;
@@ -6793,16 +6796,8 @@ create_error_entry:
 
        select->select.compound_entry = entry;
 
-       type_t            *res_type = entry->type;
-       type_qualifiers_t  qual     = type_left->base.qualifiers;
-       if (qual != 0) {
-               type_t *const copy = duplicate_type(res_type);
-               copy->base.qualifiers |= qual;
-
-               res_type = typehash_insert(copy);
-               if (type != copy)
-                       free_type(copy);
-       }
+       type_t *const res_type =
+               get_qualified_type(entry->type, type_left->base.qualifiers);
 
        /* we always do the auto-type conversions; the & and sizeof parser contains
         * code to revert this! */
@@ -7095,13 +7090,8 @@ static expression_t *parse_conditional_expression(unsigned precedence,
                                to = type_void;
                        }
 
-                       type_t *const copy = duplicate_type(to);
-                       copy->base.qualifiers = to1->base.qualifiers | to2->base.qualifiers;
-
-                       type_t *const type = typehash_insert(copy);
-                       if (type != copy)
-                               free_type(copy);
-
+                       type_t *const type =
+                               get_qualified_type(to, to1->base.qualifiers | to2->base.qualifiers);
                        result_type = make_pointer_type(type, TYPE_QUALIFIER_NONE);
                } else if (is_type_integer(other_type)) {
                        warningf(&conditional->base.source_position,
diff --git a/type.c b/type.c
index f5a98e1..2a9aba5 100644 (file)
--- a/type.c
+++ b/type.c
@@ -761,6 +761,36 @@ type_t *get_unqualified_type(type_t *type)
        return result;
 }
 
+type_t *get_qualified_type(type_t *type, type_qualifiers_t const qual)
+{
+       assert(!is_typeref(type));
+
+       type_t *copy;
+       if (is_type_array(type)) {
+               /* For array types the element type has to be adjusted */
+               type_t *element_type      = type->array.element_type;
+               type_t *qual_element_type = get_qualified_type(element_type, qual);
+
+               if (qual_element_type == element_type)
+                       return type;
+
+               copy                     = duplicate_type(type);
+               copy->array.element_type = qual_element_type;
+       } else {
+               if ((type->base.qualifiers & qual) == qual)
+                       return type;
+
+               copy                   = duplicate_type(type);
+               copy->base.qualifiers |= qual;
+       }
+
+       type = typehash_insert(copy);
+       if (type != copy)
+               obstack_free(type_obst, copy);
+
+       return type;
+}
+
 /**
  * Check if a type is valid.
  *
diff --git a/type.h b/type.h
index fd039a7..2dba894 100644 (file)
--- a/type.h
+++ b/type.h
@@ -162,6 +162,7 @@ bool is_type_object(const type_t *type);
 bool types_compatible(const type_t *type1, const type_t *type2);
 
 type_t *get_unqualified_type(type_t *type);
+type_t *get_qualified_type(type_t*, type_qualifiers_t);
 type_t *skip_typeref(type_t *type);
 
 /**