diff mbox

[Fortran] PR 48624 - fix DECL for external procedures with proc arguments

Message ID 4DA8C6E9.5040407@net-b.de
State New
Headers show

Commit Message

Tobias Burnus April 15, 2011, 10:30 p.m. UTC
Hi all,

the following patch fixes an issue with a multiple decl for procedures 
with procedure dummy arguments. Without the patch, multiple declarations 
are generated, which causes link failures ("euler" is optimized away) 
with -fwhole-program.  (Thanks goes to Richard for spotting the problem 
with gfortran.dg/cray_pointers_8.f90.)

I have no idea why there should be a problem with inlining (cf. deleted 
comment), but removing that part did not give any test suite failure 
(check-gfortran + libgomp's check). Additionally, I have build and run 
the Polyhedron testsuite with "-march=native -ffast-math -funroll-loops 
-O3 -fno-protect-parens -finline-limit=400 -fwhole-program".

Build and tested on x86-64-linux.
OK for the trunk?

Tobias

PS: I have not created a test case; you think it should be added, one 
can copy gfortran.dg/cray_pointers_8.f90 and add a version with 
dg-options "-fwhole-file".

Comments

Steve Kargl April 15, 2011, 10:41 p.m. UTC | #1
On Sat, Apr 16, 2011 at 12:30:01AM +0200, Tobias Burnus wrote:
> 
> I have no idea why there should be a problem with inlining (cf. deleted 
> comment), but removing that part did not give any test suite failure 
> (check-gfortran + libgomp's check). Additionally, I have build and run 
> the Polyhedron testsuite with "-march=native -ffast-math -funroll-loops 
> -O3 -fno-protect-parens -finline-limit=400 -fwhole-program".

The comment comes from r170414, which suggest there is
a problem if a procedure is in an argument list, and 
that procedure gets in-lined.

laptop:kargl[205] svn log -r 170414 trans-decl.c |more
------------------------------------------------------------------------
r170414 | pault | 2011-02-22 12:33:45 -0800 (Tue, 22 Feb 2011) | 12 lines

2011-02-22  Paul Thomas  <pault@gcc.gnu.org>

        PR fortran/45743
        * trans-decl.c (gfc_get_extern_function_decl): Don't use the
        gsymbol backend_decl if the procedure has a formal argument
        that is a procedure.

2011-02-22  Paul Thomas  <pault@gcc.gnu.org>

        PR fortran/45743
        * gfortran.dg/whole_file_32.f90 : New test.

Perhaps, looking at the -fdump-tree-original on whole_file_32.f90
may shed light on the situation.
Tobias Burnus April 16, 2011, 6:34 a.m. UTC | #2
Steve Kargl wrote:
> The comment comes from r170414, which suggest there is a problem if a 
> procedure is in an argument list, and that procedure gets in-lined.
> [...]
> Perhaps, looking at the -fdump-tree-original on whole_file_32.f90 may 
> shed light on the situation.

Well, it does not. The function gets inlined - and looks OK - the 
function itself remains as it is externally visible. There is also no 
ICE, which is not surprising otherwise the testsuite had failed.

For completeness, the optimized (-O3 -finline-small-functions) dump 
looks as follows:

;; Function phload (phload_)
phload (integer(kind=4) (*<T403>) () reader)
{
   integer(kind=4) _result_reader;
<bb 2>:
   _result_reader_2 = reader_1(D) ();
   return 1;
}

;; Function main (main) (executed once)
main (integer(kind=4) argc, character(kind=1) * * argv)
{
   static integer(kind=4) options.0[8] = {68, 511, 0, 0, 0, 1, 0, 1};
<bb 2>:
   _gfortran_set_args (argc_1(D), argv_2(D));
   _gfortran_set_options (8, &options.0[0]);
   r ();
   return 0;
}


while the source file is the following:

       SUBROUTINE PHLOAD (READER,*)
       IMPLICIT NONE
       EXTERNAL         READER
       CALL READER (*1)
  1    RETURN 1
       END SUBROUTINE

       program test
       EXTERNAL R
       CALL PHLOAD (R, *999) ! This one is OK
  999  continue
       END program test


Thus: OK for the trunk?

Tobias
Richard Biener April 16, 2011, 9:28 a.m. UTC | #3
On Sat, Apr 16, 2011 at 8:34 AM, Tobias Burnus <burnus@net-b.de> wrote:
> Steve Kargl wrote:
>>
>> The comment comes from r170414, which suggest there is a problem if a
>> procedure is in an argument list, and that procedure gets in-lined.
>> [...]
>> Perhaps, looking at the -fdump-tree-original on whole_file_32.f90 may shed
>> light on the situation.
>
> Well, it does not. The function gets inlined - and looks OK - the function
> itself remains as it is externally visible. There is also no ICE, which is
> not surprising otherwise the testsuite had failed.
>
> For completeness, the optimized (-O3 -finline-small-functions) dump looks as
> follows:
>
> ;; Function phload (phload_)
> phload (integer(kind=4) (*<T403>) () reader)
> {
>  integer(kind=4) _result_reader;
> <bb 2>:
>  _result_reader_2 = reader_1(D) ();
>  return 1;
> }
>
> ;; Function main (main) (executed once)
> main (integer(kind=4) argc, character(kind=1) * * argv)
> {
>  static integer(kind=4) options.0[8] = {68, 511, 0, 0, 0, 1, 0, 1};
> <bb 2>:
>  _gfortran_set_args (argc_1(D), argv_2(D));
>  _gfortran_set_options (8, &options.0[0]);
>  r ();
>  return 0;
> }
>
>
> while the source file is the following:
>
>      SUBROUTINE PHLOAD (READER,*)
>      IMPLICIT NONE
>      EXTERNAL         READER
>      CALL READER (*1)
>  1    RETURN 1
>      END SUBROUTINE
>
>      program test
>      EXTERNAL R
>      CALL PHLOAD (R, *999) ! This one is OK
>  999  continue
>      END program test
>
>
> Thus: OK for the trunk?

Indeed all "exceptions" not to use the single backend-decl are
suspicious and may simply hide
other problems.  Note that the middle-end has to deal with indirect
calls becoming direct calls
but with mismatched arguments fine already (by simply not trying
anything fancy).  So, if you
hit problems in the middle-end with even strictly invalid Fortran
input it's a middle-end problem.

Richard.

> Tobias
>
Thomas Koenig April 16, 2011, 10:10 p.m. UTC | #4
Am 16.04.2011 08:34, schrieb Tobias Burnus:
>
> Thus: OK for the trunk?

OK. Thanks for the patch (which, incidentally, also fixes PR 48644).

	Thomas
diff mbox

Patch

2011-05-15  Tobias Burnus  <burnus@net-b.de>

	PR fortran/48624
	* trans-decl.c (gfc_get_extern_function_decl): Fix decl
	for external procedures with proc arguments.

diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 784dfc8..866720f 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -1527,7 +1527,6 @@  gfc_get_extern_function_decl (gfc_symbol * sym)
   tree name;
   tree mangled_name;
   gfc_gsymbol *gsym;
-  bool proc_formal_arg;
 
   if (sym->backend_decl)
     return sym->backend_decl;
@@ -1544,27 +1543,10 @@  gfc_get_extern_function_decl (gfc_symbol * sym)
      return the backend_decl.  */
   gsym =  gfc_find_gsymbol (gfc_gsym_root, sym->name);
 
-  /* Do not use procedures that have a procedure argument because this
-     can result in problems of multiple decls during inlining.  */
-  proc_formal_arg = false;
-  if (gsym && gsym->ns && gsym->ns->proc_name)
-    {
-      gfc_formal_arglist *formal = gsym->ns->proc_name->formal;
-      for (; formal; formal = formal->next)
-	{
-	  if (formal->sym && formal->sym->attr.flavor == FL_PROCEDURE)
-	    {
-	      proc_formal_arg = true;
-	      break;
-	    }
-	}
-    }
-
   if (gfc_option.flag_whole_file
 	&& (!sym->attr.use_assoc || sym->attr.if_source != IFSRC_DECL)
 	&& !sym->backend_decl
 	&& gsym && gsym->ns
-	&& !proc_formal_arg
 	&& ((gsym->type == GSYM_SUBROUTINE) || (gsym->type == GSYM_FUNCTION))
 	&& (gsym->ns->proc_name->backend_decl || !sym->attr.intrinsic))
     {