aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/trans.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2008-05-17 08:21:08 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2008-05-17 08:21:08 +0000
commit74c11a6c4d7b55e0e903a99fe58dfd491ce4fc2c (patch)
treef9545569019d481d033e308ad0d90115d50e0a21 /gcc/ada/trans.c
parent30da41ed0e281e0fd35454eb24490ed35325e9b5 (diff)
downloadgcc-74c11a6c4d7b55e0e903a99fe58dfd491ce4fc2c.zip
gcc-74c11a6c4d7b55e0e903a99fe58dfd491ce4fc2c.tar.gz
gcc-74c11a6c4d7b55e0e903a99fe58dfd491ce4fc2c.tar.bz2
trans.c (gnat_to_gnu): Account for dummy types pointed to by the converted pointer types.
* trans.c (gnat_to_gnu) <N_Validate_Unchecked_Conversion>: Account for dummy types pointed to by the converted pointer types. From-SVN: r135464
Diffstat (limited to 'gcc/ada/trans.c')
-rw-r--r--gcc/ada/trans.c84
1 files changed, 55 insertions, 29 deletions
diff --git a/gcc/ada/trans.c b/gcc/ada/trans.c
index f7dd9b9..76592fe 100644
--- a/gcc/ada/trans.c
+++ b/gcc/ada/trans.c
@@ -4777,45 +4777,71 @@ gnat_to_gnu (Node_Id gnat_node)
break;
case N_Validate_Unchecked_Conversion:
- /* If the result is a pointer type, see if we are either converting
- from a non-pointer or from a pointer to a type with a different
- alias set and warn if so. If the result defined in the same unit as
- this unchecked conversion, we can allow this because we can know to
- make that type have alias set 0. */
{
+ Entity_Id gnat_target_type = Target_Type (gnat_node);
tree gnu_source_type = gnat_to_gnu_type (Source_Type (gnat_node));
- tree gnu_target_type = gnat_to_gnu_type (Target_Type (gnat_node));
-
- if (POINTER_TYPE_P (gnu_target_type)
- && !In_Same_Source_Unit (Target_Type (gnat_node), gnat_node)
- && get_alias_set (TREE_TYPE (gnu_target_type)) != 0
- && !No_Strict_Aliasing (Underlying_Type (Target_Type (gnat_node)))
- && (!POINTER_TYPE_P (gnu_source_type)
- || (get_alias_set (TREE_TYPE (gnu_source_type))
- != get_alias_set (TREE_TYPE (gnu_target_type)))))
+ tree gnu_target_type = gnat_to_gnu_type (gnat_target_type);
+
+ /* No need for any warning in this case. */
+ if (!flag_strict_aliasing)
+ ;
+
+ /* If the result is a pointer type, see if we are either converting
+ from a non-pointer or from a pointer to a type with a different
+ alias set and warn if so. If the result is defined in the same
+ unit as this unchecked conversion, we can allow this because we
+ can know to make the pointer type behave properly. */
+ else if (POINTER_TYPE_P (gnu_target_type)
+ && !In_Same_Source_Unit (gnat_target_type, gnat_node)
+ && !No_Strict_Aliasing (Underlying_Type (gnat_target_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);
- post_error_ne
- ("\\?or use `pragma No_Strict_Aliasing (&);`",
- gnat_node, Target_Type (gnat_node));
+ tree gnu_source_desig_type = POINTER_TYPE_P (gnu_source_type)
+ ? TREE_TYPE (gnu_source_type)
+ : NULL_TREE;
+ tree gnu_target_desig_type = TREE_TYPE (gnu_target_type);
+
+ if ((TYPE_DUMMY_P (gnu_target_desig_type)
+ || get_alias_set (gnu_target_desig_type) != 0)
+ && (!POINTER_TYPE_P (gnu_source_type)
+ || (TYPE_DUMMY_P (gnu_source_desig_type)
+ != TYPE_DUMMY_P (gnu_target_desig_type))
+ || (TYPE_DUMMY_P (gnu_source_desig_type)
+ && gnu_source_desig_type != gnu_target_desig_type)
+ || (get_alias_set (gnu_source_desig_type)
+ != get_alias_set (gnu_target_desig_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);
+ post_error_ne
+ ("\\?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. */
+ /* But if the result is a fat pointer type, we have no mechanism to
+ do that, so we unconditionally warn in problematic cases. */
else if (TYPE_FAT_POINTER_P (gnu_target_type))
{
- tree array_type
+ tree gnu_source_array_type
+ = TYPE_FAT_POINTER_P (gnu_source_type)
+ ? TREE_TYPE (TREE_TYPE (TYPE_FIELDS (gnu_source_type)))
+ : NULL_TREE;
+ tree gnu_target_array_type
= TREE_TYPE (TREE_TYPE (TYPE_FIELDS (gnu_target_type)));
- if (get_alias_set (array_type) != 0
+ if ((TYPE_DUMMY_P (gnu_target_array_type)
+ || get_alias_set (gnu_target_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))))
+ || (TYPE_DUMMY_P (gnu_source_array_type)
+ != TYPE_DUMMY_P (gnu_target_array_type))
+ || (TYPE_DUMMY_P (gnu_source_array_type)
+ && gnu_source_array_type != gnu_target_array_type)
+ || (get_alias_set (gnu_source_array_type)
+ != get_alias_set (gnu_target_array_type))))
{
post_error_ne
("?possible aliasing problem for type&",