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]

[Patch, fortran] PR31211 - wrong code generated for pointer returning function as actual argument


:ADDPATCH fortran:

This one is easy.  Scalar pointer functions were de-referenced in
gfc_conv_expr_reference and then an address expression built.  This
did not help the cause when the result was null()!  The fix adds an
extra block to this function, such that the pointer result is
returned.  Note that arrays are handled, correctly elsewhere.

Bootstrapped and regtested on x86_ia64 - OK for trunk?

Paul

2007-07-27  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/31211
	* trans-expr.c (gfc_conv_expr_reference): Add block for case of
	scalar pointer functions so that NULL result is correctly
	handled.

2007-07-27  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/31211
	* gfortran.dg/actual_pointer_function_1.f90: New test.

-- 
I love deadlines. I love the whooshing sound they make as they go by.
--Douglas Adams
Index: gcc/fortran/trans-expr.c
===================================================================
*** gcc/fortran/trans-expr.c	(revision 126961)
--- gcc/fortran/trans-expr.c	(working copy)
*************** gfc_conv_expr_reference (gfc_se * se, gf
*** 3342,3347 ****
--- 3342,3360 ----
        return;
      }
  
+   if (expr->expr_type == EXPR_FUNCTION
+ 	&& expr->symtree->n.sym->attr.pointer
+ 	&& !expr->symtree->n.sym->attr.dimension)
+     {
+       se->want_pointer = 1;
+       gfc_conv_expr (se, expr);
+       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
+       gfc_add_modify_expr (&se->pre, var, se->expr);
+       se->expr = var;
+       return;
+     }
+ 
+ 
    gfc_conv_expr (se, expr);
  
    /* Create a temporary var to hold the value.  */
Index: gcc/testsuite/gfortran.dg/actual_pointer_function_1.f90
===================================================================
*** gcc/testsuite/gfortran.dg/actual_pointer_function_1.f90	(revision 0)
--- gcc/testsuite/gfortran.dg/actual_pointer_function_1.f90	(revision 0)
***************
*** 0 ****
--- 1,33 ----
+ ! { dg-do run }
+ ! Tests the fix for PR31211, in which the value of the result for
+ ! cp_get_default_logger was stored as a temporary, rather than the
+ ! pointer itself.  This caused a segfault when the result was
+ ! nullified.
+ !
+ ! Contributed by Joost VandeVondele <jv244@cam.ac.uk>
+ !
+   TYPE cp_logger_type
+     INTEGER :: a
+   END TYPE cp_logger_type
+ 
+   if (cp_logger_log(cp_get_default_logger (0))) call abort ()
+   if (.not. cp_logger_log(cp_get_default_logger (42))) call abort ()
+ 
+ CONTAINS
+ 
+   logical function cp_logger_log(logger)
+     TYPE(cp_logger_type), POINTER ::logger
+     cp_logger_log = associated (logger) .and. (logger%a .eq. 42)
+   END function
+ 
+   FUNCTION cp_get_default_logger(v) RESULT(res)
+     TYPE(cp_logger_type), POINTER ::res
+     integer :: v
+     if (v .eq. 0) then
+       NULLIFY(RES)
+     else
+       allocate(RES)
+       res%a = v
+     end if
+   END FUNCTION cp_get_default_logger
+ END

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