Bug 31211

Summary: wrong code generated for pointer returning function as actual argument
Product: gcc Reporter: Joost VandeVondele <Joost.VandeVondele>
Component: fortranAssignee: Paul Thomas <pault>
Status: RESOLVED FIXED    
Severity: normal CC: burnus, gcc-bugs
Priority: P3 Keywords: wrong-code
Version: 4.3.0   
Target Milestone: 4.3.0   
Host: Target:
Build: Known to work:
Known to fail: 4.3.0 4.2.0 4.1.3 Last reconfirmed: 2007-07-25 15:30:55
Bug Depends on:    
Bug Blocks: 32834    

Description Joost VandeVondele 2007-03-16 11:29:50 UTC
With a recent gfortran, the following compiles, but generates the wrong results:

MODULE T
  INTERFACE cp_log
     MODULE PROCEDURE cp_logger_log
  END INTERFACE

  TYPE cp_logger_type
    INTEGER :: a
  END TYPE cp_logger_type

  PUBLIC :: cp_log, cp_logger_type

CONTAINS

  SUBROUTINE cp_logger_log(logger)
    TYPE(cp_logger_type), POINTER ::logger
  END SUBROUTINE

  FUNCTION cp_get_default_logger() RESULT(res)
    TYPE(cp_logger_type), POINTER ::res
    NULLIFY(RES)
  END FUNCTION cp_get_default_logger

END MODULE T

USE T
 CALL cp_log(cp_get_default_logger())
END
Comment 1 Tobias Burnus 2007-03-21 17:13:00 UTC
The following code is wrong, if cp_get_default_logger returns NULL.

    struct cp_logger_type D.1364;
    D.1364 = *cp_get_default_logger ();
    cp_logger_log (&&D.1364);

*** This bug has been marked as a duplicate of 31200 ***
Comment 2 Joost VandeVondele 2007-05-30 14:01:14 UTC
this still fails with current gfortran, so isn't a duplicate
Comment 3 Joost VandeVondele 2007-06-29 11:38:10 UTC
still failing with today's trunk
Comment 4 Paul Thomas 2007-07-25 15:30:55 UTC
This fixes the PR but is not regtested:

Index: gcc/fortran/trans-expr.c
===================================================================
*** gcc/fortran/trans-expr.c    (révision 126835)
--- gcc/fortran/trans-expr.c    (copie de travail)
*************** gfc_conv_expr_reference (gfc_se * se, gf
*** 3355,3360 ****
--- 3344,3359 ----
          gfc_add_block_to_block (&se->pre, &se->post);
          se->expr = var;
        }
+       return;
+     }
+
+   if (expr->expr_type == EXPR_FUNCTION && expr->symtree->n.sym->attr.pointer)
+     {
+       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;
      }

I am rather sure that it will be OK, since the following tests correctly:

MODULE T
  INTERFACE cp_log
     MODULE PROCEDURE cp_logger_log
  END INTERFACE

  TYPE cp_logger_type
    INTEGER :: a
  END TYPE cp_logger_type

  PUBLIC :: cp_log, cp_logger_type

CONTAINS

  SUBROUTINE cp_logger_log(logger)
    TYPE(cp_logger_type), POINTER ::logger
    if (associated (logger)) print *, logger%a
  END SUBROUTINE

  FUNCTION cp_get_default_logger() RESULT(res)
    TYPE(cp_logger_type), POINTER ::res
    NULLIFY(RES)
  END FUNCTION cp_get_default_logger

  FUNCTION cp_get_unity_logger() RESULT(res)
    TYPE(cp_logger_type), POINTER ::res
    allocate(RES)
    res%a = 1
  END FUNCTION cp_get_unity_logger

END MODULE T

USE T
 CALL cp_log(cp_get_default_logger())
 CALL cp_log(cp_get_unity_logger())
END

Comment 5 Tobias Burnus 2007-07-25 17:15:17 UTC
> This fixes the PR but is not regtested:
Patch looks OK and regtests on x86-64.
Comment 6 Paul Thomas 2007-07-26 09:20:58 UTC
(In reply to comment #5)
> > This fixes the PR but is not regtested:
> Patch looks OK and regtests on x86-64.

That's strange - for me, it breaks ret_pointer_2.f90, at the statement print *, x(3) because the elements in the data transfer are incorrectly referenced.

Paul

Comment 7 Tobias Burnus 2007-07-26 09:49:41 UTC
> > Patch looks OK and regtests on x86-64.
> That's strange - for me, it breaks ret_pointer_2.f90, at the statement print *,
> x(3) because the elements in the data transfer are incorrectly referenced.

In the boot-strapped compiler of today I also get this failure (x86-64: -m32/-m64); I probably should always do the full bootstrap/check-gfortran(-m32/-m64) to make sure it really works :-/
Comment 8 patchapp@dberlin.org 2007-07-27 10:55:13 UTC
Subject: Bug number PR31211

A patch for this bug has been added to the patch tracker.
The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2007-07/msg01975.html
Comment 9 Paul Thomas 2007-07-29 14:44:20 UTC
Subject: Bug 31211

Author: pault
Date: Sun Jul 29 14:44:03 2007
New Revision: 127044

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=127044
Log:
2007-07-29  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.

	PR fortran/32682
	*trans-array.c (gfc_trans_array_constructor): On detecting a
	multi-dimensional parameter array, set the loop limits.

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

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

	PR fortran/32682
	* gfortran.dg/scalarize_parameter_array_1.f90: New test.


Added:
    trunk/gcc/testsuite/gfortran.dg/actual_pointer_function_1.f90
    trunk/gcc/testsuite/gfortran.dg/scalarize_parameter_array_1.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-array.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/testsuite/ChangeLog

Comment 10 Paul Thomas 2007-07-29 14:47:51 UTC
Fixed on trunk.

Paul