diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2008-05-17 08:21:08 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2008-05-17 08:21:08 +0000 |
commit | 74c11a6c4d7b55e0e903a99fe58dfd491ce4fc2c (patch) | |
tree | f9545569019d481d033e308ad0d90115d50e0a21 /gcc/ada/trans.c | |
parent | 30da41ed0e281e0fd35454eb24490ed35325e9b5 (diff) | |
download | gcc-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.c | 84 |
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&", |