diff options
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 116 |
1 files changed, 57 insertions, 59 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 6d7900d..e99aeb4 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -3004,9 +3004,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) { SET_TYPE_ALIGN (gnu_type, 0); - /* If a type needs strict alignment, the minimum size will be the - type size instead of the RM size (see validate_size). Cap the - alignment lest it causes this type size to become too large. */ + /* If a type needs strict alignment, then its type size will also + be the RM size (see below). Cap the alignment if needed, lest + it may cause this type size to become too large. */ if (Strict_Alignment (gnat_entity) && Known_RM_Size (gnat_entity)) { unsigned int max_size = UI_To_Int (RM_Size (gnat_entity)); @@ -3283,6 +3283,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) compute_record_mode (gnu_type); } + /* If the type needs strict alignment, then no object of the type + may have a size smaller than the natural size, which means that + the RM size of the type is equal to the type size. */ + if (Strict_Alignment (gnat_entity)) + SET_TYPE_ADA_SIZE (gnu_type, TYPE_SIZE (gnu_type)); + /* If there are entities in the chain corresponding to components that we did not elaborate, ensure we elaborate their types if they are Itypes. */ @@ -4187,7 +4193,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) already defined so we cannot pass true for IN_PLACE here. */ process_attributes (&gnu_type, &attr_list, false, gnat_entity); - /* ??? Don't set the size for a String_Literal since it is either + /* See if a size was specified, by means of either an Object_Size or + a regular Size clause, and validate it if so. + + ??? Don't set the size for a String_Literal since it is either confirming or we don't handle it properly (if the low bound is non-constant). */ if (!gnu_size && kind != E_String_Literal_Subtype) @@ -4309,49 +4318,44 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) /* If we are just annotating types and the type is tagged, the tag and the parent components are not generated by the front-end so - alignment and sizes must be adjusted if there is no rep clause. */ - if (type_annotate_only - && Is_Tagged_Type (gnat_entity) - && Unknown_RM_Size (gnat_entity) - && !VOID_TYPE_P (gnu_type) - && (!TYPE_FIELDS (gnu_type) - || integer_zerop (bit_position (TYPE_FIELDS (gnu_type))))) + alignment and sizes must be adjusted. */ + if (type_annotate_only && Is_Tagged_Type (gnat_entity)) { - tree offset; - - if (Is_Derived_Type (gnat_entity)) - { - Entity_Id gnat_parent = Etype (Base_Type (gnat_entity)); - offset = UI_To_gnu (Esize (gnat_parent), bitsizetype); - Set_Alignment (gnat_entity, Alignment (gnat_parent)); - } - else + const bool derived_p = Is_Derived_Type (gnat_entity); + const Entity_Id gnat_parent + = derived_p ? Etype (Base_Type (gnat_entity)) : Empty; + const unsigned int inherited_align + = derived_p + ? UI_To_Int (Alignment (gnat_parent)) * BITS_PER_UNIT + : POINTER_SIZE; + const unsigned int align + = MAX (TYPE_ALIGN (gnu_type), inherited_align); + + Set_Alignment (gnat_entity, UI_From_Int (align / BITS_PER_UNIT)); + + /* If there is neither size clause nor representation clause, the + sizes need to be adjusted. */ + if (Unknown_RM_Size (gnat_entity) + && !VOID_TYPE_P (gnu_type) + && (!TYPE_FIELDS (gnu_type) + || integer_zerop (bit_position (TYPE_FIELDS (gnu_type))))) { - unsigned int align - = MAX (TYPE_ALIGN (gnu_type), POINTER_SIZE) / BITS_PER_UNIT; - offset = bitsize_int (POINTER_SIZE); - Set_Alignment (gnat_entity, UI_From_Int (align)); + tree offset + = derived_p + ? UI_To_gnu (Esize (gnat_parent), bitsizetype) + : bitsize_int (POINTER_SIZE); + if (TYPE_FIELDS (gnu_type)) + offset + = round_up (offset, DECL_ALIGN (TYPE_FIELDS (gnu_type))); + gnu_size = size_binop (PLUS_EXPR, gnu_size, offset); } - if (TYPE_FIELDS (gnu_type)) - offset - = round_up (offset, DECL_ALIGN (TYPE_FIELDS (gnu_type))); - - gnu_size = size_binop (PLUS_EXPR, gnu_size, offset); - gnu_size = round_up (gnu_size, POINTER_SIZE); - Uint uint_size = annotate_value (gnu_size); - Set_RM_Size (gnat_entity, uint_size); - Set_Esize (gnat_entity, uint_size); - } - - /* If there is a rep clause, only adjust alignment and Esize. */ - else if (type_annotate_only && Is_Tagged_Type (gnat_entity)) - { - unsigned int align - = MAX (TYPE_ALIGN (gnu_type), POINTER_SIZE) / BITS_PER_UNIT; - Set_Alignment (gnat_entity, UI_From_Int (align)); - gnu_size = round_up (gnu_size, POINTER_SIZE); + gnu_size = round_up (gnu_size, align); Set_Esize (gnat_entity, annotate_value (gnu_size)); + + /* Tagged types are Strict_Alignment so RM_Size = Esize. */ + if (Unknown_RM_Size (gnat_entity)) + Set_RM_Size (gnat_entity, Esize (gnat_entity)); } /* Otherwise no adjustment is needed. */ @@ -8732,7 +8736,7 @@ validate_size (Uint uint_size, tree gnu_type, Entity_Id gnat_object, enum tree_code kind, bool component_p, bool zero_ok) { Node_Id gnat_error_node; - tree type_size, size; + tree old_size, size; /* Return 0 if no size was specified. */ if (uint_size == No_Uint) @@ -8797,17 +8801,11 @@ validate_size (Uint uint_size, tree gnu_type, Entity_Id gnat_object, && TYPE_CONTAINS_TEMPLATE_P (gnu_type)) size = size_binop (PLUS_EXPR, DECL_SIZE (TYPE_FIELDS (gnu_type)), size); - if (kind == VAR_DECL - /* If a type needs strict alignment, a component of this type in - a packed record cannot be packed and thus uses the type size. */ - || (kind == TYPE_DECL && Strict_Alignment (gnat_object))) - type_size = TYPE_SIZE (gnu_type); - else - type_size = rm_size (gnu_type); + old_size = (kind == VAR_DECL ? TYPE_SIZE (gnu_type) : rm_size (gnu_type)); - /* Modify the size of a discriminated type to be the maximum size. */ - if (type_size && CONTAINS_PLACEHOLDER_P (type_size)) - type_size = max_size (type_size, true); + /* If the old size is self-referential, get the maximum size. */ + if (CONTAINS_PLACEHOLDER_P (old_size)) + old_size = max_size (old_size, true); /* If this is an access type or a fat pointer, the minimum size is that given by the smallest integral mode that's valid for pointers. */ @@ -8816,23 +8814,23 @@ validate_size (Uint uint_size, tree gnu_type, Entity_Id gnat_object, scalar_int_mode p_mode = NARROWEST_INT_MODE; while (!targetm.valid_pointer_mode (p_mode)) p_mode = GET_MODE_WIDER_MODE (p_mode).require (); - type_size = bitsize_int (GET_MODE_BITSIZE (p_mode)); + old_size = bitsize_int (GET_MODE_BITSIZE (p_mode)); } /* Issue an error either if the default size of the object isn't a constant or if the new size is smaller than it. */ - if (TREE_CODE (type_size) != INTEGER_CST - || TREE_OVERFLOW (type_size) - || tree_int_cst_lt (size, type_size)) + if (TREE_CODE (old_size) != INTEGER_CST + || TREE_OVERFLOW (old_size) + || tree_int_cst_lt (size, old_size)) { if (component_p) post_error_ne_tree ("component size for& too small{, minimum allowed is ^}", - gnat_error_node, gnat_object, type_size); + gnat_error_node, gnat_object, old_size); else post_error_ne_tree ("size for& too small{, minimum allowed is ^}", - gnat_error_node, gnat_object, type_size); + gnat_error_node, gnat_object, old_size); return NULL_TREE; } |