Bug 91556 - Problems with better interface checking
Summary: Problems with better interface checking
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 10.0
: P3 enhancement
Target Milestone: ---
Assignee: Thomas Koenig
URL:
Keywords:
: 91731 (view as bug list)
Depends on:
Blocks:
 
Reported: 2019-08-27 04:57 UTC by Jürgen Reuter
Modified: 2019-09-15 08:44 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2019-08-27 00:00:00


Attachments
Reproducer (13.10 KB, text/plain)
2019-08-27 04:57 UTC, Jürgen Reuter
Details
Concept patch (527 bytes, patch)
2019-08-28 21:34 UTC, Thomas Koenig
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jürgen Reuter 2019-08-27 04:57:35 UTC
Created attachment 46763 [details]
Reproducer

This is a rather recent regression, failing with r274920, and it had been still working with r274120. The compile error is:
gfortran  -c muli_remnant.f90
muli_remnant.f90:2186:34:

 2186 |        call evolvePDF (x(0), q, f)
      |                                  1
Error: Type mismatch in argument '_formal_0' at (1); passed REAL(8) to REAL(16)
muli_remnant.f90:2192:37:

 2192 |           call evolvePDF (x(1), q, f)
      |                                     1
Error: Type mismatch in argument '_formal_0' at (1); passed REAL(8) to REAL(16)
muli_remnant.f90:2199:34:

 2199 |        call evolvePDF (x(1), q, f)
      |                                  1
Error: Type mismatch in argument '_formal_0' at (1); passed REAL(8) to REAL(16)


