On Sun, Feb 17, 2019 at 7:19 PM Thomas Koenig <tkoe...@netcologne.de> wrote: > > Hello world, > > the attached patch fixes a rather bad ABI violation on POWER systems. > > In the absence of an explicit interface and if a procedure is not in > the same file, gfortran currently generates wrong function decls - > a longstanding problem that also creates problems with LTO, because > it (correctly) complains about mismatched declarations. > > Usually, we got lucky because the actual calling sequences generated > by the compiler with the wrong info happened to match the ones > with the correct info. However, our luck ran out on POWER because > as soon as arguments were passed in memory, things did not work > any more. The test case in question (see attachments) produced > wrong code on POWER, but merely warned with LTO on other systems. > > The method for solving this problem can be seen in the patch - if > there is no backend decl for an external procedure, simply generate > a formal argument list from the arguments. > > Regression tests turned up a few ICEs (now fixed), plus two > very invalid test cases, which I think are not worth saving.
They were added to verify we don't ICE for such invalid testcases. How do they fail now? > I suspect that this will also fix a few LTO bugs, but we can always > check that after this has been committed. > > I'd still like confirmation from one of the POWER people that > this also fixes the bug on that architecture. > > Should this still go into gcc-9? Richard has indicated in the > PR that he thinks so. I think so too, because of the severity > of the bug(s) this fixes. Any bugs resulting from this could > be either a) ICE-on-valid (easily fixed) or b) somehow generating > a wrong decl, but we are already doing this as of this moment, > so things can not really be made much worse, and a lot better. > > So, ok for trunk and for backport (with some time in between) > once gcc-8 has re-opened? The patch looks good to me. I wonder how the frontend handles the 2nd call to doesntwork_p8 for program main implicit none character :: c character(len=20) :: res, doesntwork_p8 external doesntwork_p8 c = 'o' res = doesntwork_p8(c,1,2,3,4,5,6) res = doesntwork_p8(1,2) if (res /= 'foo') stop 3 end program main at least I get no diagnostic and the patch suggests whatever call gets there first determines the backend-decl and its type? At least when I omit res = from the second call I get t.f:4:47: 4 | character(len=20) :: res, doesntwork_p8 | 1 ...... 8 | call doesntwork_p8(1,2) | Error: ‘doesntwork_p8’ at (1) has a type, which is not consistent with the CALL at (2) Does the Fortran standard say anything in how the above case should be handled? Richard. > > Regards > > Thomas > > 2019-02-17 Thomas Koenig <tkoe...@gcc.gnu.org> > > PR fortran/87689 > * trans-decl.c (gfc_get_extern_function_decl): Add argument > actual_args and pass it through to gfc_get_function_type. > * trans-expr.c (conv_function_val): Add argument actual_args > and pass it on to gfc_get_extern_function_decl. > (conv_procedure_call): Pass actual arguments to conv_function_val. > * trans-types.c (get_formal_from_actual_arglist): New function. > (gfc_get_function_type): Add argument actual_args. Generate > formal args from actual args if necessary. > * trans-types.h (gfc_get_function_type): Add optional argument. > * trans.h (gfc_get_extern_function_decl): Add optional argument. > > 2019-02-17 Thomas Koenig <tkoe...@gcc.gnu.org> > > PR fortran/87689 > * gfortran.dg/lto/20091028-1_0.f90: Remove invalid test > case. > * gfortran.dg/lto/20091028-1_1.c: Likewise. > * gfortran.dg/lto/20091028-2_0.f90: Likewise. > * gfortran.dg/lto/20091028-2_1.c: Likewise. > * gfortran.dg/lto/pr87689_0.f: New file. > * gfortran.dg/lto/pr87689_1.f: New file.