summaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/gcc-interface')
-rw-r--r--gcc/ada/gcc-interface/Makefile.in7
-rw-r--r--gcc/ada/gcc-interface/decl.c21
-rw-r--r--gcc/ada/gcc-interface/misc.c3
-rw-r--r--gcc/ada/gcc-interface/trans.c42
-rw-r--r--gcc/ada/gcc-interface/utils.c51
-rw-r--r--gcc/ada/gcc-interface/utils2.c2
6 files changed, 94 insertions, 32 deletions
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index d9ede9f426..8996dd1bef 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -2670,10 +2670,9 @@ gnatlink-re: ../stamp-tools gnatmake-re
install-gcc-specs:
# Install all the requested GCC spec files.
- for f in $(GCC_SPEC_FILES); do \
- $(INSTALL_DATA_DATE) $(srcdir)/ada/$$f \
- $(libsubdir)/$$(echo $$f|sed -e 's#_[a-zA-Z0-9]*##g'); \
- done
+ $(foreach f,$(GCC_SPEC_FILES), \
+ $(INSTALL_DATA_DATE) $(srcdir)/ada/$(f) \
+ $(DESTDIR)$(libsubdir)/$$(echo $(f)|sed -e 's#_[a-zA-Z0-9]*##g');)
install-gnatlib: ../stamp-gnatlib-$(RTSDIR) install-gcc-specs
$(RMDIR) $(DESTDIR)$(ADA_RTL_OBJ_DIR)
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 87026e742b..6f2b0bbfd2 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -966,6 +966,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
&& !call_is_atomic_load (inner))
|| TREE_CODE (inner) == ADDR_EXPR
|| TREE_CODE (inner) == NULL_EXPR
+ || TREE_CODE (inner) == PLUS_EXPR
|| TREE_CODE (inner) == CONSTRUCTOR
|| CONSTANT_CLASS_P (inner)
/* We need to detect the case where a temporary is created to
@@ -2321,10 +2322,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnat_name = Packed_Array_Impl_Type (gnat_entity);
else
gnat_name = gnat_entity;
- if (gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL)
- gnu_entity_name = create_concat_name (gnat_name, "XUP");
- create_type_decl (gnu_entity_name, gnu_fat_type, artificial_p,
- debug_info_p, gnat_entity);
+ tree xup_name
+ = (gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL)
+ ? get_entity_name (gnat_name)
+ : create_concat_name (gnat_name, "XUP");
+ create_type_decl (xup_name, gnu_fat_type, artificial_p, debug_info_p,
+ gnat_entity);
/* Create the type to be designated by thin pointers: a record type for
the array and its template. We used to shift the fields to have the
@@ -2334,11 +2337,11 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
Note that GDB can handle standard DWARF information for them, so we
don't have to name them as a GNAT encoding, except if specifically
asked to. */
- if (gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL)
- gnu_entity_name = create_concat_name (gnat_name, "XUT");
- else
- gnu_entity_name = get_entity_name (gnat_name);
- tem = build_unc_object_type (gnu_template_type, tem, gnu_entity_name,
+ tree xut_name
+ = (gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL)
+ ? get_entity_name (gnat_name)
+ : create_concat_name (gnat_name, "XUT");
+ tem = build_unc_object_type (gnu_template_type, tem, xut_name,
debug_info_p);
SET_TYPE_UNCONSTRAINED_ARRAY (tem, gnu_type);
diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index 61a61fad40..521f8b9907 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -369,9 +369,6 @@ gnat_init (void)
sbitsize_one_node = sbitsize_int (1);
sbitsize_unit_node = sbitsize_int (BITS_PER_UNIT);
- /* Show that REFERENCE_TYPEs are internal and should be Pmode. */
- internal_reference_types ();
-
/* Register our internal error function. */
global_dc->internal_error = &internal_error_function;
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 357d26f8d5..cf64d229a5 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -2483,13 +2483,15 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
static tree
Case_Statement_to_gnu (Node_Id gnat_node)
{
- tree gnu_result, gnu_expr, gnu_label;
+ tree gnu_result, gnu_expr, gnu_type, gnu_label;
Node_Id gnat_when;
location_t end_locus;
bool may_fallthru = false;
gnu_expr = gnat_to_gnu (Expression (gnat_node));
gnu_expr = convert (get_base_type (TREE_TYPE (gnu_expr)), gnu_expr);
+ gnu_expr = maybe_character_value (gnu_expr);
+ gnu_type = TREE_TYPE (gnu_expr);
/* We build a SWITCH_EXPR that contains the code with interspersed
CASE_LABEL_EXPRs for each label. */
@@ -2559,6 +2561,11 @@ Case_Statement_to_gnu (Node_Id gnat_node)
gcc_assert (!gnu_low || TREE_CODE (gnu_low) == INTEGER_CST);
gcc_assert (!gnu_high || TREE_CODE (gnu_high) == INTEGER_CST);
+ if (gnu_low && TREE_TYPE (gnu_low) != gnu_type)
+ gnu_low = convert (gnu_type, gnu_low);
+ if (gnu_high && TREE_TYPE (gnu_high) != gnu_type)
+ gnu_high = convert (gnu_type, gnu_high);
+
add_stmt_with_node (build_case_label (gnu_low, gnu_high, label),
gnat_choice);
choices_added_p = true;
@@ -2590,8 +2597,8 @@ Case_Statement_to_gnu (Node_Id gnat_node)
/* Now emit a definition of the label the cases branch to, if any. */
if (may_fallthru)
add_stmt (build1 (LABEL_EXPR, void_type_node, gnu_label));
- gnu_result = build3 (SWITCH_EXPR, TREE_TYPE (gnu_expr), gnu_expr,
- end_stmt_group (), NULL_TREE);
+ gnu_result
+ = build3 (SWITCH_EXPR, gnu_type, gnu_expr, end_stmt_group (), NULL_TREE);
return gnu_result;
}
@@ -7635,10 +7642,11 @@ gnat_to_gnu (Node_Id gnat_node)
else
gnu_actual_obj_type = gnu_obj_type;
+ tree gnu_size = TYPE_SIZE_UNIT (gnu_actual_obj_type);
+ gnu_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_size, gnu_ptr);
+
gnu_result
- = build_call_alloc_dealloc (gnu_ptr,
- TYPE_SIZE_UNIT (gnu_actual_obj_type),
- gnu_obj_type,
+ = build_call_alloc_dealloc (gnu_ptr, gnu_size, gnu_obj_type,
Procedure_To_Call (gnat_node),
Storage_Pool (gnat_node),
gnat_node);
@@ -7719,16 +7727,22 @@ gnat_to_gnu (Node_Id gnat_node)
N_Raise_Constraint_Error));
}
- /* If the result has side-effects and is of an unconstrained type, make a
- SAVE_EXPR so that we can be sure it will only be referenced once. But
- this is useless for a call to a function that returns an unconstrained
- type with default discriminant, as we cannot compute the size of the
- actual returned object. We must do this before any conversions. */
+ /* If the result has side-effects and is of an unconstrained type, protect
+ the expression in case it will be referenced multiple times, i.e. for
+ its value and to compute the size of an object. But do it neither for
+ an object nor a renaming declaration, nor a return statement of a call
+ to a function that returns an unconstrained record type with default
+ discriminant, because there is no size to be computed in these cases
+ and this will create a useless temporary. We must do this before any
+ conversions. */
if (TREE_SIDE_EFFECTS (gnu_result)
- && !(TREE_CODE (gnu_result) == CALL_EXPR
- && type_is_padding_self_referential (TREE_TYPE (gnu_result)))
&& (TREE_CODE (gnu_result_type) == UNCONSTRAINED_ARRAY_TYPE
- || CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type))))
+ || CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type)))
+ && !(TREE_CODE (gnu_result) == CALL_EXPR
+ && type_is_padding_self_referential (TREE_TYPE (gnu_result))
+ && (Nkind (Parent (gnat_node)) == N_Object_Declaration
+ || Nkind (Parent (gnat_node)) == N_Object_Renaming_Declaration
+ || Nkind (Parent (gnat_node)) == N_Simple_Return_Statement)))
gnu_result = gnat_protect_expr (gnu_result);
/* Now convert the result to the result type, unless we are in one of the
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 9bd2773ba9..4226f95463 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -90,6 +90,8 @@ static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
+static tree handle_noinline_attribute (tree *, tree, tree, int, bool *);
+static tree handle_noclone_attribute (tree *, tree, tree, int, bool *);
static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
static tree handle_always_inline_attribute (tree *, tree, tree, int, bool *);
static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
@@ -121,6 +123,10 @@ const struct attribute_spec gnat_internal_attribute_table[] =
false },
{ "noreturn", 0, 0, true, false, false, handle_noreturn_attribute,
false },
+ { "noinline", 0, 0, true, false, false, handle_noinline_attribute,
+ false },
+ { "noclone", 0, 0, true, false, false, handle_noclone_attribute,
+ false },
{ "leaf", 0, 0, true, false, false, handle_leaf_attribute,
false },
{ "always_inline",0, 0, true, false, false, handle_always_inline_attribute,
@@ -5974,6 +5980,51 @@ handle_noreturn_attribute (tree *node, tree name, tree ARG_UNUSED (args),
return NULL_TREE;
}
+/* Handle a "noinline" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_noinline_attribute (tree *node, tree name,
+ tree ARG_UNUSED (args),
+ int ARG_UNUSED (flags), bool *no_add_attrs)
+{
+ if (TREE_CODE (*node) == FUNCTION_DECL)
+ {
+ if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (*node)))
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
+ "with attribute %qs", name, "always_inline");
+ *no_add_attrs = true;
+ }
+ else
+ DECL_UNINLINABLE (*node) = 1;
+ }
+ else
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
+
+ return NULL_TREE;
+}
+
+/* Handle a "noclone" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_noclone_attribute (tree *node, tree name,
+ tree ARG_UNUSED (args),
+ int ARG_UNUSED (flags), bool *no_add_attrs)
+{
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
+
+ return NULL_TREE;
+}
+
/* Handle a "leaf" attribute; arguments as in
struct attribute_spec.handler. */
diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c
index c1bb74da28..6f05ee29bc 100644
--- a/gcc/ada/gcc-interface/utils2.c
+++ b/gcc/ada/gcc-interface/utils2.c
@@ -2266,8 +2266,6 @@ build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, tree gnu_type,
Entity_Id gnat_proc, Entity_Id gnat_pool,
Node_Id gnat_node)
{
- gnu_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_size, gnu_obj);
-
/* Explicit proc to call ? This one is assumed to deal with the type
alignment constraints. */
if (Present (gnat_proc))