https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77278
--- Comment #30 from Jan Hubicka <hubicka at ucw dot cz> ---
Hi,
this patch makes Fortran logicals to become C unsigned types of
corresponding size. I think it is better than making them signed
because the globbing will affect aliasing within Fortran programs as
well. We still ignore sign on chars and size_t, so this is still
throwing away some precision (i.e. LOGICAL of size 1 will become INTEGER
if size 1 for TBAA purposes)
Index: lto/lto-common.c
===================================================================
--- lto/lto-common.c (revision 272506)
+++ lto/lto-common.c (working copy)
@@ -238,6 +238,8 @@ hash_canonical_type (tree type)
types. */
gcc_checking_assert (type_with_alias_set_p (type));
+ type = type_for_canonical_type_merging (type);
+
/* Combine a few common features of types so that types are grouped into
smaller sets; when searching for existing matching types to merge,
only existing types having the same features as the new type will be
Index: testsuite/gfortran.dg/lto/bind_c-7_0.f90
===================================================================
--- testsuite/gfortran.dg/lto/bind_c-7_0.f90 (nonexistent)
+++ testsuite/gfortran.dg/lto/bind_c-7_0.f90 (working copy)
@@ -0,0 +1,33 @@
+! { dg-lto-do run }
+! { dg-lto-options {{ -O3 -flto }} }
+! this testcase tests additional interoperability of Fortran logical
+! that is not part of the standard but needed by libgfortran.
+program main
+ logical (kind=1) :: l1
+ logical (kind=2) :: l2
+ logical (kind=4) :: l4
+ logical (kind=8) :: l8
+ logical (kind=16) :: l16
+
+ l1 = .true.
+ l2 = .true.
+ l4 = .true.
+ l8 = .true.
+ call logical_c (l1, l2, l4, l8, l16)
+ if (l1 .or. l2 .or. l4 .or. l8 .or. l16) stop 1
+end program main
+
+subroutine foo(l1, l2, l4, l8, l16)
+ logical (kind=1) :: l1
+ logical (kind=2) :: l2
+ logical (kind=4) :: l4
+ logical (kind=8) :: l8
+ logical (kind=16) :: l16
+
+ l1 = .false.
+ l2 = .false.
+ l4 = .false.
+ l8 = .false.
+ l16 = .false.
+end subroutine foo
+
Index: testsuite/gfortran.dg/lto/bind_c-7_1.c
===================================================================
--- testsuite/gfortran.dg/lto/bind_c-7_1.c (nonexistent)
+++ testsuite/gfortran.dg/lto/bind_c-7_1.c (working copy)
@@ -0,0 +1,6 @@
+
+extern void foo_ (_Bool *l1, unsigned short *l2, unsigned int *l4, unsigned
long long *l8, unsigned __int128 *l16);
+void logical_c_ (_Bool *l1, unsigned short *l2, unsigned int *l4, unsigned
long long *l8, unsigned __int128 *l16)
+{
+ foo_ (l1, l2, l4, l8, l16);
+}
Index: tree.c
===================================================================
--- tree.c (revision 272506)
+++ tree.c (working copy)
@@ -14047,6 +14053,25 @@ type_with_interoperable_signedness (cons
|| TYPE_PRECISION (type) == TYPE_PRECISION (size_type_node));
}
+/* Return type replacing TYPE for canonical type merging.
+
+ We translate BOOLEAN_TYPE of size different from C _Bool to
+ unsigned integers. This makes it possible to interoperate C
+ and Fortran on Fortran's LOGICAL types which come in different
+ sizes. This is not required by the language standard but
+ used by libgfortran. */
+
+extern tree
+type_for_canonical_type_merging (const_tree type)
+{
+ if (TREE_CODE (type) == BOOLEAN_TYPE
+ && !tree_int_cst_equal (TYPE_SIZE (type),
+ TYPE_SIZE (boolean_type_node)))
+ return lang_hooks.types.type_for_mode (TYPE_MODE (type),
+ true);
+ return const_cast <tree> (type);
+}
+
/* 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
@@ -14066,6 +14091,8 @@ gimple_canonical_types_compatible_p (con
t1 = TYPE_MAIN_VARIANT (t1);
t2 = TYPE_MAIN_VARIANT (t2);
}
+ t1 = type_for_canonical_type_merging (t1);
+ t2 = type_for_canonical_type_merging (t2);
/* Check first for the obvious case of pointer identity. */
if (t1 == t2)
Index: tree.h
===================================================================
--- tree.h (revision 272506)
+++ tree.h (working copy)
@@ -5132,9 +5141,10 @@ extern void DEBUG_FUNCTION verify_type (
extern bool gimple_canonical_types_compatible_p (const_tree, const_tree,
bool trust_type_canonical =
true);
extern bool type_with_interoperable_signedness (const_tree);
+extern tree type_for_canonical_type_merging (const_tree type);
extern bitmap get_nonnull_args (const_tree);
extern int get_range_pos_neg (tree);
/* Return simplified tree code of type that is used for canonical type
merging. */
inline enum tree_code