diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-03-18 11:47:18 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-03-18 11:47:18 +0000 |
commit | 10d5317506f422b22d3cf3ed48a3fc6e211cb431 (patch) | |
tree | 65b5f248d06750565cc817641650223fd0f8922a /gcc/ada/trans.c | |
parent | 46504d45fd7942be0cf3372995e24d79318cd6cd (diff) | |
download | gcc-10d5317506f422b22d3cf3ed48a3fc6e211cb431.tar.gz |
2005-03-17 Eric Botcazou <ebotcazou@adacore.com>
* ada-tree.h: (DECL_RENAMING_GLOBAL_P): New predicate.
(DECL_RENAMED_OBJECT): New accessor macro.
(SET_DECL_RENAMED_OBJECT): New setter macro.
* decl.c (gnat_to_gnu_entity) <E_Variable>: Stabilize the renamed
object in all cases. Attach the renamed object to the VAR_DECL.
(gnat_to_gnu_field): Do not lift the record wrapper if the size of the
field is not prescribed.
* misc.c (gnat_handle_option): Handle -gnatO separately.
(gnat_print_decl) <VAR_DECL>: New case.
Print the DECL_RENAMED_OBJECT node.
* lang.opt: Declare separate -gnatO option.
* trans.c (tree_transform) <N_Identifier>: If the object is a renaming
pointer, replace it with the renamed object.
<N_Validate_Unchecked_Conversion>: Warn for a conversion to a fat
pointer type if the source is not a fat pointer type whose underlying
array has the same non-zero alias set as that of the destination array.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@96660 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/trans.c')
-rw-r--r-- | gcc/ada/trans.c | 65 |
1 files changed, 34 insertions, 31 deletions
diff --git a/gcc/ada/trans.c b/gcc/ada/trans.c index 7e6485557a4..10955e35231 100644 --- a/gcc/ada/trans.c +++ b/gcc/ada/trans.c @@ -393,7 +393,7 @@ Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p) && DECL_BY_COMPONENT_PTR_P (gnu_result)))) { bool ro = DECL_POINTS_TO_READONLY_P (gnu_result); - tree initial; + tree renamed_obj; if (TREE_CODE (gnu_result) == PARM_DECL && DECL_BY_COMPONENT_PTR_P (gnu_result)) @@ -402,34 +402,17 @@ Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p) convert (build_pointer_type (gnu_result_type), gnu_result)); - /* If the object is constant, we try to do the dereference directly - through the DECL_INITIAL. This is actually required in order to get - correct aliasing information for renamed objects that are components - of non-aliased aggregates, because the type of the renamed object and - that of the aggregate don't alias. - - Note that we expect the initial value to have been stabilized. - If it contains e.g. a variable reference, we certainly don't want - to re-evaluate the variable each time the renaming is used. - - Stabilization is currently not performed at the global level but - create_var_decl avoids setting DECL_INITIAL if the value is not - constant then, and we get to the pointer dereference below. - - ??? Couldn't the aliasing issue show up again in this case ? - There is no obvious reason why not. */ - else if (TREE_READONLY (gnu_result) - && DECL_INITIAL (gnu_result) - /* Strip possible conversion to reference type. */ - && ((initial = TREE_CODE (DECL_INITIAL (gnu_result)) - == NOP_EXPR - ? TREE_OPERAND (DECL_INITIAL (gnu_result), 0) - : DECL_INITIAL (gnu_result), 1)) - && TREE_CODE (initial) == ADDR_EXPR - && (TREE_CODE (TREE_OPERAND (initial, 0)) == ARRAY_REF - || (TREE_CODE (TREE_OPERAND (initial, 0)) - == COMPONENT_REF))) - gnu_result = TREE_OPERAND (initial, 0); + /* If it's a renaming pointer and we are at the right binding level, + we can reference the renamed object directly, since the renamed + expression has been protected against multiple evaluations. */ + else if (TREE_CODE (gnu_result) == VAR_DECL + && (renamed_obj = DECL_RENAMED_OBJECT (gnu_result)) != 0 + && (! DECL_RENAMING_GLOBAL_P (gnu_result) + || global_bindings_p ()) + /* Make sure it's an lvalue like INDIRECT_REF. */ + && (TREE_CODE_CLASS (TREE_CODE (renamed_obj)) == 'd' + || TREE_CODE_CLASS (TREE_CODE (renamed_obj)) == 'r')) + gnu_result = renamed_obj; else gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, fold (gnu_result)); @@ -746,8 +729,7 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) if (CONTAINS_PLACEHOLDER_P (gnu_result)) { if (TREE_CODE (gnu_prefix) != TYPE_DECL) - gnu_result = substitute_placeholder_in_expr (gnu_result, - gnu_expr); + gnu_result = substitute_placeholder_in_expr (gnu_result, gnu_expr); else gnu_result = max_size (gnu_result, true); } @@ -4012,6 +3994,27 @@ gnat_to_gnu (Node_Id gnat_node) ("\\?or use `pragma No_Strict_Aliasing (&);`", gnat_node, Target_Type (gnat_node)); } + + /* The No_Strict_Aliasing flag is not propagated to the back-end for + fat pointers so unconditionally warn in problematic cases. */ + else if (TYPE_FAT_POINTER_P (gnu_target_type)) + { + tree array_type + = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (gnu_target_type))); + + if (get_alias_set (array_type) != 0 + && (!TYPE_FAT_POINTER_P (gnu_source_type) + || (get_alias_set (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (gnu_source_type)))) + != get_alias_set (array_type)))) + { + post_error_ne + ("?possible aliasing problem for type&", + gnat_node, Target_Type (gnat_node)); + post_error + ("\\?use -fno-strict-aliasing switch for references", + gnat_node); + } + } } gnu_result = alloc_stmt_list (); break; |