Hi, I constructed this testcase as I anticipated a bogus warning. It does not happen because C_FUNPTR is function pointer and useless_type_conversion does not look into function signature, but it is still useful testcase to have. Once we start to do TBAA for pointers, we will end up in need to glob C_FUNPTR with void * to make it universal.
regtested ppc64le-linux, will commit it shortly. Honza * gfortran.dg/lto/bind_c-5_0.f90: New testcase. * gfortran.dg/lto/bind_c-5_1.c: New testcase. Index: bind_c-5_0.f90 =================================================================== --- bind_c-5_0.f90 (revision 0) +++ bind_c-5_0.f90 (working copy) @@ -0,0 +1,17 @@ +! { dg-lto-do run } +! { dg-lto-options {{ -O3 -flto }} } +! This testcase will abort if C_FUNPTR is not interoperable with both int * +! and float * +module lto_type_merge_test + use, intrinsic :: iso_c_binding + implicit none + + type(c_funptr), bind(c, name="myVar") :: myVar + type(c_funptr), bind(c, name="myVar2") :: myVar2 + +contains + subroutine types_test() bind(c) + myVar = myVar2 + end subroutine types_test +end module lto_type_merge_test + Index: bind_c-5_1.c =================================================================== --- bind_c-5_1.c (revision 0) +++ bind_c-5_1.c (working copy) @@ -0,0 +1,31 @@ +#include <stdlib.h> +/* declared in the fortran module */ +extern int (*myVar) (int); +extern float (*myVar2) (float); +void types_test(void); + + +extern void abort(void); + +int main(int argc, char **argv) +{ + int (**myptr) (int); + float (**myptr2) (float); + asm("":"=r"(myptr):"0"(&myVar)); + asm("":"=r"(myptr2):"0"(&myVar2)); + *myptr = (int (*) (int)) (size_t) (void *)1; + *myptr2 = (float (*) (float)) (size_t) (void *)2; + types_test(); + if (*myptr != (int (*) (int)) (size_t) (void *)2) + abort (); + if (*myptr2 != (float (*) (float)) (size_t) (void *)2) + abort (); + *myptr2 = (float (*) (float)) (size_t) (void *)3; + types_test(); + if (*myptr != (int (*) (int)) (size_t) (void *)3) + abort (); + if (*myptr2 != (float (*) (float)) (size_t) (void *)3) + abort (); + return 0; +} +