This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch,Fortran] PR 40873 - -fwhole-program decl fixes


Le 26.07.2010 22:32, Tobias Burnus a écrit :
Dear all,

the attached patch is rather obvious - after one has found the right spots.

a) If Fortran tried first to resolve "call proc()" and then only
generated the code for "subroutine proc()", two separate declarations
where created - thus the decl of "subroutine proc()" was never called --
and therefore, with -fwhole-program, "subroutine proc()" was optimized
away - causing linker errors.

The solution is simple: When obtaining the external decl, first generate
the decl for the real procedure - and place it at the global binding level.

b) gfortran did not properly resolve procedures if they were declared
with INTERFACE, causing crashes for assumed-shape dummies. For those,
one needs to change the dummy from AS_DEFERRED to AS_ASSUMED_SHAPE, but
this was not be done for the real global symbol. Well, as consequence,
one got an ICE in trans*.c when treating it as AS_DEFERRED array.

The solution was to also handle INTERFACE; afterwards, I had to adapt
(and to conditionally disable) some checks.


Build and and currently regtesting on x86-64-linux. If there is no failure: OK for the trunk?
The extra expr.c hunk (pr45081 fix) which slipped through, is ok (and obvious).
The function decl changes are OK.
For the interface thing see below.


Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(Revision 162542)
+++ gcc/fortran/resolve.c	(Arbeitskopie)
@@ -1816,7 +1816,8 @@ resolve_global_procedure (gfc_symbol *sy
     gfc_global_used (gsym, where);

   if (gfc_option.flag_whole_file
-	&& sym->attr.if_source == IFSRC_UNKNOWN
+	&& (sym->attr.if_source == IFSRC_UNKNOWN
+	    || sym->attr.if_source == IFSRC_IFBODY)
 	&& gsym->type != GSYM_UNKNOWN
 	&& gsym->ns
 	&& gsym->ns->resolved != -1
@@ -1902,7 +1903,7 @@ resolve_global_procedure (gfc_symbol *sy
 		   sym->name, &sym->declared_at, gfc_typename (&sym->ts),
 		   gfc_typename (&def_sym->ts));

-      if (def_sym->formal)
+      if (def_sym->formal && sym->attr.if_source != IFSRC_IFBODY)
 	{
 	  gfc_formal_arglist *arg = def_sym->formal;
 	  for ( ; arg; arg = arg->next)
@@ -1969,14 +1970,19 @@ resolve_global_procedure (gfc_symbol *sy
 		       where);

 	  /* F2003, 12.3.1.1 (3b); F2008, 12.4.2.2 (3b) */
-	  if (def_sym->result->attr.pointer
-	      || def_sym->result->attr.allocatable)
+	  if ((def_sym->result->attr.pointer
+	       || def_sym->result->attr.allocatable)
+	       && (sym->attr.if_source != IFSRC_IFBODY
The above makes sense, but the 4 following lines are odd.

If I understand it correctly if there is a function definition/interface mismatch (between pointer or allocatable attributes), we generate an error asking for explicit interface (even if the symbol comes from an interface block which _is_ an explicit interface).
Well, maybe it's better than nothing after all.
+		   || def_sym->result->attr.pointer
+			!= sym->result->attr.pointer)
There is an extra parenthesis here

+ || (def_sym->result->attr.allocatable
And another one here


+			!= sym->result->attr.allocatable))
 	    gfc_error ("Function '%s' at %L with a POINTER or ALLOCATABLE "
 		       "result must have an explicit interface", sym->name,
 		       where);

 	  /* F2003, 12.3.1.1 (3c); F2008, 12.4.2.2 (3c)  */
-	  if (sym->ts.type == BT_CHARACTER
+	  if (sym->ts.type == BT_CHARACTER && sym->attr.if_source != IFSRC_IFBODY
This is going past the 80th character (OK, very minor ;) )

 	      && def_sym->ts.u.cl->length != NULL)
 	    {
 	      gfc_charlen *cl = sym->ts.u.cl;
@@ -1992,14 +1998,14 @@ resolve_global_procedure (gfc_symbol *sy
 	}

       /* F2003, 12.3.1.1 (4); F2008, 12.4.2.2 (4) */
-      if (def_sym->attr.elemental)
+      if (def_sym->attr.elemental && !sym->attr.elemental)
Same as above, I would put
if (def_sym->attr.elemental && sym->attr.if_source != IFSRC_IFBODY) like in the previous cases.
It is odd to guess interface explicitness out of symbol elementalness.


 	{
 	  gfc_error ("ELEMENTAL procedure '%s' at %L must have an explicit "
 		     "interface", sym->name, &sym->declared_at);
 	}

       /* F2003, 12.3.1.1 (5); F2008, 12.4.2.2 (5) */
-      if (def_sym->attr.is_bind_c)
+      if (def_sym->attr.is_bind_c && !sym->attr.is_bind_c)
Same here.
 	{
 	  gfc_error ("Procedure '%s' at %L with BIND(C) attribute must have "
 		     "an explicit interface", sym->name, &sym->declared_at);
@@ -2010,7 +2016,8 @@ resolve_global_procedure (gfc_symbol *sy
 	      && !(gfc_option.warn_std & GFC_STD_GNU)))
 	gfc_errors_to_warnings (1);

-      gfc_procedure_use (def_sym, actual, where);
+      if (sym->attr.if_source != IFSRC_IFBODY)
+	gfc_procedure_use (def_sym, actual, where);

       gfc_errors_to_warnings (0);
     }

The comments above are about cases where procedure definitions don't match the corresponding interfaces, which makes them invalid.
As the previous status (without -fwhole-file) was not to check at all and the patch doesn't seem to error on valid testcases, OK if it passes the testsuite.
I may try to find testcases for my comments above tomorrow.


Mikael


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]