[Patch, fortran] PR29284 - ping! (+ PRs29321/2)

Paul Thomas paulthomas2@wanadoo.fr
Tue Oct 3 16:31:00 GMT 2006


Dear All,

I need to get this out of the way rather urgently.  The allocatable 
components patch is within a few days of submission and will not go 
cleanly with this one or vice versa.  The effort of applying part of the 
patch by hand will be smaller if this one goes first.

Since it has evolved beyond the 'obvious' stage, by taking on board FX's 
remark and the subsequent two PRs, I would be  grateful if somebody 
would review it, please.

Paul
 

> FX,
>
> I believe that the attached answers all the concerns.
>
> It regtests on FC5/Athlon - OK for trunk and 4.1?
>
> Paul
>
> 2006-10-03  Paul Thomas  <pault@gcc.gnu.org>
>
>    PR fortran/29284
>    * trans-expr.c (gfc_conv_function_call): Check the expression
>    and the formal symbol are present when testing the actual
>    argument.
>
> 2006-10-03  Paul Thomas  <pault@gcc.gnu.org>
>
>    PR fortran/29284
>    * gfortran.dg/optional_assumed_charlen_1.f90: New test.
>
>    PR fortran/29321
>    PR fortran/29322
>    * gfortran.dg/missing_optional_dummy_2.f90: New test.
>
>
>>> Hi Paul,
>>>
>>>> In testing for an actual argument that is an assumed character 
>>>> length procedure, I did not test if the expression for the argument 
>>>> is NULL. This, of course, happens if an optional argument is not 
>>>> present and an ICE ensues for not doing the check. The testcase is 
>>>> that provided by the author.
>>>
>>>
>>>
>>>
>>> Doesn't the same problem happen with the block of code above the one 
>>> you fixed, ie
>>>
>>> /* If an INTENT(OUT) dummy of derived type has a default
>>> initializer, it must be (re)initialized here. */
>>> if (fsym && fsym->attr.intent == INTENT_OUT && fsym->ts.type == 
>>> BT_DERIVED
>>> && fsym->value)
>>> {
>>> gcc_assert (!fsym->attr.allocatable);
>>> tmp = gfc_trans_assignment (e, fsym->value);
>>> gfc_add_expr_to_block (&se->pre, tmp);
>>> }
>>>
>>> I think the following code exhibit this behaviour:
>>>
>>> MODULE foo
>>> TYPE T
>>> INTEGER :: I = 1
>>> END TYPE T
>>>
>>> TYPE(T),PARAMETER :: TT = T(1)
>>> CONTAINS
>>> SUBROUTINE sub1(a)
>>> TYPE(T), OPTIONAL, INTENT(OUT) :: a
>>> WRITE(*,*) 'foo bar'
>>> END SUBROUTINE sub1
>>> SUBROUTINE sub2
>>> CALL sub1()
>>> END SUBROUTINE sub2
>>> END MODULE foo
>>>
>>>
>>> Due to my limited knowledge of these matters (derived types), I'm 
>>> not sure this is allowed, although I think it is. Could you comment 
>>> on this? If this code is indeed legal, I think simply changing the 
>>> condition into "if (e && ...)" would also be correct there. I'm in 
>>> no position to regtest this last change right now, because my tree 
>>> is in an awful mess as I'm finalizing my patch for intrinsics as 
>>> actual arguments.
>>>
>>> Thanks,
>>> FX
>>>
>>>
>>
>>
>>
>
>------------------------------------------------------------------------
>
>Index: gcc/fortran/trans-expr.c
>===================================================================
>*** gcc/fortran/trans-expr.c	(revision 117347)
>--- gcc/fortran/trans-expr.c	(working copy)
>*************** gfc_conv_function_call (gfc_se * se, gfc
>*** 2006,2043 ****
>  	    } 
>  	}
>  
>!       /* If an optional argument is itself an optional dummy argument,
>! 	 check its presence and substitute a null if absent.  */
>!       if (e && e->expr_type == EXPR_VARIABLE
>! 	    && e->symtree->n.sym->attr.optional
>! 	    && fsym && fsym->attr.optional)
>! 	gfc_conv_missing_dummy (&parmse, e, fsym->ts);
>! 
>!       if (fsym && need_interface_mapping)
>! 	gfc_add_interface_mapping (&mapping, fsym, &parmse);
>  
>!       gfc_add_block_to_block (&se->pre, &parmse.pre);
>!       gfc_add_block_to_block (&post, &parmse.post);
>  
>!       /* If an INTENT(OUT) dummy of derived type has a default
>! 	 initializer, it must be (re)initialized here.  */
>!       if (fsym && fsym->attr.intent == INTENT_OUT && fsym->ts.type == BT_DERIVED
>!           && fsym->value)
>! 	{
>! 	  gcc_assert (!fsym->attr.allocatable);
>! 	  tmp = gfc_trans_assignment (e, fsym->value);
>! 	  gfc_add_expr_to_block (&se->pre, tmp);
>  	}
>  
>!       if (fsym && fsym->ts.type == BT_CHARACTER
>! 	     && parmse.string_length == NULL_TREE
>! 	     && e->ts.type == BT_PROCEDURE
>! 	     && e->symtree->n.sym->ts.type == BT_CHARACTER
>! 	     && e->symtree->n.sym->ts.cl->length != NULL)
>! 	{
>! 	  gfc_conv_const_charlen (e->symtree->n.sym->ts.cl);
>! 	  parmse.string_length = e->symtree->n.sym->ts.cl->backend_decl;
>! 	}
>  
>        /* Character strings are passed as two parameters, a length and a
>           pointer.  */
>--- 2006,2054 ----
>  	    } 
>  	}
>  
>!       if (fsym)
>! 	{
>! 	  if (e)
>! 	    {
>! 	      /* If an optional argument is itself an optional dummy
>! 		 argument, check its presence and substitute a null
>! 		 if absent.  */
>! 	      if (e->expr_type == EXPR_VARIABLE
>! 		    && e->symtree->n.sym->attr.optional
>! 		    && fsym && fsym->attr.optional)
>! 		gfc_conv_missing_dummy (&parmse, e, fsym->ts);
>! 
>! 	      /* If an INTENT(OUT) dummy of derived type has a default
>! 		 initializer, it must be (re)initialized here.  */
>! 	      if (fsym->attr.intent == INTENT_OUT
>! 		    && fsym->ts.type == BT_DERIVED
>! 		    && fsym->value)
>! 		{
>! 		  gcc_assert (!fsym->attr.allocatable);
>! 		  tmp = gfc_trans_assignment (e, fsym->value);
>! 		  gfc_add_expr_to_block (&se->pre, tmp);
>! 		}
>  
>! 	      /* Obtain the character length of an assumed character
>! 		 length procedure from the typespec.  */
>! 	      if (fsym->ts.type == BT_CHARACTER
>! 		    && parmse.string_length == NULL_TREE
>! 		    && e->ts.type == BT_PROCEDURE
>! 		    && e->symtree->n.sym->ts.type == BT_CHARACTER
>! 		    && e->symtree->n.sym->ts.cl->length != NULL)
>! 		{
>! 		  gfc_conv_const_charlen (e->symtree->n.sym->ts.cl);
>! 		  parmse.string_length
>! 			= e->symtree->n.sym->ts.cl->backend_decl;
>! 		}
>! 	    }
>  
>! 	  if (need_interface_mapping)
>! 	    gfc_add_interface_mapping (&mapping, fsym, &parmse);
>  	}
>  
>!       gfc_add_block_to_block (&se->pre, &parmse.pre);
>!       gfc_add_block_to_block (&post, &parmse.post);
>  
>        /* Character strings are passed as two parameters, a length and a
>           pointer.  */
>Index: gcc/testsuite/gfortran.dg/missing_optional_dummy_2.f90
>===================================================================
>*** gcc/testsuite/gfortran.dg/missing_optional_dummy_2.f90	(revision 0)
>--- gcc/testsuite/gfortran.dg/missing_optional_dummy_2.f90	(revision 0)
>***************
>*** 0 ****
>--- 1,40 ----
>+ ! { dg-do compile }
>+ ! Tests the fix for PR29321 and PR29322, in which ICEs occurred for the
>+ ! lack of proper attention to checking pointers in gfc_conv_function_call.
>+ !
>+ ! Contributed by Olav Vahtras  <vahtras@pdc.kth.se>
>+ ! and Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
>+ !
>+ MODULE myint
>+    TYPE NUM
>+       INTEGER :: R = 0
>+    END TYPE NUM
>+    CONTAINS 
>+       FUNCTION FUNC(A,B) RESULT(E)
>+       IMPLICIT NONE
>+       TYPE(NUM)  A,B,E
>+       INTENT(IN) ::  A,B
>+       OPTIONAL B
>+       E%R=A%R
>+       CALL SUB(A,E)
>+       END FUNCTION FUNC
>+ 
>+       SUBROUTINE SUB(A,E,B,C)
>+       IMPLICIT NONE
>+       TYPE(NUM) A,E,B,C
>+       INTENT(IN)   A,B
>+       INTENT(OUT)  E,C
>+       OPTIONAL B,C
>+       E%R=A%R
>+       END SUBROUTINE SUB
>+ END MODULE myint
>+ 
>+   if (isscan () /= 0) call abort
>+ contains
>+   integer function isscan (substr)
>+     character(*), optional :: substr
>+     if (.not.present(substr)) isscan = myscan ("foo", "over")
>+   end function isscan
>+ end
>+ ! { dg-final { cleanup-modules "myint" } }
>+ 
>Index: gcc/testsuite/gfortran.dg/optional_assumed_charlen_1.f90
>===================================================================
>*** gcc/testsuite/gfortran.dg/optional_assumed_charlen_1.f90	(revision 0)
>--- gcc/testsuite/gfortran.dg/optional_assumed_charlen_1.f90	(revision 0)
>***************
>*** 0 ****
>--- 1,20 ----
>+ ! { dg-do compile }
>+ ! Tests the fix for PR29284 in which an ICE would occur in converting
>+ ! the call to a suboutine with an assumed character length, optional
>+ ! dummy that is not present.
>+ !
>+ ! Contributed by Rakuen Himawari  <rakuen_himawari@yahoo.co.jp>
>+ !
>+       MODULE foo
>+       CONTAINS
>+         SUBROUTINE sub1(a)
>+           CHARACTER (LEN=*), OPTIONAL :: a
>+           WRITE(*,*) 'foo bar'
>+         END SUBROUTINE sub1
>+ 
>+       SUBROUTINE sub2
>+         CALL sub1()
>+       END SUBROUTINE sub2
>+ 
>+      END MODULE foo
>+ ! { dg-final { cleanup-modules "foo" } }
>  
>
>------------------------------------------------------------------------
>
>2006-10-03  Paul Thomas  <pault@gcc.gnu.org>
>
>	PR fortran/29284
>	* trans-expr.c (gfc_conv_function_call): Check the expression
>	and the formal symbol are present when testing the actual
>	argument.
>
>2006-10-03  Paul Thomas  <pault@gcc.gnu.org>
>
>	PR fortran/29284
>	* gfortran.dg/optional_assumed_charlen_1.f90: New test.
>
>	PR fortran/29321
>	PR fortran/29322
>	* gfortran.dg/missing_optional_dummy_2.f90: New test.
>  
>



More information about the Fortran mailing list