alias.c (get_alias_set): Be ready for TYPE_CANONICAL of ptr_type_node to not be ptr_t...
authorJan Hubicka <hubicka@ucw.cz>
Sun, 7 Jun 2015 21:30:58 +0000 (23:30 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sun, 7 Jun 2015 21:30:58 +0000 (21:30 +0000)
* alias.c (get_alias_set): Be ready for TYPE_CANONICAL
of ptr_type_node to not be ptr_to_node.
* tree.c (gimple_types_compatible_p): Do not match TREE_CODE of
TREE_TYPE of pointers.
* gimple-expr.c (useless_type_conversion): Reorder the check for
function pointers and TYPE_CANONICAL.
* lto.c (hash_canonical_type): Do not hash TREE_CODE of TREE_TYPE of
pointers.
* gfortran.dg/lto/bind_c-1_0.f90: New testcase.
* gfortran.dg/lto/bind_c-1_1.c: New testcase.
* gcc.dg/lto/c-compatible-types_0.c: Rename to ...
* gcc.dg/lto/c-compatible-types-1_0.c: this one; fix template
* gcc.dg/lto/c-compatible-types_1.c: Rename to ...
* gcc.dg/lto/c-compatible-types-1_1.c: this one; harden for
-fshort-enum.

From-SVN: r224201

13 files changed:
gcc/ChangeLog
gcc/alias.c
gcc/gimple-expr.c
gcc/lto/ChangeLog
gcc/lto/lto.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/lto/c-compatible-types-1_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/c-compatible-types-1_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/c-compatible-types_0.c [deleted file]
gcc/testsuite/gcc.dg/lto/c-compatible-types_1.c [deleted file]
gcc/testsuite/gfortran.dg/lto/bind_c-1_0.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/lto/bind_c-1_1.c [new file with mode: 0644]
gcc/tree.c

index 3c1b02aceb6ecf996d02fb60e8c2abddc66c7313..e1bd305f9739441c174587a79e4b3dfdcb14b241 100644 (file)
@@ -1,3 +1,12 @@
+2015-06-06  Jan Hubicka  <hubicka@ucw.cz>
+
+       * alias.c (get_alias_set): Be ready for TYPE_CANONICAL
+       of ptr_type_node to not be ptr_to_node.
+       * tree.c (gimple_types_compatible_p): Do not match TREE_CODE of
+       TREE_TYPE of pointers.
+       * gimple-expr.c (useless_type_conversion): Reorder the check for
+       function pointers and TYPE_CANONICAL.
+
 2015-06-06  John David Anglin  <danglin@gcc.gnu.org>
 
        PR bootstrap/66319
index 6fa98b52e8ecdb819f54f348b26b2bbc0d8a4526..6cc3aa2644e0ab24407f07cfc14c894a53d7267f 100644 (file)
@@ -1072,8 +1072,9 @@ get_alias_set (tree t)
     }
   /* In LTO the rules above needs to be part of canonical type machinery.
      For now just punt.  */
-  else if (POINTER_TYPE_P (t) && t != ptr_type_node && in_lto_p)
-    set = get_alias_set (ptr_type_node);
+  else if (POINTER_TYPE_P (t)
+          && t != TYPE_CANONICAL (ptr_type_node) && in_lto_p)
+    set = get_alias_set (TYPE_CANONICAL (ptr_type_node));
 
   /* Otherwise make a new alias set for this type.  */
   else
index 022437e3a3e71777c2302bb7bef66b357607f276..d2fbe22cfc1e21dcf9d78356d43f98f965166631 100644 (file)
@@ -84,6 +84,12 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
       if (TYPE_ADDR_SPACE (TREE_TYPE (outer_type))
          != TYPE_ADDR_SPACE (TREE_TYPE (inner_type)))
        return false;
+      /* Do not lose casts to function pointer types.  */
+      if ((TREE_CODE (TREE_TYPE (outer_type)) == FUNCTION_TYPE
+          || TREE_CODE (TREE_TYPE (outer_type)) == METHOD_TYPE)
+         && !(TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE
+              || TREE_CODE (TREE_TYPE (inner_type)) == METHOD_TYPE))
+       return false;
     }
 
   /* From now on qualifiers on value types do not matter.  */