I will cut this further down.
Comment 1 kargl 2019-08-27 05:04:08 UTC
W(In reply to Jürgen Reuter from comment #0)
> Created attachment 46763 [details]
> Reproducer
> 
> This is a rather recent regression, failing with r274920, and it had been
> still working with r274120. The compile error is:
> gfortran  -c muli_remnant.f90
> muli_remnant.f90:2186:34:
> 
>  2186 |        call evolvePDF (x(0), q, f)
>       |                                  1
> Error: Type mismatch in argument '_formal_0' at (1); passed REAL(8) to
> REAL(16)

What are the declared types of x, q, and f?
What are the types of the dummy arguments of
evolvepdf()?
Comment 2 Jürgen Reuter 2019-08-27 05:09:22 UTC
(In reply to kargl from comment #1)
> W(In reply to Jürgen Reuter from comment #0)
> > Created attachment 46763 [details]
> > Reproducer
> > 
> > This is a rather recent regression, failing with r274920, and it had been
> > still working with r274120. The compile error is:
> > gfortran  -c muli_remnant.f90
> > muli_remnant.f90:2186:34:
> > 
> >  2186 |        call evolvePDF (x(0), q, f)
> >       |                                  1
> > Error: Type mismatch in argument '_formal_0' at (1); passed REAL(8) to
> > REAL(16)
> 
> What are the declared types of x, q, and f?
> What are the types of the dummy arguments of
> evolvepdf()?

The code is attached.
Comment 3 kargl 2019-08-27 05:19:27 UTC
(In reply to Jürgen Reuter from comment #2)
> (In reply to kargl from comment #1)
> > W(In reply to Jürgen Reuter from comment #0)
> > > Created attachment 46763 [details]
> > > Reproducer
> > > 
> > > This is a rather recent regression, failing with r274920, and it had been
> > > still working with r274120. The compile error is:
> > > gfortran  -c muli_remnant.f90
> > > muli_remnant.f90:2186:34:
> > > 
> > >  2186 |        call evolvePDF (x(0), q, f)
> > >       |                                  1
> > > Error: Type mismatch in argument '_formal_0' at (1); passed REAL(8) to
> > > REAL(16)
> > 
> > What are the declared types of x, q, and f?
> > What are the types of the dummy arguments of
> > evolvepdf()?
> 
> The code is attached.

The code is broken, and gfortran has told you.
Comment 4 Jürgen Reuter 2019-08-27 05:20:33 UTC
But where? It works with all former versions of gfortran, and it works with ifort.
Comment 5 kargl 2019-08-27 05:28:26 UTC
(In reply to kargl from comment #3)
> (In reply to Jürgen Reuter from comment #2)
> > (In reply to kargl from comment #1)
> > > W(In reply to Jürgen Reuter from comment #0)
> > > > Created attachment 46763 [details]
> > > > Reproducer
> > > > 
> > > > This is a rather recent regression, failing with r274920, and it had been
> > > > still working with r274120. The compile error is:
> > > > gfortran  -c muli_remnant.f90
> > > > muli_remnant.f90:2186:34:
> > > > 
> > > >  2186 |        call evolvePDF (x(0), q, f)
> > > >       |                                  1
> > > > Error: Type mismatch in argument '_formal_0' at (1); passed REAL(8) to
> > > > REAL(16)
> > > 
> > > What are the declared types of x, q, and f?
> > > What are the types of the dummy arguments of
> > > evolvepdf()?
> > 
> > The code is attached.
> 
> The code is broken, and gfortran has told you.

module kinds
  integer, parameter :: double    =  8   !  7..15 ! real64  ! c_double     
  integer, parameter :: quadruple = 16   ! 19..33 ! real128 ! c_float128   
  integer, parameter :: default  = quadruple
end module kinds
 
module pdf_builtin

  subroutine pdfnorm_scan (this)
    real(double) :: q, q2min, q2max
    real(double), dimension(-6:6) :: f
    real(double), dimension(0:2) :: x
    call evolvePDF (x(1), q, f)
  end subroutine pdfnorm_scan

evolvepdf is called with REAL(8), REAL(8), REAL(8)

  subroutine proton_remnant_momentum_kind_pdf (this, GeV_scale, &
       momentum_fraction, lha_flavor, valence_pdf, sea_pdf, twin_pdf)
    real(default), intent(in) :: GeV_scale, momentum_fraction
    integer, intent(in) :: lha_flavor
    real(double), dimension(-6:6) :: pdf_array
    call evolvePDF (momentum_fraction, GeV_scale, pdf_array)
  end subroutine proton_remnant_momentum_kind_pdf

evolvepdf is called with REAL(16), REAl(16), REAL(8)


evolvepdf is not generic.
Comment 6 Jürgen Reuter 2019-08-27 05:35:41 UTC
(In reply to kargl from comment #5)
> (In reply to kargl from comment #3)
> > (In reply to Jürgen Reuter from comment #2)
> > > (In reply to kargl from comment #1)
> > > > W(In reply to Jürgen Reuter from comment #0)
> > > > > Created attachment 46763 [details]
> > > > > Reproducer
> > > > > 
> > > > > This is a rather recent regression, failing with r274920, and it had been
> > > > > still working with r274120. The compile error is:
> > > > > gfortran  -c muli_remnant.f90
> > > > > muli_remnant.f90:2186:34:
> > > > > 
> > > > >  2186 |        call evolvePDF (x(0), q, f)
> > > > >       |                                  1
> > > > > Error: Type mismatch in argument '_formal_0' at (1); passed REAL(8) to
> > > > > REAL(16)
> > > > 
> > > > What are the declared types of x, q, and f?
> > > > What are the types of the dummy arguments of
> > > > evolvepdf()?
> > > 
> > > The code is attached.
> > 
> > The code is broken, and gfortran has told you.
> 
> module kinds
>   integer, parameter :: double    =  8   !  7..15 ! real64  ! c_double     
>   integer, parameter :: quadruple = 16   ! 19..33 ! real128 ! c_float128   
>   integer, parameter :: default  = quadruple
> end module kinds
>  
> module pdf_builtin
> 
>   subroutine pdfnorm_scan (this)
>     real(double) :: q, q2min, q2max
>     real(double), dimension(-6:6) :: f
>     real(double), dimension(0:2) :: x
>     call evolvePDF (x(1), q, f)
>   end subroutine pdfnorm_scan
> 
> evolvepdf is called with REAL(8), REAL(8), REAL(8)
> 
>   subroutine proton_remnant_momentum_kind_pdf (this, GeV_scale, &
>        momentum_fraction, lha_flavor, valence_pdf, sea_pdf, twin_pdf)
>     real(default), intent(in) :: GeV_scale, momentum_fraction
>     integer, intent(in) :: lha_flavor
>     real(double), dimension(-6:6) :: pdf_array
>     call evolvePDF (momentum_fraction, GeV_scale, pdf_array)
>   end subroutine proton_remnant_momentum_kind_pdf
> 
> evolvepdf is called with REAL(16), REAl(16), REAL(8)
> 
> 
> evolvepdf is not generic.

Steve, you are absolutely right. The cast of evolvePDF is always on double precision arguments, this line here:
call evolvePDF (momentum_fraction, GeV_scale, pdf_array)
should be
call evolvePDF (dble (momentum_fraction), dble(GeV_scale), pdf_array)
Sorry for the hiccup. Please close.
Comment 7 kargl 2019-08-27 05:44:41 UTC
(In reply to Jürgen Reuter from comment #6)
> (In reply to kargl from comment #5)
> > (In reply to kargl from comment #3)
> > > (In reply to Jürgen Reuter from comment #2)
> > > > (In reply to kargl from comment #1)
> > > > > W(In reply to Jürgen Reuter from comment #0)
> > > > > > Created attachment 46763 [details]
> > > > > > Reproducer
> > > > > > 
> > > > > > This is a rather recent regression, failing with r274920, and it had been
> > > > > > still working with r274120. The compile error is:
> > > > > > gfortran  -c muli_remnant.f90
> > > > > > muli_remnant.f90:2186:34:
> > > > > > 
> > > > > >  2186 |        call evolvePDF (x(0), q, f)
> > > > > >       |                                  1
> > > > > > Error: Type mismatch in argument '_formal_0' at (1); passed REAL(8) to
> > > > > > REAL(16)
> > > > > 
> > > > > What are the declared types of x, q, and f?
> > > > > What are the types of the dummy arguments of
> > > > > evolvepdf()?
> > > > 
> > > > The code is attached.
> > > 
> > > The code is broken, and gfortran has told you.
> > 
> > module kinds
> >   integer, parameter :: double    =  8   !  7..15 ! real64  ! c_double     
> >   integer, parameter :: quadruple = 16   ! 19..33 ! real128 ! c_float128   
> >   integer, parameter :: default  = quadruple
> > end module kinds
> >  
> > module pdf_builtin
> > 
> >   subroutine pdfnorm_scan (this)
> >     real(double) :: q, q2min, q2max
> >     real(double), dimension(-6:6) :: f
> >     real(double), dimension(0:2) :: x
> >     call evolvePDF (x(1), q, f)
> >   end subroutine pdfnorm_scan
> > 
> > evolvepdf is called with REAL(8), REAL(8), REAL(8)
> > 
> >   subroutine proton_remnant_momentum_kind_pdf (this, GeV_scale, &
> >        momentum_fraction, lha_flavor, valence_pdf, sea_pdf, twin_pdf)
> >     real(default), intent(in) :: GeV_scale, momentum_fraction
> >     integer, intent(in) :: lha_flavor
> >     real(double), dimension(-6:6) :: pdf_array
> >     call evolvePDF (momentum_fraction, GeV_scale, pdf_array)
> >   end subroutine proton_remnant_momentum_kind_pdf
> > 
> > evolvepdf is called with REAL(16), REAl(16), REAL(8)
> > 
> > 
> > evolvepdf is not generic.
> 
> Steve, you are absolutely right. The cast of evolvePDF is always on double
> precision arguments, this line here:
> call evolvePDF (momentum_fraction, GeV_scale, pdf_array)
> should be
> call evolvePDF (dble (momentum_fraction), dble(GeV_scale), pdf_array)
> Sorry for the hiccup. Please close.

I'll give Thomas a chance to look at the bug.  This is a new feature 
for gfortran that tries to track (external) subprogram interfaces.  The
error message seems odd to me

 2186 |        call evolvePDF (x(0), q, f)
      |                                  1
  Error: Type mismatch in argument '_formal_0' at (1); passed REAL(8)
  to REAL(16)

I would hope that the error could use an argument name, e.g., 
example.

 2186 |        call evolvePDF (x(0), q, f)
      |                                  1
   Error: Type mismatch in argument 'f' at (1); passed REAL(8) to REAL(16)

If gfortran told a user the problem was with the type of 'f', then one
could check the the types of 'f' and the dummy argument.

If you look through the last week or so of fortran mailing list, you'll
see that Thomas has discovered a large number of argument mismatch problems.
Comment 8 Richard Biener 2019-08-27 10:26:41 UTC
Happens all over SPEC sources as well :/  Tacking more -std=legacy into FFLAGS...
Comment 9 Thomas Koenig 2019-08-27 15:57:19 UTC
After r274937, the new flag -fallow-argument-mismatch can also be used.

Now, I agree that the error message can be improved - the _formal_...
argument names can be improved, it would probably a better idea
to refer to the place that the declaration came from in that case.

I'll do this, but it will probably be a couple of weeks until I can
come up with something - too many things happening in Real Life (TM)
at the moment.
Comment 10 Thomas Koenig 2019-08-28 21:34:36 UTC
Created attachment 46776 [details]
Concept patch

Here's what a patch could look like.

With the test case, it yields

multi.f90:2186:23:

 2186 |        call evolvePDF (x(0), q, f)
      |                       1
......
 2362 |     call evolvePDF (momentum_fraction, GeV_scale, sea_pdf)
      |                    2   
Error: Type mismatch between argument passed at (1) and previous call at (2) (REAL(8)/REAL(16))
multi.f90:2192:26:

 2192 |           call evolvePDF (x(1), q, f)
      |                          1
......
 2362 |     call evolvePDF (momentum_fraction, GeV_scale, sea_pdf)
      |                    2      
Error: Type mismatch between argument passed at (1) and previous call at (2) (REAL(8)/REAL(16))
multi.f90:2199:23:

 2199 |        call evolvePDF (x(1), q, f)
      |                       1
......
 2362 |     call evolvePDF (momentum_fraction, GeV_scale, sea_pdf)
      |                    2   
Error: Type mismatch between argument passed at (1) and previous call at (2) (REAL(8)/REAL(16))

I suppose this would be a bit more helpful.
Comment 11 Steve Kargl 2019-08-28 21:49:21 UTC
On Wed, Aug 28, 2019 at 09:34:36PM +0000, tkoenig at gcc dot gnu.org wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91556
> 
> multi.f90:2199:23:
> 
>  2199 |        call evolvePDF (x(1), q, f)
>       |                       1
> ......
>  2362 |     call evolvePDF (momentum_fraction, GeV_scale, sea_pdf)
>       |                    2   
> Error: Type mismatch between argument passed at (1) and previous call at (2)
> (REAL(8)/REAL(16))
> 
> I suppose this would be a bit more helpful.
> 

Yes, I think is is quite helpful.  The word "previous" seems
odd with the locus pointers.  (1) is the first call in line
2199, and (2) is next call in line 2362.  I would say that
line 2199 contains the "previous" call.  Perhaps, 

Error: Type mismatch between argument passed at (1) and argument
passed at (2) (REAL(8)/REAL(16))

or

Error: Type mismatch between actual argument at (1) and actual
argument at (2) (REAL(8)/REAL(16))
Comment 12 Thomas Koenig 2019-08-29 05:32:39 UTC
(In reply to Steve Kargl from comment #11)

> Error: Type mismatch between actual argument at (1) and actual
> argument at (2) (REAL(8)/REAL(16))

That sounds _much_ better (and is also shorter). When I am back again, I will
use this and extend it to the other cases (rank, character length and maybe
others as well).

If you feel that this should be done earlier and would like to do this
yourself, that is also no problem :-)
Comment 13 Steve Kargl 2019-08-29 06:02:15 UTC
On Thu, Aug 29, 2019 at 05:32:39AM +0000, tkoenig at gcc dot gnu.org wrote:
> --- Comment #12 from Thomas Koenig <tkoenig at gcc dot gnu.org> ---
> (In reply to Steve Kargl from comment #11)
> 
> > Error: Type mismatch between actual argument at (1) and actual
> > argument at (2) (REAL(8)/REAL(16))
> 
> That sounds _much_ better (and is also shorter). When I am back again, I will
> use this and extend it to the other cases (rank, character length and maybe
> others as well).
> 
> If you feel that this should be done earlier and would like to do this
> yourself, that is also no problem :-)
> 

I'm currently looking at the next round of Gerhard bug reports. ;-)

I don't think this too critical, so whenever you (or a lurker on the
fortran@ list) comes up with some better, feel free to commit.
Comment 14 anlauf 2019-08-29 18:49:15 UTC
The current solution is a bit annoying for implicitly-derived interfaces.

Consider a code like:

module foo
  implicit none
  type t1
     integer :: i = 1
  end type t1
  type t2
     integer :: j = 2
  end type t2
contains
  subroutine s1 (x)
    type(t1) :: x
    call my_mpi_bcast_wrapper (x, storage_size (x)/8)
  end subroutine s1
  subroutine s2 (y)
    type(t2) :: y
    call my_mpi_bcast_wrapper (y, storage_size (y)/8)
  end subroutine s2
end module foo

That's perfectly legal, but gets rejected unless -fallow-argument-mismatch
is specified.  But then I still get a warning (or many if this appears in
a large module).

I know that there is a (quite clumsy) solution to the above by providing
many dummy interfaces, just to defeat the checking.

I would like to see an error only for explicit interfaces.  But e.g. for
packages like MPI, where the mpi_* routines can handle different argument
types, and where by default one doesn't need (or want) an explicit interface,
I'd hope that that the checks could be downgraded.
Comment 15 Steve Kargl 2019-08-29 19:15:09 UTC
On Thu, Aug 29, 2019 at 06:49:15PM +0000, anlauf at gcc dot gnu.org wrote:
> module foo
>   implicit none
>   type t1
>      integer :: i = 1
>   end type t1
>   type t2
>      integer :: j = 2
>   end type t2
> contains
>   subroutine s1 (x)
>     type(t1) :: x
>     call my_mpi_bcast_wrapper (x, storage_size (x)/8)
>   end subroutine s1
>   subroutine s2 (y)
>     type(t2) :: y
>     call my_mpi_bcast_wrapper (y, storage_size (y)/8)
>   end subroutine s2
> end module foo
> 
> That's perfectly legal, but gets rejected unless -fallow-argument-mismatch
> is specified.  But then I still get a warning (or many if this appears in
> a large module).

You can get rid of the warning with -w.
Comment 16 anlauf 2019-08-29 19:18:01 UTC
(In reply to Steve Kargl from comment #15)
> On Thu, Aug 29, 2019 at 06:49:15PM +0000, anlauf at gcc dot gnu.org wrote:
> > module foo
> >   implicit none
> >   type t1
> >      integer :: i = 1
> >   end type t1
> >   type t2
> >      integer :: j = 2
> >   end type t2
> > contains
> >   subroutine s1 (x)
> >     type(t1) :: x
> >     call my_mpi_bcast_wrapper (x, storage_size (x)/8)
> >   end subroutine s1
> >   subroutine s2 (y)
> >     type(t2) :: y
> >     call my_mpi_bcast_wrapper (y, storage_size (y)/8)
> >   end subroutine s2
> > end module foo
> > 
> > That's perfectly legal, but gets rejected unless -fallow-argument-mismatch
> > is specified.  But then I still get a warning (or many if this appears in
> > a large module).
> 
> You can get rid of the warning with -w.

That would get rid of all warnings.
Comment 17 Steve Kargl 2019-08-29 19:33:06 UTC
On Thu, Aug 29, 2019 at 07:18:01PM +0000, anlauf at gcc dot gnu.org wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91556
> 
> --- Comment #16 from anlauf at gcc dot gnu.org ---
> (In reply to Steve Kargl from comment #15)
> > On Thu, Aug 29, 2019 at 06:49:15PM +0000, anlauf at gcc dot gnu.org wrote:
> > > 
> > > That's perfectly legal, but gets rejected unless -fallow-argument-mismatch
> > > is specified.  But then I still get a warning (or many if this appears in
> > > a large module).
> > 
> > You can get rid of the warning with -w.
> 
> That would get rid of all warnings.
> 

Yes, that is a down side to writing code with implicit
interfaces.  There is no excuse for not using proper
explicit interfaces in modern Fortran.
Comment 18 Thomas Koenig 2019-08-29 21:38:09 UTC
(In reply to anlauf from comment #14)
> The current solution is a bit annoying for implicitly-derived interfaces.
> 
> Consider a code like:
> 
> module foo
>   implicit none
>   type t1
>      integer :: i = 1
>   end type t1
>   type t2
>      integer :: j = 2
>   end type t2
> contains
>   subroutine s1 (x)
>     type(t1) :: x
>     call my_mpi_bcast_wrapper (x, storage_size (x)/8)
>   end subroutine s1
>   subroutine s2 (y)
>     type(t2) :: y
>     call my_mpi_bcast_wrapper (y, storage_size (y)/8)
>   end subroutine s2
> end module foo
> 
> That's perfectly legal,

This is illegal, as far as I know. The type names are different,
which makes them different types.

To quote 7.5.2.4  Determination of derived types

Two data entities have the same type if they are declared with reference to the same derived-type definition. Data
entities also have the same type if they are declared with reference to different derived-type definitions that specify
the same type name, all have the SEQUENCE attribute or all have the BIND attribute, have no components
with PRIVATE accessibility, and have components that agree in order, name, and attributes. Otherwise, they
are of different derived types.[...]
Comment 19 anlauf 2019-08-30 19:43:54 UTC
(In reply to Thomas Koenig from comment #18)
> (In reply to anlauf from comment #14)
> > The current solution is a bit annoying for implicitly-derived interfaces.
> > 
> > Consider a code like:
> > 
> > module foo
> >   implicit none
> >   type t1
> >      integer :: i = 1
> >   end type t1
> >   type t2
> >      integer :: j = 2
> >   end type t2
> > contains
> >   subroutine s1 (x)
> >     type(t1) :: x
> >     call my_mpi_bcast_wrapper (x, storage_size (x)/8)
> >   end subroutine s1
> >   subroutine s2 (y)
> >     type(t2) :: y
> >     call my_mpi_bcast_wrapper (y, storage_size (y)/8)
> >   end subroutine s2
> > end module foo
> > 
> > That's perfectly legal,
> 
> This is illegal, as far as I know. The type names are different,
> which makes them different types.

Of course the types are different - that's the point!

The above is an attempt to extract a self-contained example demonstrating
what does happen in real-world codes using MPI.  You can convert it to the
real thing yourself (see e.g. man mpi_bcast).

What I wanted to say: in many codes using MPI, the 'buffer' argument of MPI_*
can be of any type or kind, provided the other arguments are appropriately
set.  There is no explicit interface - the library routines may not even be
written in Fortran - and there cannot be any reasonable inference from an
implicit interface.  Using this to generate an error *by default* is not a
good idea. 

The same problem shows up for me in parts of the code using direct calls to
BLAS (again, no explicit interfaces), or to NetCDF.  I guess this is similar
to the issues people reported for the SPEC codes.

The recommendation to use -fallow-argument-mismatch to downgrade this to a
warning (not silence it!) does not really solve the issue: the signal-to-noise
ratio of gfortran warnings has become close to useless.  (Just ask colleagues
whether they pay attention to warnings.)

And do you really want users to add -w to the list of options?
If you think about it, you might conclude that this will do gfortran a
poor service.

I'll stop ranting now.
Comment 20 Steve Kargl 2019-08-30 20:01:36 UTC
On Fri, Aug 30, 2019 at 07:43:54PM +0000, anlauf at gcc dot gnu.org wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91556
> 
> --- Comment #19 from anlauf at gcc dot gnu.org ---
> (In reply to Thomas Koenig from comment #18)
> > (In reply to anlauf from comment #14)
> > > The current solution is a bit annoying for implicitly-derived interfaces.
> > > 
> > > Consider a code like:
> > > 
> > > module foo
> > >   implicit none
> > >   type t1
> > >      integer :: i = 1
> > >   end type t1
> > >   type t2
> > >      integer :: j = 2
> > >   end type t2
> > > contains
> > >   subroutine s1 (x)
> > >     type(t1) :: x
> > >     call my_mpi_bcast_wrapper (x, storage_size (x)/8)
> > >   end subroutine s1
> > >   subroutine s2 (y)
> > >     type(t2) :: y
> > >     call my_mpi_bcast_wrapper (y, storage_size (y)/8)
> > >   end subroutine s2
> > > end module foo
> > > 
> > > That's perfectly legal,
> > 
> > This is illegal, as far as I know. The type names are different,
> > which makes them different types.
> 
> Of course the types are different - that's the point!
> 
> The above is an attempt to extract a self-contained example demonstrating
> what does happen in real-world codes using MPI.  You can convert it to the
> real thing yourself (see e.g. man mpi_bcast).
> 

From the Fortran standard (actually 18-007r1.pdf), page 304.

15.5.2.4 Ordinary dummy variables

2 The dummy argument shall be type compatible with the actual argument.

How can the dummy argument be type compatiable with two distinct
different types for the actual arguments x and y in your example?
Comment 21 Steve Kargl 2019-08-30 21:18:19 UTC
On Thu, Aug 29, 2019 at 09:38:09PM +0000, tkoenig at gcc dot gnu.org wrote:
> --- Comment #18 from Thomas Koenig <tkoenig at gcc dot gnu.org> ---
> (In reply to anlauf from comment #14)
> > The current solution is a bit annoying for implicitly-derived interfaces.
> > 
> > Consider a code like:
> > 
> > module foo
> >   implicit none
> >   type t1
> >      integer :: i = 1
> >   end type t1
> >   type t2
> >      integer :: j = 2
> >   end type t2
> > contains
> >   subroutine s1 (x)
> >     type(t1) :: x
> >     call my_mpi_bcast_wrapper (x, storage_size (x)/8)
> >   end subroutine s1
> >   subroutine s2 (y)
> >     type(t2) :: y
> >     call my_mpi_bcast_wrapper (y, storage_size (y)/8)
> >   end subroutine s2
> > end module foo
> > 
> > That's perfectly legal,
> 
> This is illegal, as far as I know. The type names are different,
> which makes them different types.
> 

Thomas,

I'll leave this to whatever you decide.  gfortran could
do -fallow-argument-mismatch=n. n=0 is an error, n=1
is for a warning, and n>1 silences the warning. n=0 would
be the default setting as I think the error messages 
will encourage people to fix their codes.

PS: the MPI argument is somewhat bogus.  At least, OpenMPI
has an Fortran 2008 interface for mpi_bcast() (ie., 
11 years ago).

USE mpi_f08
MPI_Bcast(buffer, count, datatype, root, comm, ierror)
    TYPE(*), DIMENSION(..) :: buffer
    INTEGER, INTENT(IN) :: count, root
    TYPE(MPI_Datatype), INTENT(IN) :: datatype
    TYPE(MPI_Comm), INTENT(IN) :: comm
    INTEGER, OPTIONAL, INTENT(OUT) :: ierror
Comment 22 Thomas Koenig 2019-09-01 20:52:44 UTC
A problem with such code is that type violations like that are likely to cause
actual wrong code issues because much of the aliasing analysis is type based...

What I could do is to

a) restrict the number of warnings for each routine to one (put a flag
   Into the gsym)

b) try to figure something out to make this harmless to the middle end... like
   passing a void* instead of a reference.

If we just continue to ignore this error, is is going to bite people sooner or
later. And wehn somevody finds that a complex  MPI code no longer works, I want
to have that warning in the build log.

Also, this sort of code is a major obstacle for LTO, If we do not fix this, then
I might as well give up on making gfortran LTO clean.
Comment 23 anlauf 2019-09-02 18:51:23 UTC
(In reply to Thomas Koenig from comment #22)
> A problem with such code is that type violations like that are likely to
> cause
> actual wrong code issues because much of the aliasing analysis is type
> based...
> 
> What I could do is to
> 
> a) restrict the number of warnings for each routine to one (put a flag
>    Into the gsym)
> 
> b) try to figure something out to make this harmless to the middle end...
> like
>    passing a void* instead of a reference.

I do see that there was a motivation for the change.  However, I think that
the resolution happens at the wrong time and comes to wrong conclusions.

The example in comment#14 compiles if I add e.g.

  interface
     subroutine my_mpi_bcast_wrapper (buffer, len)
       type(*), dimension(..) :: buffer
       integer, intent(in)    :: len
     end subroutine my_mpi_bcast_wrapper
  end interface

which I think is the appropriate explicit interface *if* it needs to be
explicitly given.  Then the code compiles without any warnings.

> If we just continue to ignore this error, is is going to bite people sooner
> or
> later. And wehn somevody finds that a complex  MPI code no longer works, I
> want
> to have that warning in the build log.

A warning by default would be fine with me, especially when it can be turned
off.  I am not happy to make this an error.
(I may have a different opinion for a varying number of arguments to a
procedure.)

> Also, this sort of code is a major obstacle for LTO, If we do not fix this,
> then
> I might as well give up on making gfortran LTO clean.

Is the current treatment only necessary for LTO?

How does LTO handle TYPE(*) etc.?  It has to be able to deal with it!

Otherwise, can procedures without explicit interfaces be marked that they
are not eligible to this kind of optimization?
Comment 24 Steve Kargl 2019-09-03 02:25:57 UTC
On Mon, Sep 02, 2019 at 06:51:23PM +0000, anlauf at gcc dot gnu.org wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91556
> 
> --- Comment #23 from anlauf at gcc dot gnu.org ---
> (In reply to Thomas Koenig from comment #22)
> > A problem with such code is that type violations like that are likely to
> > cause
> > actual wrong code issues because much of the aliasing analysis is type
> > based...
> > 
> > What I could do is to
> > 
> > a) restrict the number of warnings for each routine to one (put a flag
> >    Into the gsym)
> > 
> > b) try to figure something out to make this harmless to the middle end...
> > like
> >    passing a void* instead of a reference.
> 
> I do see that there was a motivation for the change.  However, I think that
> the resolution happens at the wrong time and comes to wrong conclusions.
> 
> The example in comment#14 compiles if I add e.g.
> 
>   interface
>      subroutine my_mpi_bcast_wrapper (buffer, len)
>        type(*), dimension(..) :: buffer
>        integer, intent(in)    :: len
>      end subroutine my_mpi_bcast_wrapper
>   end interface
> 
> which I think is the appropriate explicit interface *if* it needs to be
> explicitly given.  Then the code compiles without any warnings.

This is exactly why TYPE(*) was added to the Fortran standard.
I would need to good spelunking on the J3 website, but I vaguely
recal that Craig Rassmussen from the OpenMP standard committee
championed it.  From the Fortran 2018 standard

   An entity that is declared using the TYPE(*) type specifier is
   assumed-type and is an unlimited polymorphic entity.  It is not
   declared to have a type, and is not considered to have the same
   declared type as any other entity, including another unlimited
   polymorphic entity.  Its dynamic type and type parameters are
   assumed from its effective argument.

Adding the INTERFACE in the code from comment #14 allows gfortran
to use the effective type in the function calls.

> > If we just continue to ignore this error, is is going to bite people sooner
> > or
> > later. And wehn somevody finds that a complex  MPI code no longer works, I
> > want
> > to have that warning in the build log.
> 
> A warning by default would be fine with me, especially when it can be turned
> off.  I am not happy to make this an error.
> (I may have a different opinion for a varying number of arguments to a
> procedure.)
> 
> > Also, this sort of code is a major obstacle for LTO, If we do not fix this,
> > then
> > I might as well give up on making gfortran LTO clean.
> 
> Is the current treatment only necessary for LTO?

Of course.  Thomas quoted a part of the standard that indicate 
the code is invalid Fortran.  I quoted a different line from the
standard that indicates the code is invalid Fortran.  gfortran
is informing the user the code is broken.

> Otherwise, can procedures without explicit interfaces be marked that they
> are not eligible to this kind of optimization?

It seems that you missed an important aspect of Thomas's patch.  It
allows one to find suspect subprogram references when the subprograms
are implicitly defined.  Go read the first 6 comments in the PR.
Jurgen had a bug in his code.  Thomas's patch generated an error 
pointing to the problem.  With Jurgen's code, there is a big difference
in passing a double precision value as opposed to the desired quad
precision value.

I'm having a hard time understanding why you think gfortran should
continue to silently compile invalid, and possibly broken, code
instead of actually alerting a user of an issue.  I'm having an
even harder time understanding why you want to have the ability
to completely disable the
Comment 25 Mario Baumann 2019-09-09 11:21:05 UTC
Hi all,

the following fortran code (without module/interface statements)

      SUBROUTINE FOO (A)
      IMPLICIT NONE
      DOUBLE PRECISION :: A(2)
      DOUBLE PRECISION :: B(2)
      CALL GOO (A(1))
      CALL GOO (B)
      END

returns a similar error:

> /Gcc/10.0.0/bin/gfortran -c foo.F
foo.F:6:16:

    6 |       CALL GOO (B)
      |                1
Error: Rank mismatch in argument '_formal_0' at (1) (scalar and rank-1)


> /Gcc/10.0.0/bin/gfortran -v
Using built-in specs.
COLLECT_GCC=/Gcc/10.0.0/bin/gfortran
COLLECT_LTO_WRAPPER=/Gcc/10.0.0/libexec/gcc/x86_64-apple-darwin17/10.0.0/lto-wrapper
Target: x86_64-apple-darwin17
Configured with: /Gcc/10.0.0/.src/configure --prefix=/Gcc/10.0.0 --build=x86_64-apple-darwin17 --enable-languages=c,c++,fortran --enable-lto --enable-stage1-checking --enable-libstdcxx-time --disable-nls --disable-libquadmath --disable-libquadmath-support --with-ld=/opt/local/bin/ld --with-ar=/opt/local/bin/ar --with-as=/opt/local/bin/as --with-system-zlib --with-pkgversion=svn-revision-275501
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.0.0 20190909 (experimental) (svn-revision-275501)
Comment 26 Steve Kargl 2019-09-09 14:02:49 UTC
On Mon, Sep 09, 2019 at 11:21:05AM +0000, mario-baumann at web dot de wrote:
> 
> --- Comment #25 from Mario Baumann <mario-baumann at web dot de> ---
> 
> the following fortran code (without module/interface statements)
> 
>       SUBROUTINE FOO (A)
>       IMPLICIT NONE
>       DOUBLE PRECISION :: A(2)
>       DOUBLE PRECISION :: B(2)
>       CALL GOO (A(1))
>       CALL GOO (B)
>       END
> 
> returns a similar error:
> 
> > /Gcc/10.0.0/bin/gfortran -c foo.F
> foo.F:6:16:
> 
>     6 |       CALL GOO (B)
>       |                1
> Error: Rank mismatch in argument '_formal_0' at (1) (scalar and rank-1)
> 

You can use the -fallow-argument-mismatch option to
degrade the error to warning.  You'll continue to 
get a warning until you fix the code.
Comment 27 Thomas Koenig 2019-09-11 09:08:22 UTC
*** Bug 91731 has been marked as a duplicate of this bug. ***
Comment 28 Thomas Koenig 2019-09-14 20:41:27 UTC
Author: tkoenig
Date: Sat Sep 14 20:40:55 2019
New Revision: 275719

URL: https://gcc.gnu.org/viewcvs?rev=275719&root=gcc&view=rev
Log:
2019-09-14  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/91557
	PR fortran/91556
	* frontend-passes.c (check_externals_procedure): Reformat argument
	list. Use gfc_compare_actual_formal instead of gfc_procedure_use.
	* gfortran.h (gfc_symbol): Add flag error.
	* interface.c (gfc_compare_interfaces): Reformat.
	(argument_rank_mismatch): Add where_formal argument. If it is
	present, note that the error is between different calls.
	(compare_parameter): Change warnings that previously dependended
	on -Wargument-mismatch to unconditional.  Issue an error / warning
	on type mismatch only once.  Pass where_formal to
	argument_rank_mismatch for artificial variables.
	(compare_actual_formal): Change warnings that previously
	dependeded on -Wargument-mismatch to unconditional.
	(gfc_check_typebound_override): Likewise.
	(gfc_get_formal_from_actual_arglist): Set declared_at for
	artificial symbol.
	* invoke.texi: Extend description of -fallow-argument-mismatch.
	Delete -Wargument-mismatch.
	* lang.opt: Change -Wargument-mismatch to do-nothing option.
	* resolve.c (resolve_structure_cons): Change warnings that
	previously depended on -Wargument-mismatch to unconditional.
	* trans-decl.c (generate_local_decl): Do not warn if the symbol is
	artificial.

2019-09-14  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/91557
	PR fortran/91556
	* gfortran.dg/argument_checking_20.f90: New test.
	* gfortran.dg/argument_checking_21.f90: New test.
	* gfortran.dg/argument_checking_22.f90: New test.
	* gfortran.dg/argument_checking_23.f90: New test.
	* gfortran.dg/warn_unused_dummy_argument_5.f90: New test.
	* gfortran.dg/bessel_3.f90: Add pattern for type mismatch.
	* gfortran.dg/g77/20010519-1.f: Adjust dg-warning messages to new
	handling.
	* gfortran.dg/pr24823.f: Likewise.
	* gfortran.dg/pr39937.f: Likewise.


Added:
    trunk/gcc/testsuite/gfortran.dg/argument_checking_20.f90
    trunk/gcc/testsuite/gfortran.dg/argument_checking_21.f90
    trunk/gcc/testsuite/gfortran.dg/argument_checking_22.f90
    trunk/gcc/testsuite/gfortran.dg/argument_checking_23.f90
    trunk/gcc/testsuite/gfortran.dg/warn_unused_dummy_argument_5.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/frontend-passes.c
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/interface.c
    trunk/gcc/fortran/invoke.texi
    trunk/gcc/fortran/lang.opt
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/bessel_3.f90
    trunk/gcc/testsuite/gfortran.dg/g77/20010519-1.f
    trunk/gcc/testsuite/gfortran.dg/pr24823.f
    trunk/gcc/testsuite/gfortran.dg/pr39937.f
Comment 29 Thomas Koenig 2019-09-14 20:42:15 UTC
I think this is resolved now.
Comment 30 Thomas Koenig 2019-09-15 08:44:14 UTC
Author: tkoenig
Date: Sun Sep 15 08:43:42 2019
New Revision: 275726

URL: https://gcc.gnu.org/viewcvs?rev=275726&root=gcc&view=rev
Log:
2019-09-15  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/91556
	* gfortran.dg/warn_argument_mismatch_1.f90: Remove.


Removed:
    trunk/gcc/testsuite/gfortran.dg/warn_argument_mismatch_1.f90
Modified:
    trunk/gcc/testsuite/ChangeLog