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.
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()?
(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.
(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.
But where? It works with all former versions of gfortran, and it works with ifort.
(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.
(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.
(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.
Happens all over SPEC sources as well :/ Tacking more -std=legacy into FFLAGS...
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.
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.
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))
(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 :-)
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.
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.
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.
(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.
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.
(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.[...]
(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.
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?
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
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.
(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?
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
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)
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.
*** Bug 91731 has been marked as a duplicate of this bug. ***
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
I think this is resolved now.
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