aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2015-10-10 21:43:49 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2015-10-10 19:43:49 +0000
commit9c4eeafc11dbd996949b3a0c3f5196e7c45ef92f (patch)
treea70d4b968b6a34668f485e3a39033f4dc68cf53c /gcc/tree.c
parent05486daafd85d56f457ab6808a02de02d53d60b3 (diff)
downloadgcc-9c4eeafc11dbd996949b3a0c3f5196e7c45ef92f.zip
gcc-9c4eeafc11dbd996949b3a0c3f5196e7c45ef92f.tar.gz
gcc-9c4eeafc11dbd996949b3a0c3f5196e7c45ef92f.tar.bz2
tree.c (type_with_interoperable_signedness): New.
* tree.c (type_with_interoperable_signedness): New. (gimple_canonical_types_compatible_p): Use it. * tree.h (type_with_interoperable_signedness): Declare * lto.c (hash_canonical_type): Honor type_with_interoperable_signedness. * gfortran.dg/lto/bind_c-2_0.f90: New testcase. * gfortran.dg/lto/bind_c-2_1.c: New testcase. * gfortran.dg/lto/bind_c-3_0.f90: New testcase. * gfortran.dg/lto/bind_c-3_1.c: New testcase. * gfortran.dg/lto/bind_c-4_0.f90: New testcase. * gfortran.dg/lto/bind_c-4_1.c: New testcase. * gfortran.dg/lto/bind_c-5_0.f90: New testcase. * gfortran.dg/lto/bind_c-5_1.c: New testcase. From-SVN: r228680
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index f78a2c2..02f0a7a 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -13012,6 +13012,23 @@ verify_type_variant (const_tree t, tree tv)
back to pointer-comparison of TYPE_CANONICAL for aggregates
for example. */
+/* Return true if TYPE_UNSIGNED of TYPE should be ignored for canonical
+ type calculation because we need to allow inter-operability between signed
+ and unsigned variants. */
+
+bool
+type_with_interoperable_signedness (const_tree type)
+{
+ /* Fortran standard require C_SIGNED_CHAR to be interoperable with both
+ signed char and unsigned char. Similarly fortran FE builds
+ C_SIZE_T as signed type, while C defines it unsigned. */
+
+ return tree_code_for_canonical_type_merging (TREE_CODE (type))
+ == INTEGER_TYPE
+ && (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node)
+ || TYPE_PRECISION (type) == TYPE_PRECISION (size_type_node));
+}
+
/* Return true iff T1 and T2 are structurally identical for what
TBAA is concerned.
This function is used both by lto.c canonical type merging and by the
@@ -13062,8 +13079,8 @@ gimple_canonical_types_compatible_p (const_tree t1, const_tree t2,
return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
/* Can't be the same type if the types don't have the same code. */
- if (tree_code_for_canonical_type_merging (TREE_CODE (t1))
- != tree_code_for_canonical_type_merging (TREE_CODE (t2)))
+ enum tree_code code = tree_code_for_canonical_type_merging (TREE_CODE (t1));
+ if (code != tree_code_for_canonical_type_merging (TREE_CODE (t2)))
return false;
/* Qualifiers do not matter for canonical type comparison purposes. */
@@ -13086,9 +13103,14 @@ gimple_canonical_types_compatible_p (const_tree t1, const_tree t2,
|| TREE_CODE (t1) == OFFSET_TYPE
|| POINTER_TYPE_P (t1))
{
- /* Can't be the same type if they have different sign or precision. */
- if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2)
- || TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2))
+ /* Can't be the same type if they have different recision. */
+ if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2))
+ return false;
+
+ /* In some cases the signed and unsigned types are required to be
+ inter-operable. */
+ if (TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2)
+ && !type_with_interoperable_signedness (t1))
return false;
/* Fortran's C_SIGNED_CHAR is !TYPE_STRING_FLAG but needs to be