diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2009-07-11 20:52:28 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2009-07-11 20:52:28 +0000 |
commit | f4cd2542becd2e4a9b648587693906a0e64531dd (patch) | |
tree | 5f43f396f64c2d468fbd26fc6394ff8b2d0734e9 /gcc/ada/gcc-interface | |
parent | 97c281dacf21dcec5ed4f75f089960c8bfa81b0a (diff) | |
download | gcc-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.c | 70 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/gigi.h | 7 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/trans.c | 13 |
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); |