Hi, I see that gfortran accepts the following code (even with strict debug flags) which is ambiguous in the resolution of the generic. The code is correctly rejected if disp2 uses CLASS(t2) instead of TYPE(t2), while with TYPE(T2) the code compiles and DISP2 is called, which I think should not be allowed. $ gfortran --version GNU Fortran (GCC) 4.10.0 20140613 (experimental) module m implicit none private public :: t1, t2, disp type :: t1 integer :: i = 1 end type t1 type, extends(t1) :: t2 real :: r = 2.0 end type t2 interface disp module procedure disp1, disp2 end interface contains subroutine disp1(x) class(t1), intent(in) :: x write(*,*) "Disp 1: ",x%i end subroutine disp1 subroutine disp2(x) type(t2), intent(in) :: x ! <- accepted !class(t2), intent(in) :: x ! <- rejected write(*,*) "Disp 2: ",x%r end subroutine disp2 end module m program p use m implicit none type(t1) :: a type(t2) :: b call disp(a) call disp(b) end program p
Up to r200946 (2013-07-14, 4.9) gfortran gives an error Error: Ambiguous interfaces 'disp2' and 'disp1' in generic interface 'disp' at (1) From at least r201266 (2013-07-26) gfortran accepts the code. I did not find any obvious culprit in this range for the change in behavior. I also don't know what is the correct behavior.
I am no expert, but I think that the correct behaviour is that of the older version: the two interfaces indeed are ambiguous, since a call like type(t2) :: b call disp(b) could call both disp1 and disp2.
It seems to be due to the following code in interface.c, which was added for PR57530 in r201329: compare_type (gfc_symbol *s1, gfc_symbol *s2) { if (s2->attr.ext_attr & (1 << EXT_ATTR_NO_ARG_CHECK)) return 1; /* TYPE and CLASS of the same declared type are type compatible, but have different characteristics. */ if ((s1->ts.type == BT_CLASS && s2->ts.type == BT_DERIVED) || (s1->ts.type == BT_DERIVED && s2->ts.type == BT_CLASS)) return 0;
Confirmed per comment 3.
GCC 4.9.2 has been released.
(In reply to Tobias Burnus from comment #3) > It seems to be due to the following code in interface.c, which was added for > PR57530 in r201329: Reverting this part of the patch ... Index: gcc/fortran/interface.c =================================================================== --- gcc/fortran/interface.c (Revision 219753) +++ gcc/fortran/interface.c (Arbeitskopie) @@ -515,12 +515,6 @@ if (s2->attr.ext_attr & (1 << EXT_ATTR_NO_ARG_CHECK)) return 1; - /* TYPE and CLASS of the same declared type are type compatible, - but have different characteristics. */ - if ((s1->ts.type == BT_CLASS && s2->ts.type == BT_DERIVED) - || (s1->ts.type == BT_DERIVED && s2->ts.type == BT_CLASS)) - return 0; - return gfc_compare_types (&s1->ts, &s2->ts) || s2->ts.type == BT_ASSUMED; } ... indeed brings back the expected error message for comment 0. However, it causes a few testsuite regressions: FAIL: gfortran.dg/dummy_procedure_4.f90 -O (test for errors, line 28) FAIL: gfortran.dg/proc_ptr_30.f90 -O (test for errors, line 25) FAIL: gfortran.dg/proc_ptr_comp_32.f90 -O (test for errors, line 34) FAIL: gfortran.dg/proc_ptr_comp_33.f90 -O (test for errors, line 14) FAIL: gfortran.dg/proc_ptr_comp_33.f90 -O (test for errors, line 54)
Reverting the whole commit of r201329 does not work either, but produces a different set of failures: FAIL: gfortran.dg/class_to_type_3.f03 -O0 (test for excess errors) FAIL: gfortran.dg/pointer_assign_8.f90 -O0 (test for excess errors) FAIL: gfortran.dg/pointer_assign_9.f90 -O0 (test for excess errors)
GCC 4.9.3 has been released.
GCC 4.9 branch is being closed
GCC 6 branch is being closed
The GCC 7 branch is being closed, re-targeting to GCC 8.4.
GCC 8.4.0 has been released, adjusting target milestone.
GCC 8 branch is being closed.
GCC 9.4 is being released, retargeting bugs to GCC 9.5.
GCC 9 branch is being closed
GCC 10.4 is being released, retargeting bugs to GCC 10.5.
GCC 10 branch is being closed.