Bug 61527 - [11/12/13/14 Regression] [OOP] class/extends, multiple generic assignment, accept invalid
Summary: [11/12/13/14 Regression] [OOP] class/extends, multiple generic assignment, ac...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 5.0
: P5 normal
Target Milestone: 11.5
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid
Depends on:
Blocks:
 
Reported: 2014-06-16 16:05 UTC by mrestelli
Modified: 2023-07-07 10:30 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-07-12 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description mrestelli 2014-06-16 16:05:57 UTC
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
Comment 1 Dominique d'Humieres 2014-06-16 16:19:18 UTC
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.
Comment 2 mrestelli 2014-06-16 16:38:35 UTC
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.
Comment 3 Tobias Burnus 2014-07-12 21:33:55 UTC
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;
Comment 4 Dominique d'Humieres 2014-07-12 22:05:12 UTC
Confirmed per comment 3.
Comment 5 Jakub Jelinek 2014-10-30 10:39:11 UTC
GCC 4.9.2 has been released.
Comment 6 janus 2015-01-16 17:16:05 UTC
(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)
Comment 7 janus 2015-01-16 17:43:21 UTC
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)
Comment 8 Jakub Jelinek 2015-06-26 19:54:50 UTC
GCC 4.9.3 has been released.
Comment 9 Richard Biener 2016-08-03 11:41:13 UTC
GCC 4.9 branch is being closed
Comment 10 Jakub Jelinek 2018-10-26 10:23:11 UTC
GCC 6 branch is being closed
Comment 11 Richard Biener 2019-11-14 07:52:49 UTC
The GCC 7 branch is being closed, re-targeting to GCC 8.4.
Comment 12 Jakub Jelinek 2020-03-04 09:34:11 UTC
GCC 8.4.0 has been released, adjusting target milestone.
Comment 13 Jakub Jelinek 2021-05-14 09:47:15 UTC
GCC 8 branch is being closed.
Comment 14 Richard Biener 2021-06-01 08:06:20 UTC
GCC 9.4 is being released, retargeting bugs to GCC 9.5.
Comment 15 Richard Biener 2022-05-27 09:35:15 UTC
GCC 9 branch is being closed
Comment 16 Jakub Jelinek 2022-06-28 10:30:59 UTC
GCC 10.4 is being released, retargeting bugs to GCC 10.5.
Comment 17 Richard Biener 2023-07-07 10:30:21 UTC
GCC 10 branch is being closed.