aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2009-07-11 20:52:28 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2009-07-11 20:52:28 +0000
commitf4cd2542becd2e4a9b648587693906a0e64531dd (patch)
tree5f43f396f64c2d468fbd26fc6394ff8b2d0734e9 /gcc/ada/gcc-interface
parent97c281dacf21dcec5ed4f75f089960c8bfa81b0a (diff)
downloadgcc-f4cd2542becd2e4a9b648587693906a0e64531dd.zip
gcc-f4cd2542becd2e4a9b648587693906a0e64531dd.tar.gz
gcc-f4cd2542becd2e4a9b648587693906a0e64531dd.tar.bz2
checks.adb (Apply_Address_Clause_Check): Remove Size_Warning_Output local variable and do not test it in...
* checks.adb (Apply_Address_Clause_Check): Remove Size_Warning_Output local variable and do not test it in Compile_Time_Bad_Alignment. Do not issue size or alignment warnings for the X'Address form. * sem_util.ads (Find_Overlaid_Object): Delete. (Find_Overlaid_Entity): New procedure. * sem_util.adb (Find_Overlaid_Object): Rename to... (Find_Overlaid_Entity): ...this and turn into a procedure. Report whether the address is offseted within the overlaid entity. (Has_Compatible_Alignment): Track the offset globally instead of passing it to Check_Offset. For an indexed component, compute the full offset when possible. If the resulting offset is zero, only check the prefix. (Check_Offset): Delete. * sem_ch13.adb (Address_Clause_Check_Record): Add Off field. (Address_Aliased_Entity): Delete. (Analyze_Attribute_Definition_Clause) <Attribute_Address>: Call Find_Overlaid_Entity to find the overlaid entity and the offset. Adjust throughout for above change. (Validate_Address_Clauses): Always use attributes of entities, not of their type. Tweak message for warning. Call Has_Compatible_Alignment if the address is offseted to warn about incompatible alignments. * gcc-interface/gigi.h (annotate_object): Declare. * gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Annotate renaming entity. Call annotate_object instead of annotating manually objects. (annotate_object): New function. * gcc-interface/trans.c (Subprogram_Body_to_gnu): Annotate parameters at the end. From-SVN: r149520
Diffstat (limited to 'gcc/ada/gcc-interface')
-rw-r--r--gcc/ada/gcc-interface/decl.c70
-rw-r--r--gcc/ada/gcc-interface/gigi.h7
-rw-r--r--gcc/ada/gcc-interface/trans.c13
3 files changed, 60 insertions, 30 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 4208612..67d8cd1 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -905,6 +905,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
mark_visited (&gnu_decl);
save_gnu_tree (gnat_entity, gnu_decl, true);
saved = true;
+ annotate_object (gnat_entity, gnu_type, NULL_TREE,
+ false);
break;
}
@@ -1382,32 +1384,15 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
&& Exception_Mechanism != Back_End_Exceptions)
TREE_ADDRESSABLE (gnu_decl) = 1;
- gnu_type = TREE_TYPE (gnu_decl);
-
- /* Back-annotate Alignment and Esize of the object if not already
- known, except for when the object is actually a pointer to the
- real object, since alignment and size of a pointer don't have
- anything to do with those of the designated object. Note that
- we pick the values of the type, not those of the object, to
- shield ourselves from low-level platform-dependent adjustments
- like alignment promotion. This is both consistent with all the
- treatment above, where alignment and size are set on the type of
- the object and not on the object directly, and makes it possible
- to support confirming representation clauses in all cases. */
-
- if (!used_by_ref && Unknown_Alignment (gnat_entity))
- Set_Alignment (gnat_entity,
- UI_From_Int (TYPE_ALIGN (gnu_type) / BITS_PER_UNIT));
-
- if (!used_by_ref && Unknown_Esize (gnat_entity))
- {
- if (TREE_CODE (gnu_type) == RECORD_TYPE
- && TYPE_CONTAINS_TEMPLATE_P (gnu_type))
- gnu_object_size
- = TYPE_SIZE (TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (gnu_type))));
-
- Set_Esize (gnat_entity, annotate_value (gnu_object_size));
- }
+ /* Back-annotate Esize and Alignment of the object if not already
+ known. Note that we pick the values of the type, not those of
+ the object, to shield ourselves from low-level platform-dependent
+ adjustments like alignment promotion. This is both consistent with
+ all the treatment above, where alignment and size are set on the
+ type of the object and not on the object directly, and makes it
+ possible to support all confirming representation clauses. */
+ annotate_object (gnat_entity, TREE_TYPE (gnu_decl), gnu_object_size,
+ used_by_ref);
}
break;
@@ -7223,6 +7208,39 @@ annotate_value (tree gnu_size)
return ret;
}
+/* Given GNAT_ENTITY, an object (constant, variable, parameter, exception)
+ and GNU_TYPE, its corresponding GCC type, set Esize and Alignment to the
+ size and alignment used by Gigi. Prefer SIZE over TYPE_SIZE if non-null.
+ BY_REF is true if the object is used by reference. */
+
+void
+annotate_object (Entity_Id gnat_entity, tree gnu_type, tree size, bool by_ref)
+{
+ if (by_ref)
+ {
+ if (TYPE_FAT_POINTER_P (gnu_type))
+ gnu_type = TYPE_UNCONSTRAINED_ARRAY (gnu_type);
+ else
+ gnu_type = TREE_TYPE (gnu_type);
+ }
+
+ if (Unknown_Esize (gnat_entity))
+ {
+ if (TREE_CODE (gnu_type) == RECORD_TYPE
+ && TYPE_CONTAINS_TEMPLATE_P (gnu_type))
+ size = TYPE_SIZE (TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (gnu_type))));
+ else if (!size)
+ size = TYPE_SIZE (gnu_type);
+
+ if (size)
+ Set_Esize (gnat_entity, annotate_value (size));
+ }
+
+ if (Unknown_Alignment (gnat_entity))
+ Set_Alignment (gnat_entity,
+ UI_From_Int (TYPE_ALIGN (gnu_type) / BITS_PER_UNIT));
+}
+
/* Given GNAT_ENTITY, a record type, and GNU_TYPE, its corresponding
GCC type, set Component_Bit_Offset and Esize to the position and size
used by Gigi. */
diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h
index 7bc89ee..de253b8 100644
--- a/gcc/ada/gcc-interface/gigi.h
+++ b/gcc/ada/gcc-interface/gigi.h
@@ -135,6 +135,13 @@ extern tree maybe_pad_type (tree type, tree size, unsigned int align,
the value passed against the list of choices. */
extern tree choices_to_gnu (tree operand, Node_Id choices);
+/* Given GNAT_ENTITY, an object (constant, variable, parameter, exception)
+ and GNU_TYPE, its corresponding GCC type, set Esize and Alignment to the
+ size and alignment used by Gigi. Prefer SIZE over TYPE_SIZE if non-null.
+ BY_REF is true if the object is used by reference. */
+extern void annotate_object (Entity_Id gnat_entity, tree gnu_type, tree size,
+ bool by_ref);
+
/* Given a type T, a FIELD_DECL F, and a replacement value R, return a new
type with all size expressions that contain F updated by replacing F
with R. If F is NULL_TREE, always make a new RECORD_TYPE, even if
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 76200ab..5b4e5e8 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -2328,13 +2328,18 @@ Subprogram_Body_to_gnu (Node_Id gnat_node)
end_subprog_body (gnu_result, false);
- /* Disconnect the trees for parameters that we made variables for from the
- GNAT entities since these are unusable after we end the function. */
+ /* Finally annotate the parameters and disconnect the trees for parameters
+ that we have turned into variables since they are now unusable. */
for (gnat_param = First_Formal_With_Extras (gnat_subprog_id);
Present (gnat_param);
gnat_param = Next_Formal_With_Extras (gnat_param))
- if (TREE_CODE (get_gnu_tree (gnat_param)) == VAR_DECL)
- save_gnu_tree (gnat_param, NULL_TREE, false);
+ {
+ tree gnu_param = get_gnu_tree (gnat_param);
+ annotate_object (gnat_param, TREE_TYPE (gnu_param), NULL_TREE,
+ DECL_BY_REF_P (gnu_param));
+ if (TREE_CODE (gnu_param) == VAR_DECL)
+ save_gnu_tree (gnat_param, NULL_TREE, false);
+ }
if (DECL_FUNCTION_STUB (gnu_subprog_decl))
build_function_stub (gnu_subprog_decl, gnat_subprog_id);