@@ -142,13 +148,6 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
   else if (POINTER_TYPE_P (inner_type)
           && POINTER_TYPE_P (outer_type))
     {
-      /* Do not lose casts to function pointer types.  */
-      if ((TREE_CODE (TREE_TYPE (outer_type)) == FUNCTION_TYPE
-          || TREE_CODE (TREE_TYPE (outer_type)) == METHOD_TYPE)
-         && !(TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE
-              || TREE_CODE (TREE_TYPE (inner_type)) == METHOD_TYPE))
-       return false;
-
       /* We do not care for const qualification of the pointed-to types
         as const qualification has no semantic value to the middle-end.  */
 
index 5ba6a4f9de9c7a4e5d6cecd392e125917cb9694c..d9dffefcbdc949db3c8a0f228dd6aa22ef911a62 100644 (file)
@@ -1,3 +1,8 @@
+2015-06-06  Jan Hubicka  <hubicka@ucw.cz>
+
+       * lto.c (hash_canonical_type): Do not hash TREE_CODE of TREE_TYPE of
+       pointers.
+
 2015-06-05  Aldy Hernandez  <aldyh@redhat.com>
 
        * lto-lang.c (lto_write_globals): Remove.
index 735a2e70c0c175d02917a90064832dc579d0afbb..b93e512e08e8f2aa9710612eba37a4d1990ba98d 100644 (file)
@@ -337,12 +337,12 @@ hash_canonical_type (tree type)
   if (TREE_CODE (type) == COMPLEX_TYPE)
     hstate.add_int (TYPE_UNSIGNED (type));
 
-  /* For pointer and reference types, fold in information about the type
-     pointed to but do not recurse to the pointed-to type.  */
+  /* Fortran standard define C_PTR type that is compatible with every
+     C pointer.  For this reason we need to glob all pointers into one.
+     Still pointers in different address spaces are not compatible.  */
   if (POINTER_TYPE_P (type))
     {
       hstate.add_int (TYPE_ADDR_SPACE (TREE_TYPE (type)));
-      hstate.add_int (TREE_CODE (TREE_TYPE (type)));
     }
 
   /* For integer types hash only the string flag.  */
index 0505e8a7950575728847f9f4fc2dc1f324b12430..71d38586c446aeb8c21088c9e10ddd1c3d5e4f42 100644 (file)
@@ -1,3 +1,13 @@
+2015-06-06  Jan Hubicka  <hubicka@ucw.cz>
+
+       * gfortran.dg/lto/bind_c-1_0.f90: New testcase.
+       * gfortran.dg/lto/bind_c-1_1.c: New testcase.
+       * gcc.dg/lto/c-compatible-types_0.c: Rename to ...
+       * gcc.dg/lto/c-compatible-types-1_0.c: this one; fix template
+       * gcc.dg/lto/c-compatible-types_1.c: Rename to ...
+       * gcc.dg/lto/c-compatible-types-1_1.c: this one; harden for
+       -fshort-enum.
+
 2015-06-06  Thomas Koenig  <tkoenig@netcologne.de>
 
        PR fortran/47659
diff --git a/gcc/testsuite/gcc.dg/lto/c-compatible-types-1_0.c b/gcc/testsuite/gcc.dg/lto/c-compatible-types-1_0.c
new file mode 100644 (file)
index 0000000..376da00
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options "-O3" } */
+
+/* By C standard Each enumerated type shall be compatible with char, a  signed
+   integer, type, or an unsigned integer type. The choice of type is
+   implementation-defined.  Check that enum and unsigned int match.  */
+unsigned int a;
+unsigned int *b;
+void t();
+
+void reset ()
+{
+  asm("":"=r"(a):"0"(0));
+}
+int
+main()
+{
+  asm("":"=r"(a):"0"(1));
+  asm("":"=r"(b):"0"(&a));
+  t();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/lto/c-compatible-types-1_1.c b/gcc/testsuite/gcc.dg/lto/c-compatible-types-1_1.c
new file mode 100644 (file)
index 0000000..40cd07d
--- /dev/null
@@ -0,0 +1,20 @@
+#include <limits.h>
+enum a {test1, test2, test3=INT_MAX};
+enum a a;
+enum a *b;
+
+void reset (void);
+
+void
+t()
+{
+  if (a != test2)
+    __builtin_abort ();
+  if (*b != test2)
+    __builtin_abort ();
+  reset ();
+  if (a != test1)
+    __builtin_abort ();
+  if (*b != test1)
+    __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/lto/c-compatible-types_0.c b/gcc/testsuite/gcc.dg/lto/c-compatible-types_0.c
deleted file mode 100644 (file)
index ca33de2..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* { dg-do run } */
-/* { dg-options "-O3" } */
-/* { dg-skip-if "require -fno-short-enums to work" {target short_enums} } */
-
-/* By C standard Each enumerated type shall be compatible with char, a  signed
-   integer, type, or an unsigned integer type. The choice of type is
-   implementation-defined.  Check that enum and unsigned int match.  */
-unsigned int a;
-unsigned int *b;
-void t();
-
-void reset ()
-{
-  asm("":"=r"(a):"0"(0));
-}
-int
-main()
-{
-  asm("":"=r"(a):"0"(1));
-  asm("":"=r"(b):"0"(&a));
-  t();
-  return 0;
-}
diff --git a/gcc/testsuite/gcc.dg/lto/c-compatible-types_1.c b/gcc/testsuite/gcc.dg/lto/c-compatible-types_1.c
deleted file mode 100644 (file)
index ff0d16e..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-enum a {test1, test2};
-enum a a;
-enum a *b;
-
-void reset (void);
-
-void
-t()
-{
-  if (a != test2)
-    __builtin_abort ();
-  if (*b != test2)
-    __builtin_abort ();
-  reset ();
-  if (a != test1)
-    __builtin_abort ();
-  if (*b != test1)
-    __builtin_abort ();
-}
diff --git a/gcc/testsuite/gfortran.dg/lto/bind_c-1_0.f90 b/gcc/testsuite/gfortran.dg/lto/bind_c-1_0.f90
new file mode 100644 (file)
index 0000000..79be99a
--- /dev/null
@@ -0,0 +1,21 @@
+! { dg-do run }
+! { dg-lto-options {{ -O3 -flto }} }
+! This testcase will abort if C_PTR is not interoperable with both int *
+! and float *
+module lto_type_merge_test
+  use, intrinsic :: iso_c_binding
+  implicit none
+
+  type, bind(c) :: MYFTYPE_1
+     type(c_ptr) :: ptr
+     type(c_ptr) :: ptrb
+  end type MYFTYPE_1
+
+  type(myftype_1), bind(c, name="myVar") :: myVar
+
+contains
+  subroutine types_test() bind(c)
+    myVar%ptr = myVar%ptrb
+  end subroutine types_test
+end module lto_type_merge_test
+
diff --git a/gcc/testsuite/gfortran.dg/lto/bind_c-1_1.c b/gcc/testsuite/gfortran.dg/lto/bind_c-1_1.c
new file mode 100644 (file)
index 0000000..2e5a415
--- /dev/null
@@ -0,0 +1,36 @@
+#include <stdlib.h>
+/* interopse with myftype_1 */
+typedef struct {
+   float *ptr;
+   int *ptr2;
+} myctype_t;
+
+
+extern void abort(void);
+void types_test(void);
+/* declared in the fortran module */
+extern myctype_t myVar;
+
+int main(int argc, char **argv)
+{
+   myctype_t *cptr;
+   asm("":"=r"(cptr):"0"(&myVar));
+   cptr->ptr = (float *)(size_t) (void *)1;
+   cptr->ptr2 = (int *)(size_t) (void *)2;
+
+   types_test();
+
+   if(cptr->ptr != (float *)(size_t) (void *)2)
+      abort();
+   if(cptr->ptr2 != (int *)(size_t) (void *)2)
+      abort();
+   myVar.ptr2 = (int *)(size_t) (void *)3;
+   types_test();
+
+   if(myVar.ptr != (float *)(size_t) (void *)3)
+      abort();
+   if(myVar.ptr2 != (int *)(size_t) (void *)3)
+      abort();
+   return 0;
+}
+
index f02eb19da9c3c68dcb395b397377e6a9be78b882..e92e63f91a758f982480987f39865cba7584f389 100644 (file)
@@ -12958,18 +12958,14 @@ gimple_canonical_types_compatible_p (const_tree t1, const_tree t2,
          && TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2))
        return false;
 
-      /* For canonical type comparisons we do not want to build SCCs
-        so we cannot compare pointed-to types.  But we can, for now,
-        require the same pointed-to type kind and match what
-        useless_type_conversion_p would do.  */
+      /* Fortran standard define C_PTR type that is compatible with every
+        C pointer.  For this reason we need to glob all pointers into one.
+        Still pointers in different address spaces are not compatible.  */
       if (POINTER_TYPE_P (t1))
        {
          if (TYPE_ADDR_SPACE (TREE_TYPE (t1))
              != TYPE_ADDR_SPACE (TREE_TYPE (t2)))
            return false;
-
-         if (TREE_CODE (TREE_TYPE (t1)) != TREE_CODE (TREE_TYPE (t2)))
-           return false;
        }
 
       /* Tail-recurse to components.  */