diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3c1b02aceb6..e1bd305f973 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2015-06-06 Jan Hubicka + + * 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 PR bootstrap/66319 diff --git a/gcc/alias.c b/gcc/alias.c index 6fa98b52e8e..6cc3aa2644e 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -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 diff --git a/gcc/gimple-expr.c b/gcc/gimple-expr.c index 022437e3a3e..d2fbe22cfc1 100644 --- a/gcc/gimple-expr.c +++ b/gcc/gimple-expr.c @@ -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. */ diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 5ba6a4f9de9..d9dffefcbdc 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,8 @@ +2015-06-06 Jan Hubicka + + * lto.c (hash_canonical_type): Do not hash TREE_CODE of TREE_TYPE of + pointers. + 2015-06-05 Aldy Hernandez * lto-lang.c (lto_write_globals): Remove. diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 735a2e70c0c..b93e512e08e 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0505e8a7950..71d38586c44 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2015-06-06 Jan Hubicka + + * 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 PR fortran/47659 diff --git a/gcc/testsuite/gcc.dg/lto/c-compatible-types_0.c b/gcc/testsuite/gcc.dg/lto/c-compatible-types-1_0.c similarity index 76% rename from gcc/testsuite/gcc.dg/lto/c-compatible-types_0.c rename to gcc/testsuite/gcc.dg/lto/c-compatible-types-1_0.c index ca33de21869..376da00599d 100644 --- a/gcc/testsuite/gcc.dg/lto/c-compatible-types_0.c +++ b/gcc/testsuite/gcc.dg/lto/c-compatible-types-1_0.c @@ -1,6 +1,5 @@ -/* { dg-do run } */ -/* { dg-options "-O3" } */ -/* { dg-skip-if "require -fno-short-enums to work" {target short_enums} } */ +/* { 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 diff --git a/gcc/testsuite/gcc.dg/lto/c-compatible-types_1.c b/gcc/testsuite/gcc.dg/lto/c-compatible-types-1_1.c similarity index 80% rename from gcc/testsuite/gcc.dg/lto/c-compatible-types_1.c rename to gcc/testsuite/gcc.dg/lto/c-compatible-types-1_1.c index ff0d16e3111..40cd07ddbbb 100644 --- a/gcc/testsuite/gcc.dg/lto/c-compatible-types_1.c +++ b/gcc/testsuite/gcc.dg/lto/c-compatible-types-1_1.c @@ -1,4 +1,5 @@ -enum a {test1, test2}; +#include +enum a {test1, test2, test3=INT_MAX}; enum a a; enum a *b; 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 index 00000000000..79be99a53c5 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/lto/bind_c-1_0.f90 @@ -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 index 00000000000..2e5a415ed99 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/lto/bind_c-1_1.c @@ -0,0 +1,36 @@ +#include +/* 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; +} + diff --git a/gcc/tree.c b/gcc/tree.c index f02eb19da9c..e92e63f91a7 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -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. */