Bug 45290 - [F08] pointer initialization
Summary: [F08] pointer initialization
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: ---
Assignee: janus
URL:
Keywords: rejects-valid
Depends on: 55887
Blocks: F2008 51266 51076
  Show dependency treegraph
 
Reported: 2010-08-15 19:46 UTC by janus
Modified: 2015-01-16 13:06 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2010-08-16 09:37:09


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description janus 2010-08-15 19:46:31 UTC
John Reid, The new features of Fortran 2008, chapter 5.5:

A pointer may be initially associated with a target:

type (entry), target :: bottom
type (entry), pointer :: top => bottom

*****

Currently gfortran responds with:

type (entry), pointer :: top => bottom
                               1
Error: Pointer initialization requires a NULL() at (1)

*****

A look at the current draft of F08 seems to indicate that this is allowed for any kind of pointer: Data pointers and data pointer components as well as procedure pointers and procedure pointer components. See:

R442 component-initialization
R443 initial-data-target
C460

R505 initialization
C511

R1216 proc-pointer-init
R1217 initial-proc-target

Note: For procedure-pointer components I was not able to find any specific reference to non-NULL default initialization. However, chapter 4.5.4.6 ("Default initialization for components") explicitly mentions the possibility of having an initial-proc-target for a PPC.
Comment 1 Daniel Kraft 2010-08-16 07:34:39 UTC
Confirmed.
Comment 2 Tobias Burnus 2010-08-16 09:17:10 UTC
(In reply to comment #0)
> Note: For procedure-pointer components I was not able to find any specific
> reference to non-NULL default initialization.

It is allowed per:

R440 proc-component-def-stmt   is   PROCEDURE ( [ proc-interface ] ) ,
                              proc-component-attr-spec-list :: proc-decl-list

As "proc-decl-list" refers to (click on it in the PDF):

R1214 proc-decl   is   procedure-entity-name [ => proc-pointer-init ]

with

R1216 proc-pointer-init    is  null-init
                           or  initial-proc-target
R1217 initial-proc-target  is  procedure-name


> John Reid, The new features of Fortran 2008

Besides John's article, you also find a list of new features in the "Introduction" (page xv) of the Fortran 2008 standard.
Comment 3 janus 2010-08-16 09:37:09 UTC
(In reply to comment #2)
> (In reply to comment #0)
> > Note: For procedure-pointer components I was not able to find any specific
> > reference to non-NULL default initialization.
> 
> It is allowed per:
> 
> R440 proc-component-def-stmt   is   PROCEDURE ( [ proc-interface ] ) ,
>                               proc-component-attr-spec-list :: proc-decl-list
> 
> As "proc-decl-list" refers to (click on it in the PDF):
> 
> R1214 proc-decl   is   procedure-entity-name [ => proc-pointer-init ]

Right. I missed that. (I guess I was expecting an explicit reference to 'proc-pointer-init' around R440.)


Also: Mine. (I'm working on a patch.)
Comment 4 janus 2010-08-18 22:32:37 UTC
Subject: Bug 45290

Author: janus
Date: Wed Aug 18 22:32:22 2010
New Revision: 163356

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=163356
Log:
2010-08-19  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/45290
	* gfortran.h (gfc_add_save): Modified prototype.
	* decl.c (add_init_expr_to_sym): Defer checking of proc pointer init.
	(match_pointer_init): New function to match F08 pointer initialization.
	(variable_decl,match_procedure_decl,match_ppc_decl): Use
	'match_pointer_init'.
	(match_attr_spec): Module variables are implicitly SAVE.
	(gfc_match_save): Modified call to 'gfc_add_save'.
	* expr.c (gfc_check_assign_symbol): Extra checks for pointer
	initialization.
	* primary.c (gfc_variable_attr): Handle SAVE attribute.
	* resolve.c (resolve_structure_cons): Add new argument and do pointer
	initialization checks.
	(gfc_resolve_expr): Modified call to 'resolve_structure_cons'.
	(resolve_values): Call 'resolve_structure_cons' directly with init arg.
	(resolve_fl_variable): Handle SAVE_IMPLICIT.
	* symbol.c (gfc_add_save,gfc_copy_attr,save_symbol): Handle
	SAVE_IMPLICIT.
	* trans-decl.c (gfc_create_module_variable): Module variables with
	TARGET can already exist.
	* trans-expr.c (gfc_conv_variable): Check for 'current_function_decl'.
	(gfc_conv_initializer): Implement non-NULL pointer
	initialization.


2010-08-19  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/45290
	* gfortran.dg/proc_ptr_comp_3.f90: Modified.
	* gfortran.dg/pointer_init_2.f90: New.
	* gfortran.dg/pointer_init_3.f90: New.
	* gfortran.dg/pointer_init_4.f90: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/pointer_init_2.f90
    trunk/gcc/testsuite/gfortran.dg/pointer_init_3.f90
    trunk/gcc/testsuite/gfortran.dg/pointer_init_4.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/decl.c
    trunk/gcc/fortran/expr.c
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/primary.c
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/symbol.c
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/proc_ptr_comp_3.f90

Comment 5 janus 2010-08-18 22:37:40 UTC
r163356 implements pointer initialization.

Leftover To-Do items:

(1) ICE on 

module m
 implicit none
 integer, target, save  :: t1
 integer, pointer :: p1 => t
 integer, pointer :: p2 => p1    ! ICE
end module m


(2) Making global variables in a program SAVE_IMPLICIT.
Comment 6 janus 2010-08-19 11:11:14 UTC
There are also still problems with procedure pointers:

module m
implicit none
procedure(f1), pointer :: pp => f1
contains
  integer function f1()
    f1 = 42
  end function
end module

use m
implicit none
if (pp()/=42) call abort()
end


This one fails with:

f951: internal compiler error: in build_function_decl, at fortran/trans-decl.c:1611
Comment 7 janus 2010-08-21 14:51:19 UTC
Subject: Bug 45290

Author: janus
Date: Sat Aug 21 14:50:57 2010
New Revision: 163445

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=163445
Log:
2010-08-21  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/45271
	PR fortran/45290
	* class.c (add_proc_comp): Add static initializer for PPCs.
	(add_procs_to_declared_vtab): Modified comment.
	* module.c (mio_component): Add argument 'vtype'. Don't read/write the
	initializer if the component is part of a vtype.
	(mio_component_list): Add argument 'vtype', pass it on to
	'mio_component'.
	(mio_symbol): Modified call to 'mio_component_list'.
	* trans.h (gfc_conv_initializer): Modified prototype.
	(gfc_trans_assign_vtab_procs): Removed.
	* trans-common.c (create_common): Modified call to
	'gfc_conv_initializer'.
	* trans-decl.c (gfc_get_symbol_decl,get_proc_pointer_decl,
	gfc_emit_parameter_debug_info): Modified call to
	'gfc_conv_initializer'.
	(build_function_decl): Remove assertion.
	* trans-expr.c (gfc_conv_derived_to_class,gfc_trans_class_assign):
	Removed call to 'gfc_trans_assign_vtab_procs'.
	(gfc_conv_initializer): Add argument 'procptr'.
	(gfc_conv_structure): Modified call to 'gfc_conv_initializer'.
	(gfc_trans_assign_vtab_procs): Removed.
	* trans-stmt.c (gfc_trans_allocate): Removed call to
	'gfc_trans_assign_vtab_procs'.


2010-08-21  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/44863
	PR fortran/45271
	PR fortran/45290
	* gfortran.dg/dynamic_dispatch_10.f03: New (PR 44863 comment #1).
	* gfortran.dg/pointer_init_5.f90: New (PR 45290 comment #6).
	* gfortran.dg/typebound_call_18.f03: New (PR 45271 comment #3).

Added:
    trunk/gcc/testsuite/gfortran.dg/dynamic_dispatch_10.f03
    trunk/gcc/testsuite/gfortran.dg/pointer_init_5.f90
    trunk/gcc/testsuite/gfortran.dg/typebound_call_18.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/class.c
    trunk/gcc/fortran/module.c
    trunk/gcc/fortran/trans-common.c
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans-stmt.c
    trunk/gcc/fortran/trans.h
    trunk/gcc/testsuite/ChangeLog

Comment 8 janus 2010-08-21 16:21:32 UTC
Comment #6 is fixed by r163445, but comment #5 is still open.
Comment 9 Tobias Burnus 2010-09-21 12:37:44 UTC
Another issue besides comment 5 is the following program (from PR 45740), which gives an ICE.

Actually, I am not quite sure the example is valid as "p2"'s target is not known at compile time.



module m
  procedure(), pointer :: p2
end module m

  use m
  procedure(), pointer :: ptr3 => p2
  call ptr3()  ! ICE, related to PR 45290
! internal compiler error: in record_reference, at cgraphbuild.c:60
  end
Comment 10 Tobias Burnus 2010-09-21 13:52:24 UTC
(In reply to comment #9)
>   procedure(), pointer :: ptr3 => p2

I now believe that this is invalid (all quotes are F2008):

R505 initialization is [...]  or  => initial-data-target
R443 initial-data-target  is  designator

C461 (R443) The designator shall designate a nonallocatable variable that has the TARGET and SAVE attributes and does not have a vector subscript. Every subscript, section subscript, substring starting point, and substring ending point in designator shall be a constant expression.


Well, in the example (cf. also the ICE in comment 5) "p2" is a POINTER and a pointer cannot have the TARGET attribute (cf. C556).

Thus, the "initial-data-target" can neither be a pointer nor a proc-pointer.
Comment 11 janus 2011-02-06 17:42:35 UTC
(In reply to comment #10)
> (In reply to comment #9)
> >   procedure(), pointer :: ptr3 => p2
> 
> I now believe that this is invalid (all quotes are F2008):
> 
> R505 initialization is [...]  or  => initial-data-target
> R443 initial-data-target  is  designator
> 
> C461 (R443) The designator shall designate a nonallocatable variable that has
> the TARGET and SAVE attributes and does not have a vector subscript. Every
> subscript, section subscript, substring starting point, and substring ending
> point in designator shall be a constant expression.
> 
> 
> Well, in the example (cf. also the ICE in comment 5) "p2" is a POINTER and a
> pointer cannot have the TARGET attribute (cf. C556).
> 
> Thus, the "initial-data-target" can neither be a pointer nor a proc-pointer.

Ok, I agree. Also I remember that we already had some discussion about this when I committed the first patch for this PR, without any consensus.


Let's compare the above C461 to the corresponding restriction for normal pointer assignment ...

R737 data-target is variable

C724 (R737) A variable shall have either the TARGET or POINTER attribute, and shall not be an array section with a vector subscript.

... which explicitly allows both the TARGET and POINTER attribute, while C461 only allows the TARGET attribute.


In conclusion, I propose the following patch:

Index: gcc/fortran/expr.c
===================================================================
--- gcc/fortran/expr.c  (revision 169853)
+++ gcc/fortran/expr.c  (working copy)
@@ -3608,7 +3608,7 @@ gfc_check_assign_symbol (gfc_symbol *sym, gfc_expr
                     "must not be ALLOCATABLE ");
          return FAILURE;
        }
-      if (!attr.target)
+      if (!attr.target || attr.pointer)
        {
          gfc_error ("Pointer initialization target at %C "
                     "must have the TARGET attribute");


We have to explicitly demand that the rhs of the pointer initialization does not have the POINTER attribute, since gfc_expr_attr gives the TARGET attribute also to POINTER expressions (probably because the thing that the pointer points to has the TARGET attribute).


The patch correctly rejects the two invalid lines in the following test case:

module m
 implicit none
 type :: t
   integer, pointer :: p
   integer :: i
 end type
 integer, target :: i
 type(t), target :: x
 integer, pointer :: p1 => i
 integer, pointer :: p2 => p1   ! invalid
 integer, pointer :: p3 => x%p  ! invalid
 integer, pointer :: p4 => x%i
end module m
Comment 12 janus 2011-02-08 22:51:09 UTC
Author: janus
Date: Tue Feb  8 22:51:04 2011
New Revision: 169948

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=169948
Log:
2011-02-08  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/45290
	* expr.c (gfc_check_assign_symbol): Reject pointers as pointer
	initialization target.


2011-02-08  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/45290
	* gfortran.dg/pointer_init_6.f90: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/pointer_init_6.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/expr.c
    trunk/gcc/testsuite/ChangeLog
Comment 13 janus 2011-02-08 23:02:56 UTC
With r169948, this PR is basically fixed. Just two minor leftovers:

(1) Making global variables in a program SAVE_IMPLICIT. (Does it even make a difference?)


(2) We currently get a slightly inappropriate error message for:

 implicit none
 integer, target, save  :: t1
 integer, pointer :: p1 => t
end


 integer, pointer :: p1 => t
                       1
Error: Different types in pointer assignment at (1); attempted assignment of UNKNOWN to INTEGER(4)


In principle it should give the same error as:

 implicit none
 integer, target, save  :: t1
 integer, pointer :: p1
 p1 => t
end

 p1 => t
        1
Error: Symbol 't' at (1) has no IMPLICIT type
Comment 14 Tobias Burnus 2011-10-18 07:23:36 UTC
See also PR 50410 comment 9
Comment 15 janus 2013-08-05 10:22:40 UTC
(In reply to janus from comment #13)
> Just two minor leftovers:
> 
> (1) Making global variables in a program SAVE_IMPLICIT. (Does it even make a
> difference?)

cf. PR 55207 (and apparently, yes, it does make a difference in some cases)
Comment 16 janus 2014-03-15 15:39:08 UTC
(In reply to janus from comment #13)
> (2) We currently get a slightly inappropriate error message for:
> 
>  implicit none
>  integer, target, save  :: t1
>  integer, pointer :: p1 => t
> end

This can be fixed with the following patch (not regtested yet):

Index: gcc/fortran/decl.c
===================================================================
--- gcc/fortran/decl.c	(revision 208590)
+++ gcc/fortran/decl.c	(working copy)
@@ -1759,8 +1759,8 @@ match_pointer_init (gfc_expr **init, int procptr)
       return MATCH_ERROR;
     }
 
-  if (!procptr)
-    gfc_resolve_expr (*init);
+  if (!procptr && !gfc_resolve_expr (*init))
+    return MATCH_ERROR;
 
   if (!gfc_notify_std (GFC_STD_F2008, "non-NULL pointer "
 		       "initialization at %C"))
Comment 17 janus 2014-03-15 16:54:26 UTC
(In reply to janus from comment #16)
> (In reply to janus from comment #13)
> > (2) We currently get a slightly inappropriate error message for:
> 
> This can be fixed with the following patch

... which does regtest cleanly in fact.
Comment 18 janus 2015-01-16 12:50:18 UTC
Author: janus
Date: Fri Jan 16 12:49:46 2015
New Revision: 219731

URL: https://gcc.gnu.org/viewcvs?rev=219731&root=gcc&view=rev
Log:
2015-01-16  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/45290
	* decl.c (match_pointer_init): Error out if resolution of init expr
	failed.

2015-01-16  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/45290
	* gfortran.dg/pointer_init_6.f90: Extended.

Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/decl.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/pointer_init_6.f90
Comment 19 janus 2015-01-16 12:54:09 UTC
The patch in comment 16 has been committed as r219731, which fixes the second leftover problem in comment 13.

Since the first one is covered by PR 55207, I'm closing this PR.