Bug 28443 - gfortran does not implement the present intrinsic procedure correctly for optional character strings
Summary: gfortran does not implement the present intrinsic procedure correctly for opt...
Status: RESOLVED DUPLICATE of bug 26227
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid, wrong-code
Depends on: 26227
Blocks:
  Show dependency treegraph
 
Reported: 2006-07-20 10:20 UTC by Patrick Farrell
Modified: 2006-09-13 16:11 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-07-20 19:53:45


Attachments
comment (560 bytes, text/plain)
2006-07-21 08:11 UTC, Matthias Langer
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Patrick Farrell 2006-07-20 10:20:58 UTC
In file strpresent.F90:

program test_string_present

    call test_present(1, "foo")
    call test_present(2)

end program

subroutine test_present(a, b)
    integer :: a
    character*(*), optional :: b

    if (present(b)) then
        write (0,*) "b is present."
    else
        write (0,*) "b is not present."
    end if

end subroutine test_present

As of SVN revision 115597, this yields the output:

 b is present.
 b is present.

It appears that the present() intrinsic function isn't working correctly for optional character strings.

Ifort yields the expected output:

 b is present.
 b is not present.

The output of gfortran -v -save-temps -o strpresent strpresent.F90:

Driving: gfortran -v -save-temps -o strpresent strpresent.F90 -lgfortranbegin -lgfortran -lm -shared-libgcc
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: /home/pfarrell/redhat/BUILD/gcc4-115597/configure --prefix=/opt/packages/gcc4 --enable-bootstrap --enable-languages=c,c++,fortran
Thread model: posix
gcc version 4.2.0 20060719 (experimental)
 /opt/packages/gcc4/libexec/gcc/i686-pc-linux-gnu/4.2.0/cc1 -E -lang-fortran -traditional-cpp -D_LANGUAGE_FORTRAN -quiet -v strpresent.F90 -mtune=generic -fpch-preprocess -o strpresent.f95
ignoring nonexistent directory "/opt/packages/gcc4/lib/gcc/i686-pc-linux-gnu/4.2.0/../../../../i686-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /opt/packages/gcc4/include
 /opt/packages/gcc4/lib/gcc/i686-pc-linux-gnu/4.2.0/include
 /usr/include
End of search list.
 /opt/packages/gcc4/libexec/gcc/i686-pc-linux-gnu/4.2.0/f951 strpresent.f95 -ffree-form -quiet -dumpbase strpresent.F90 -mtune=generic -auxbase strpresent -version -fpreprocessed -I /opt/packages/gcc4/lib/gcc/i686-pc-linux-gnu/4.2.0/finclude -o strpresent.s
GNU F95 version 4.2.0 20060719 (experimental) (i686-pc-linux-gnu)
        compiled by GNU C version 4.2.0 20060719 (experimental).
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
 as -V -Qy -o strpresent.o strpresent.s
GNU assembler version 2.15.92.0.2 (i386-redhat-linux) using BFD version 2.15.92.0.2 20040927
 /opt/packages/gcc4/libexec/gcc/i686-pc-linux-gnu/4.2.0/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o strpresent /usr/lib/crt1.o /usr/lib/crti.o /opt/packages/gcc4/lib/gcc/i686-pc-linux-gnu/4.2.0/crtbegin.o -L/opt/packages/gcc4/lib/gcc/i686-pc-linux-gnu/4.2.0 -L/opt/packages/gcc4/lib/gcc/i686-pc-linux-gnu/4.2.0/../../.. strpresent.o -lgfortranbegin -lgfortran -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /opt/packages/gcc4/lib/gcc/i686-pc-linux-gnu/4.2.0/crtend.o /usr/lib/crtn.o
Comment 1 Steven Bosscher 2006-07-20 19:53:45 UTC
Confirmed.
Comment 2 Steven Bosscher 2006-07-20 21:17:20 UTC
From the tree dumps, it would appear we totally mis-handle omitted arguments:

;; Function MAIN__ (MAIN__)

MAIN__ ()
{
<bb 2>:
  _gfortran_set_std (70, 127, 0);
  test_present (&C.1239, &C.1240);
  test_present (&C.1242);
  return;

}
Comment 3 Matthias Langer 2006-07-21 08:11:07 UTC
Created attachment 11917 [details]
comment
Comment 4 Andrew Pinski 2006-07-21 19:31:37 UTC
Yes, this is most likely one of the accepts invalid bugs where gfortran does not check the types of functions arguments already implicatedly defined.
Comment 5 Steven Bosscher 2006-07-21 23:34:31 UTC
Lahey agrees that this is invalid code:

          1        program test_string_present
          2        
          3            call test_present(1, "foo")
          4            call test_present(2)
          5        
          6        end program
          7        
          8        subroutine test_present(a, b)
          9            integer :: a
         10            character*(*), optional :: b
         11        
         12     1      if (present(b)) then
         13     1          write (0,*) "b is present."
         14     1      else
         15     1          write (0,*) "b is not present."
         16     1      end if
         17        
         18        end subroutine test_present


line 8: Dummy argument 'a' not used in this subprogram.
line 8: The previously procedure 'test_present' reference in 'line 3' shall have the explicit interface, because that has the optional argument 'b'.
line 8: The argument number of procedure 'test_present' shall be the same between definition and reference. The previous appearance is in 'line 4'.

Comment 6 Andrew Pinski 2006-07-22 08:32:44 UTC
PR 26227 is the bug about accepting invalid code with different types and numbers of dummy arguments.
Comment 7 Paul Thomas 2006-08-04 07:50:05 UTC
Just to reinforce the above, I should remark that an explicit interface in the main program makes the code behave correctly (see below).

The standard requires that references to a procedure with an implicit interface have the same number of actual arguments with the same type characteristics.

As Andrew says, gfortran does not check implicitly defined procedure arguments; either for consistency of references within one scope or for a formal interface
generated by the procedure happening to be in the same file.

Paul

program test_string_present
    interface
      subroutine test_present(a, b)
	integer :: a
        character*(*), optional :: b
      end subroutine test_present
    end interface

    call test_present(1, "foo")
    call test_present(2)

end program

subroutine test_present(a, b)
    integer :: a
    character*(*), optional :: b

    if (present(b)) then
        write (0,*) "b is present."
    else
        write (0,*) "b is not present."
    end if

end subroutine test_present
Comment 8 Tobias Schlüter 2006-09-13 16:11:35 UTC
This is another variation of the theme in 26227

*** This bug has been marked as a duplicate of 26227 ***