Bug 45337 - gfortran accepts pointer initialization of DT dummy arguments w/ INTENT(OUT)
Summary: gfortran accepts pointer initialization of DT dummy arguments w/ INTENT(OUT)
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.5.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid
Depends on:
Blocks:
 
Reported: 2010-08-19 09:14 UTC by macius bat
Modified: 2020-07-14 07:05 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-03-29 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description macius bat 2010-08-19 09:14:15 UTC
$ gfortran --version
GNU Fortran (GCC) 4.5.2 20100819 (prerelease)

which is wrong? and WHY?
Comment 1 macius bat 2010-08-19 09:14:36 UTC
module ptrmod
contains
subroutine lengthX(x, i)
   implicit none
   real, pointer, intent(out) :: x(:)=>null()
   integer :: i
   allocate(x(i))
   x=i
end subroutine
end module

program main
  use ptrmod
  implicit none
  real, pointer :: x(:)
  integer :: i
  do i=1,5
     call lengthX(x, i)
     print *, size(x), x
  enddo
  if(associated(x)) deallocate(x)
  x=>null()
end program
Comment 2 Joost VandeVondele 2010-08-19 09:22:02 UTC
(In reply to comment #1)
> module ptrmod
> contains
> subroutine lengthX(x, i)
>    implicit none
>    real, pointer, intent(out) :: x(:)=>null()

you can't initialize a dummy argument, since initialization implies save. Just put 'NULLIFY(x)' in the body of the subroutine. Intents for pointers is fine, but not Fortran95 (2003/2008?)

>    integer :: i
>    allocate(x(i))
>    x=i
> end subroutine
> end module
> 
> program main
>   use ptrmod
>   implicit none
>   real, pointer :: x(:)
>   integer :: i
>   do i=1,5
>      call lengthX(x, i)
>      print *, size(x), x
>   enddo
>   if(associated(x)) deallocate(x)
>   x=>null()
> end program
> 

Comment 3 macius bat 2010-08-19 09:22:43 UTC
module ptrmod
  implicit none
  type inde
     real :: x
  end type   

contains
subroutine lengthY(indexx)
   implicit none
   type(inde), pointer, intent(out) :: indexx(:)=>null()
end subroutine
end module

program main
  use ptrmod
  implicit none
  type(inde), pointer :: indexx(:)=>null()
  call lengthY(indexx)
end program
Comment 4 macius bat 2010-08-19 09:26:08 UTC
Too fast your answer interrupt My question. 
Comment 5 Tobias Burnus 2010-08-19 09:40:39 UTC
(In reply to comment #2)
> Intents for pointers is fine, but not Fortran95 (2003/2008?)

Intents for pointers is Fortran 2003; it applies to the pointer association status and not to the value.


The programs in comment 0 and comment 2 are both invalid.

  type(inde), pointer :: indexx(:)=>null()

means that "indexx" is initialized - which is only possible for variables which are in static memory ("SAVE"; the assignment implies the SAVE). That's OK for the line above, but not for dummy arguments to subroutines.

Note: In C  "int a = 5;" and "int a; a = 5;" have the same meaning. In Fortran not! "integer :: a = 5" means that "a" is in static memory ("SAVE") and will only be initialized once at program start. Whereas for "integer :: a; a = 5"  the assignment happens every time the line is subroutine is called.

 * * *

Regarding the accepts invalid bug:

While for the program in comment 0, gfortran prints the error
  Error: Dummy 'x' at (1) cannot have an initializer
it compiles the program in comment 2.

Note: If one removes the INTENT(OUT) or has (as in comment 0) no derived-type dummy, the error is printed.
Comment 6 Tobias Burnus 2010-08-19 09:47:08 UTC
(In reply to comment #5)
  It should read: program in comment 3 (not in comment 2).

To macius bat:
  Thanks for the bug report!

  It helps if you already state (a) the error message and (b) what you expect in the first
  description.
Comment 7 Tobias Burnus 2010-08-19 09:56:14 UTC
Untested patch:

Index: resolve.c
===================================================================
--- resolve.c   (revision 163368)
+++ resolve.c   (working copy)
@@ -9724,7 +9724,8 @@ resolve_fl_variable (gfc_symbol *sym, in
        gfc_error ("External '%s' at %L cannot have an initializer",
                   sym->name, &sym->declared_at);
       else if (sym->attr.dummy
-       && !(sym->ts.type == BT_DERIVED && sym->attr.intent == INTENT_OUT))
+       && !(sym->ts.type == BT_DERIVED && sym->attr.intent == INTENT_OUT
+            && !sym->attr.pointer))
        gfc_error ("Dummy '%s' at %L cannot have an initializer",
                   sym->name, &sym->declared_at);
       else if (sym->attr.intrinsic)
Comment 8 macius bat 2010-08-20 06:50:13 UTC
Error: Dummy 'x' at (1) cannot have an initializer

I think this is easy to understand, an additional short message about why it can't have an initializer will be better.

> 
>   It helps if you already state (a) the error message and (b) what you expect
> in the first
>   description.
> 

Comment 9 Tobias Burnus 2010-08-20 08:45:06 UTC
(In reply to comment #8)
> Error: Dummy 'x' at (1) cannot have an initializer
> 
> I think this is easy to understand, an additional short message about why it
> can't have an initializer will be better.

Do you have a suggestion?
Comment 10 Joost VandeVondele 2010-08-20 08:57:27 UTC
(In reply to comment #9)
> (In reply to comment #8)
> > Error: Dummy 'x' at (1) cannot have an initializer
>
> Do you have a suggestion?
>
Error: Dummy argument 'x' at (1) cannot have the save attribute which is implied by initialization.

?? 

Comment 11 Tobias Burnus 2010-08-20 22:28:58 UTC
(In reply to comment #7)
> Untested patch:

The patch is not sufficient as the following example shows for which no warning is printed:

type t
end type t
type t2
  integer :: j = 7
end type t2
contains
  subroutine x(a, b, c)
    type(t) ,intent(OUT) :: a = t() ! Wrong
    type(t2) ,intent(OUT) :: b = t2() ! Wrong
    type(t2) ,intent(OUT) :: c ! OK, default initializer
end subroutine x
end
Comment 12 Joost VandeVondele 2013-03-29 09:27:23 UTC
comment #11 still fails on 4.9 trunk.
Comment 13 markeggleston 2020-07-07 13:50:55 UTC
Regarding patch in comment 7 and test case in comment 11.

It seems to me that it is only necessary to to check for the dummy attribute:

diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 223dcccce91..730d11105bd 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -12918,8 +12918,7 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag)
       else if (sym->attr.external)
        gfc_error ("External %qs at %L cannot have an initializer",
                   sym->name, &sym->declared_at);
-      else if (sym->attr.dummy
-       && !(sym->ts.type == BT_DERIVED && sym->attr.intent == INTENT_OUT))
+      else if (sym->attr.dummy)
        gfc_error ("Dummy %qs at %L cannot have an initializer",
                   sym->name, &sym->declared_at);
       else if (sym->attr.intrinsic)


For the test case from comment 1:

pr45337_1.f90:3:20:

    3 | subroutine lengthX(x, i)
      |                    1
Error: Dummy 'x' at (1) cannot have an initializer
pr45337_1.f90:14:7:

   14 |   use ptrmod
      |       1
Fatal Error: Cannot open module file 'ptrmod.mod' for reading at (1): No such file or directory
compilation terminated.


and for the test case from comment 11:

pr45337_2.f90:7:16:

    7 |   subroutine x(a, b, c)
      |                1
Error: Dummy 'a' at (1) cannot have an initializer
pr45337_2.f90:7:19:

    7 |   subroutine x(a, b, c)
      |                   1
Error: Dummy 'b' at (1) cannot have an initializer


Regarding comments 8, 9 and 10.  I think the the error messages are sufficient as is.

No additional test failures encountered when running make check-fortran.
Comment 14 GCC Commits 2020-07-13 15:38:26 UTC
The master branch has been updated by Mark Eggleston <markeggleston@gcc.gnu.org>:

https://gcc.gnu.org/g:bae66e0f04323ba9d5daf60fcb997de925100e3e

commit r11-2065-gbae66e0f04323ba9d5daf60fcb997de925100e3e
Author: Mark Eggleston <markeggleston@gcc.gnu.org>
Date:   Wed Jun 10 07:22:50 2020 +0100

    Fortran  : accepts pointer initialization of DT dummy args PR45337
    
    Initialisation of a variable results in an implicit save attribute
    being added to the variable.  The save attribute is not allowed for
    variables with the dummy attribute set.  Initialisation should be
    rejected for dummy variables.
    
    2020-07-13  Mark Eggleston  <markeggleston@gcc.gnu.org>
    
    gcc/fortran/
    
            PR fortran/45337
            * resolve.c (resolve_fl_variable): Remove type and intent
            checks from the check for dummy.
    
    2020-07-13  Mark Eggleston  <markeggleston@gcc.gnu.org>
    
    gcc/testsuite/
    
            PR fortran/45337
            * gfortran.dg/pr45337_1.f90: New test.
            * gfortran.dg/pr45337_2.f90: New test.
Comment 15 markeggleston 2020-07-14 07:05:44 UTC
Committed to master.