diff options
author | Ian Lance Taylor <iant@golang.org> | 2020-10-12 09:46:38 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2020-10-12 09:46:38 -0700 |
commit | 9cd320ea6572c577cdf17ce1f9ea5230b166af6d (patch) | |
tree | d1c8e7c2e09a91ed75f0e5476c648c2e745aa2de /gcc/ada/gcc-interface | |
parent | 4854d721be78358e59367982bdd94461b4be3c5a (diff) | |
parent | 3175d40fc52fb8eb3c3b18cc343d773da24434fb (diff) | |
download | gcc-9cd320ea6572c577cdf17ce1f9ea5230b166af6d.zip gcc-9cd320ea6572c577cdf17ce1f9ea5230b166af6d.tar.gz gcc-9cd320ea6572c577cdf17ce1f9ea5230b166af6d.tar.bz2 |
Merge from trunk revision 3175d40fc52fb8eb3c3b18cc343d773da24434fb.
Diffstat (limited to 'gcc/ada/gcc-interface')
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 75 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/gigi.h | 5 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/misc.c | 13 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/targtyps.c | 10 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/trans.c | 54 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils.c | 39 |
6 files changed, 150 insertions, 46 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 025714b..cd0a50b 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -232,7 +232,7 @@ static tree build_position_list (tree, bool, tree, tree, unsigned int, tree); static vec<subst_pair> build_subst_list (Entity_Id, Entity_Id, bool); static vec<variant_desc> build_variant_list (tree, Node_Id, vec<subst_pair>, vec<variant_desc>); -static tree maybe_saturate_size (tree); +static tree maybe_saturate_size (tree, unsigned int align); static tree validate_size (Uint, tree, Entity_Id, enum tree_code, bool, bool, const char *, const char *); static void set_rm_size (Uint, tree, Entity_Id); @@ -524,7 +524,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) else if (IN (kind, Access_Kind)) max_esize = POINTER_SIZE * 2; else - max_esize = LONG_LONG_TYPE_SIZE; + max_esize = Enable_128bit_Types ? 128 : LONG_LONG_TYPE_SIZE; if (esize > max_esize) esize = max_esize; @@ -1245,6 +1245,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) if (TREE_CODE (gnu_address) == POINTER_PLUS_EXPR && TREE_OPERAND (gnu_address, 1) == off) gnu_address = TREE_OPERAND (gnu_address, 0); + /* This is the pattern built for an overaligned object. */ else if (TREE_CODE (gnu_address) == POINTER_PLUS_EXPR && TREE_CODE (TREE_OPERAND (gnu_address, 1)) @@ -1255,6 +1256,18 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) = build2 (POINTER_PLUS_EXPR, gnu_type, TREE_OPERAND (gnu_address, 0), TREE_OPERAND (TREE_OPERAND (gnu_address, 1), 0)); + + /* We make an exception for an absolute address but we warn + that there is a descriptor at the start of the object. */ + else if (TREE_CODE (gnu_address) == INTEGER_CST) + { + post_error_ne ("??aliased object& with unconstrained " + "array nominal subtype", gnat_clause, + gnat_entity); + post_error ("\\starts with a descriptor whose size is " + "given by ''Descriptor_Size", gnat_clause); + } + else { post_error_ne ("aliased object& with unconstrained array " @@ -2480,8 +2493,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) tree gnu_base_orig_max = TYPE_MAX_VALUE (gnu_base_index_type); tree gnu_min, gnu_max, gnu_high; - /* We try to define subtypes for discriminants used as bounds - that are more restrictive than those declared by using the + /* We try to create subtypes for discriminants used as bounds + that are more restrictive than those declared, by using the bounds of the index type of the base array type. This will make it possible to calculate the maximum size of the record type more conservatively. This may have already been done by @@ -2489,8 +2502,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) there will be a conversion that needs to be removed first. */ if (CONTAINS_PLACEHOLDER_P (gnu_orig_min) && TYPE_RM_SIZE (gnu_base_index_type) - && !tree_int_cst_lt (TYPE_RM_SIZE (gnu_index_type), - TYPE_RM_SIZE (gnu_base_index_type))) + && tree_int_cst_lt (TYPE_RM_SIZE (gnu_base_index_type), + TYPE_RM_SIZE (gnu_index_type))) { gnu_orig_min = remove_conversions (gnu_orig_min, false); TREE_TYPE (gnu_orig_min) @@ -2501,8 +2514,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) if (CONTAINS_PLACEHOLDER_P (gnu_orig_max) && TYPE_RM_SIZE (gnu_base_index_type) - && !tree_int_cst_lt (TYPE_RM_SIZE (gnu_index_type), - TYPE_RM_SIZE (gnu_base_index_type))) + && tree_int_cst_lt (TYPE_RM_SIZE (gnu_base_index_type), + TYPE_RM_SIZE (gnu_index_type))) { gnu_orig_max = remove_conversions (gnu_orig_max, false); TREE_TYPE (gnu_orig_max) @@ -4412,7 +4425,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) /* If the size is self-referential, annotate the maximum value after saturating it, if need be, to avoid a No_Uint value. */ if (CONTAINS_PLACEHOLDER_P (gnu_size)) - gnu_size = maybe_saturate_size (max_size (gnu_size, true)); + { + const unsigned int align + = UI_To_Int (Alignment (gnat_entity)) * BITS_PER_UNIT; + gnu_size + = maybe_saturate_size (max_size (gnu_size, true), align); + } /* 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 @@ -4448,7 +4466,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) gnu_size = size_binop (PLUS_EXPR, gnu_size, offset); } - gnu_size = maybe_saturate_size (round_up (gnu_size, align)); + gnu_size + = maybe_saturate_size (round_up (gnu_size, align), align); Set_Esize (gnat_entity, annotate_value (gnu_size)); /* Tagged types are Strict_Alignment so RM_Size = Esize. */ @@ -8849,11 +8868,15 @@ build_subst_list (Entity_Id gnat_subtype, Entity_Id gnat_type, bool definition) if (!Is_Access_Type (Etype (Node (gnat_constr)))) { tree gnu_field = gnat_to_gnu_field_decl (gnat_discrim); - tree replacement = convert (TREE_TYPE (gnu_field), - elaborate_expression - (Node (gnat_constr), gnat_subtype, - get_entity_char (gnat_discrim), - definition, true, false)); + tree replacement + = elaborate_expression (Node (gnat_constr), gnat_subtype, + get_entity_char (gnat_discrim), + definition, true, false); + /* If this is a definition, we need to make sure that the SAVE_EXPRs + are instantiated on every possibly path in size computations. */ + if (definition && TREE_CODE (replacement) == SAVE_EXPR) + add_stmt (replacement); + replacement = convert (TREE_TYPE (gnu_field), replacement); subst_pair s = { gnu_field, replacement }; gnu_list.safe_push (s); } @@ -8929,15 +8952,21 @@ build_variant_list (tree gnu_qual_union_type, Node_Id gnat_variant_part, } /* If SIZE has overflowed, return the maximum valid size, which is the upper - bound of the signed sizetype in bits; otherwise return SIZE unmodified. */ + bound of the signed sizetype in bits, rounded down to ALIGN. Otherwise + return SIZE unmodified. */ static tree -maybe_saturate_size (tree size) +maybe_saturate_size (tree size, unsigned int align) { if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size)) - size = size_binop (MULT_EXPR, - fold_convert (bitsizetype, TYPE_MAX_VALUE (ssizetype)), - build_int_cst (bitsizetype, BITS_PER_UNIT)); + { + size + = size_binop (MULT_EXPR, + fold_convert (bitsizetype, TYPE_MAX_VALUE (ssizetype)), + build_int_cst (bitsizetype, BITS_PER_UNIT)); + size = round_down (size, align); + } + return size; } @@ -9079,10 +9108,12 @@ set_rm_size (Uint uint_size, tree gnu_type, Entity_Id gnat_entity) if (uint_size == No_Uint) return; - /* Only issue an error if a Value_Size clause was explicitly given. - Otherwise, we'd be duplicating an error on the Size clause. */ + /* Only issue an error if a Value_Size clause was explicitly given for the + entity; otherwise, we'd be duplicating an error on the Size clause. */ gnat_attr_node = Get_Attribute_Definition_Clause (gnat_entity, Attr_Value_Size); + if (Present (gnat_attr_node) && Entity (gnat_attr_node) != gnat_entity) + gnat_attr_node = Empty; /* Get the size as an INTEGER_CST. Issue an error if a size was specified but cannot be represented in bitsizetype. */ diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index e43b3db..355178e 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -390,6 +390,9 @@ enum standard_datatypes /* Function decl node for 64-bit multiplication with overflow checking. */ ADT_mulv64_decl, + /* Function decl node for 128-bit multiplication with overflow checking. */ + ADT_mulv128_decl, + /* Identifier for the name of the _Parent field in tagged record types. */ ADT_parent_name_id, @@ -462,6 +465,7 @@ extern GTY(()) tree gnat_raise_decls_ext[(int) LAST_REASON_CODE + 1]; #define free_decl gnat_std_decls[(int) ADT_free_decl] #define realloc_decl gnat_std_decls[(int) ADT_realloc_decl] #define mulv64_decl gnat_std_decls[(int) ADT_mulv64_decl] +#define mulv128_decl gnat_std_decls[(int) ADT_mulv128_decl] #define parent_name_id gnat_std_decls[(int) ADT_parent_name_id] #define exception_data_name_id gnat_std_decls[(int) ADT_exception_data_name_id] #define jmpbuf_type gnat_std_decls[(int) ADT_jmpbuf_type] @@ -1035,6 +1039,7 @@ extern Pos get_target_short_size (void); extern Pos get_target_int_size (void); extern Pos get_target_long_size (void); extern Pos get_target_long_long_size (void); +extern Pos get_target_long_long_long_size (void); extern Pos get_target_pointer_size (void); extern Pos get_target_maximum_default_alignment (void); extern Pos get_target_system_allocator_alignment (void); diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c index 3999f9c..781868e 100644 --- a/gcc/ada/gcc-interface/misc.c +++ b/gcc/ada/gcc-interface/misc.c @@ -35,6 +35,7 @@ #include "stor-layout.h" #include "print-tree.h" #include "toplev.h" +#include "tree-pass.h" #include "langhooks.h" #include "langhooks-def.h" #include "plugin.h" @@ -307,6 +308,9 @@ internal_error_function (diagnostic_context *context, const char *msgid, /* Warn if plugins present. */ warn_if_plugins (); + /* Dump the representation of the function. */ + emergency_dump_function (); + /* Reset the pretty-printer. */ pp_clear_output_area (context->printer); @@ -614,10 +618,9 @@ gnat_get_fixed_point_type_info (const_tree type, { tree scale_factor; - /* GDB cannot handle fixed-point types yet, so rely on GNAT encodings - instead for it. */ + /* Do nothing if the GNAT encodings are used. */ if (!TYPE_IS_FIXED_POINT_P (type) - || gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL) + || gnat_encodings == DWARF_GNAT_ENCODINGS_ALL) return false; scale_factor = TYPE_SCALE_FACTOR (type); @@ -1000,6 +1003,10 @@ get_array_bit_stride (tree comp_type) if (INTEGRAL_TYPE_P (comp_type)) return TYPE_RM_SIZE (comp_type); + /* Likewise for record or union types. */ + if (RECORD_OR_UNION_TYPE_P (comp_type) && !TYPE_FAT_POINTER_P (comp_type)) + return TYPE_ADA_SIZE (comp_type); + /* The gnat_get_array_descr_info debug hook expects a debug tyoe. */ comp_type = maybe_debug_type (comp_type); diff --git a/gcc/ada/gcc-interface/targtyps.c b/gcc/ada/gcc-interface/targtyps.c index 9b2d241..60a37e1 100644 --- a/gcc/ada/gcc-interface/targtyps.c +++ b/gcc/ada/gcc-interface/targtyps.c @@ -29,6 +29,7 @@ #include "system.h" #include "coretypes.h" #include "tm.h" +#include "target.h" #include "tree.h" #include "ada.h" @@ -95,6 +96,15 @@ get_target_long_long_size (void) } Pos +get_target_long_long_long_size (void) +{ + if (targetm.scalar_mode_supported_p (TImode)) + return GET_MODE_BITSIZE (TImode); + else + return LONG_LONG_TYPE_SIZE; +} + +Pos get_target_pointer_size (void) { return POINTER_SIZE; diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index f74e0e7..f03d591 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -439,6 +439,19 @@ gigi (Node_Id gnat_root, NULL_TREE, is_default, true, true, true, false, false, NULL, Empty); + if (Enable_128bit_Types) + { + tree int128_type = gnat_type_for_size (128, 0); + mulv128_decl + = create_subprog_decl (get_identifier ("__gnat_mulv128"), NULL_TREE, + build_function_type_list (int128_type, + int128_type, + int128_type, + NULL_TREE), + NULL_TREE, is_default, true, true, true, false, + false, NULL, Empty); + } + /* Name of the _Parent field in tagged record types. */ parent_name_id = get_identifier (Get_Name_String (Name_uParent)); @@ -624,7 +637,7 @@ gigi (Node_Id gnat_root, constructor_elt *elt; fdesc_type_node = make_node (RECORD_TYPE); - vec_safe_grow (null_vec, TARGET_VTABLE_USES_DESCRIPTORS); + vec_safe_grow (null_vec, TARGET_VTABLE_USES_DESCRIPTORS, true); elt = (null_vec->address () + TARGET_VTABLE_USES_DESCRIPTORS - 1); for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; j++) @@ -678,7 +691,8 @@ gigi (Node_Id gnat_root, /* Save the current optimization options again after the above possible global_options changes. */ - optimization_default_node = build_optimization_node (&global_options); + optimization_default_node + = build_optimization_node (&global_options, &global_options_set); optimization_current_node = optimization_default_node; /* Now translate the compilation unit proper. */ @@ -968,12 +982,8 @@ lvalue_for_aggregate_p (Node_Id gnat_node, tree gnu_type) get_unpadded_type (Etype (gnat_parent))); case N_Object_Declaration: - /* For an aggregate object declaration, return the constant at top level - in order to avoid generating elaboration code. */ - if (global_bindings_p ()) - return false; - - /* ... fall through ... */ + /* For an aggregate object declaration, return false consistently. */ + return false; case N_Assignment_Statement: /* For an aggregate assignment, decide based on the size. */ @@ -1747,7 +1757,7 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) gnu_result = build1 (INDIRECT_REF, gnu_result_type, gnu_result); } - vec_safe_grow (gnu_vec, TARGET_VTABLE_USES_DESCRIPTORS); + vec_safe_grow (gnu_vec, TARGET_VTABLE_USES_DESCRIPTORS, true); elt = (gnu_vec->address () + TARGET_VTABLE_USES_DESCRIPTORS - 1); for (gnu_field = TYPE_FIELDS (gnu_result_type), i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; @@ -4007,6 +4017,11 @@ Subprogram_Body_to_gnu (Node_Id gnat_node) gnat_poplevel (); gnu_result = end_stmt_group (); + /* Attempt setting the end_locus of our GCC body tree, typically a BIND_EXPR, + then the end_locus of our GCC subprogram declaration tree. */ + set_end_locus_from_node (gnu_result, gnat_node); + set_end_locus_from_node (gnu_subprog_decl, gnat_node); + /* If we populated the parameter attributes cache, we need to make sure that the cached expressions are evaluated on all the possible paths leading to their uses. So we force their evaluation on entry of the function. */ @@ -4101,12 +4116,6 @@ Subprogram_Body_to_gnu (Node_Id gnat_node) gnu_return_label_stack->pop (); - /* Attempt setting the end_locus of our GCC body tree, typically a - BIND_EXPR or STATEMENT_LIST, then the end_locus of our GCC subprogram - declaration tree. */ - set_end_locus_from_node (gnu_result, gnat_node); - set_end_locus_from_node (gnu_subprog_decl, gnat_node); - /* On SEH targets, install an exception handler around the main entry point to catch unhandled exceptions. */ if (DECL_NAME (gnu_subprog_decl) == main_identifier_node @@ -6476,6 +6485,7 @@ gnat_to_gnu (Node_Id gnat_node) gnu_expr = gnat_to_gnu (Expression (gnat_node)); + /* First deal with erroneous expressions. */ if (TREE_CODE (gnu_expr) == ERROR_MARK) { /* If this is a named number for which we cannot manipulate @@ -6485,6 +6495,11 @@ gnat_to_gnu (Node_Id gnat_node) else if (type_annotate_only) gnu_expr = NULL_TREE; } + + /* Then a special case: we do not want the SLOC of the expression + of the tag to pop up every time it is referenced somewhere. */ + else if (EXPR_P (gnu_expr) && Is_Tag (gnat_temp)) + SET_EXPR_LOCATION (gnu_expr, UNKNOWN_LOCATION); } else gnu_expr = NULL_TREE; @@ -9386,6 +9401,15 @@ build_binary_op_trapv (enum tree_code code, tree gnu_type, tree left, convert (int64, rhs))); } + /* Likewise for a 128-bit mult and a 64-bit target. */ + else if (code == MULT_EXPR && precision == 128 && BITS_PER_WORD < 128) + { + tree int128 = gnat_type_for_size (128, 0); + return convert (gnu_type, build_call_n_expr (mulv128_decl, 2, + convert (int128, lhs), + convert (int128, rhs))); + } + enum internal_fn icode; switch (code) diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index a96fde6..048a0cf 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -1343,7 +1343,7 @@ make_type_from_size (tree type, tree size_tree, bool for_biased) not already have the proper size and the size is not too large. */ if (BIT_PACKED_ARRAY_TYPE_P (type) || (TYPE_PRECISION (type) == size && biased_p == for_biased) - || size > LONG_LONG_TYPE_SIZE) + || size > (Enable_128bit_Types ? 128 : LONG_LONG_TYPE_SIZE)) break; biased_p |= for_biased; @@ -2905,6 +2905,31 @@ aggregate_type_contains_array_p (tree type, bool self_referential) } } +/* Return true if TYPE is a type with variable size or a padding type with a + field of variable size or a record that has a field with such a type. */ + +static bool +type_has_variable_size (tree type) +{ + tree field; + + if (!TREE_CONSTANT (TYPE_SIZE (type))) + return true; + + if (TYPE_IS_PADDING_P (type) + && !TREE_CONSTANT (DECL_SIZE (TYPE_FIELDS (type)))) + return true; + + if (!RECORD_OR_UNION_TYPE_P (type)) + return false; + + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) + if (type_has_variable_size (TREE_TYPE (field))) + return true; + + return false; +} + /* Return a FIELD_DECL node. NAME is the field's name, TYPE is its type and RECORD_TYPE is the type of the enclosing record. If SIZE is nonzero, it is the specified size of the field. If POS is nonzero, it is the bit @@ -2974,13 +2999,15 @@ create_field_decl (tree name, tree type, tree record_type, tree size, tree pos, DECL_PACKED (field_decl) = pos ? DECL_BIT_FIELD (field_decl) : packed; - /* If FIELD_TYPE is BLKmode, we must ensure this is aligned to at least a - byte boundary since GCC cannot handle less-aligned BLKmode bitfields. + /* If FIELD_TYPE has BLKmode, we must ensure this is aligned to at least + a byte boundary since GCC cannot handle less aligned BLKmode bitfields. + Likewise if it has a variable size and no specified position because + variable-sized objects need to be aligned to at least a byte boundary. Likewise for an aggregate without specified position that contains an - array, because in this case slices of variable length of this array - must be handled by GCC and variable-sized objects need to be aligned - to at least a byte boundary. */ + array because, in this case, slices of variable length of this array + must be handled by GCC and have variable size. */ if (packed && (TYPE_MODE (type) == BLKmode + || (!pos && type_has_variable_size (type)) || (!pos && AGGREGATE_TYPE_P (type) && aggregate_type_contains_array_p (type, false)))) |