Bug 44265 - Link error with reference to parameter array in specification expression
Summary: Link error with reference to parameter array in specification expression
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code, rejects-valid
: 50406 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-05-25 02:00 UTC by Ian Harvey
Modified: 2018-11-19 11:56 UTC (History)
5 users (show)

See Also:
Host: i686-pc-mingw32
Target: i686-pc-mingw32
Build: i686-pc-mingw32
Known to work:
Known to fail:
Last reconfirmed: 2010-05-25 09:50:41


Attachments
Possible patch for PR44265 (1.62 KB, patch)
2010-10-29 23:20 UTC, Ian Harvey
Details | Diff
Updated patch (1.75 KB, patch)
2015-11-08 13:58 UTC, Dominique d'Humieres
Details | Diff
Updated patch against r23740 (1.66 KB, patch)
2016-06-16 06:49 UTC, Ian Harvey
Details | Diff
Test case (374 bytes, text/plain)
2016-06-18 08:12 UTC, Dominique d'Humieres
Details
Further development of the patch (1.94 KB, patch)
2016-07-17 19:51 UTC, Paul Thomas
Details | Diff
Failing testcases with -flto under Darwin (580 bytes, patch)
2016-12-09 12:30 UTC, Paul Thomas
Details | Diff
Assembly for char_result_16 with -flto on darwin (14.24 KB, text/plain)
2016-12-11 15:00 UTC, Dominique d'Humieres
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ian Harvey 2010-05-25 02:00:20 UTC
The following program compiles successfully, but results in an undefined reference to `___MOD_names' during linking.  It compiles and links successfully with g95 0.92! (May 31, 2009)and ifort 11.1.065.

Using gfortran built from svn trunk revision 159797.  Command line was simply "gfortran filename.f90".  Some experimentation shows that the problem is related to the use of an module procedure scoped array parameter in the specification expression for the function result.  The type of the parameter array doesn't seem to matter.

MODULE Fruits
  IMPLICIT NONE    
  PRIVATE
  PUBLIC :: Get
CONTAINS
  FUNCTION Get(i) RESULT(s)    
    CHARACTER(*), PARAMETER :: names(3) = [  &
        'Apple  ',  &
        'Orange ',  &
        'Mango  ' ];              
    INTEGER, INTENT(IN) :: i
    CHARACTER(LEN_TRIM(names(i))) :: s    
    !****    
    s = names(i)    
  END FUNCTION Get
END MODULE Fruits

PROGRAM WheresThatbLinkingConstantGone
  USE Fruits  
  IMPLICIT NONE
  !****
  WRITE (*, "('Eat the tasty ',A)") Get(1)
END PROGRAM WheresThatbLinkingConstantGone
Comment 1 Tobias Burnus 2010-05-25 09:50:41 UTC
CONFIRM
(No regression: GCC 4.1/4.2/4.3 reject the code ["names" invalid in expression] while 4.4/4.5/4.6 show either the link error or ICE. Other compilers simply work.)

One has the local parameter:
    CHARACTER(*), PARAMETER :: names(3) = ...

And the characteristics of the result variable
    INTEGER, INTENT(IN) :: i
    CHARACTER(LEN_TRIM(names(i))) :: s
which depend on the argument. (While "len(names(i))" is constant, "len_trim(names(i))"  is not.)

Thus, I see two possibilities: Mark the return length (in .MOD) as unknown (which g95 and NAG f95 seemingly do) - or to properly handle the PARAMETER.

Looking at gfortran's .mod file, one finds:
 4 'names' '' 'names' 6 ((PARAMETER UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN ...
Thus, the symbol is already saved.

 * * *

Variant: If one adds a
  subroutine test()
    print *, get(1)
  end subroutine test
in the module itself, one gets an ICE:

foo.f90:18:0: internal compiler error: in gfc_generate_function_code, at fortran/trans-decl.c:4378
Comment 2 Ian Harvey 2010-10-29 23:20:42 UTC
Created attachment 22202 [details]
Possible patch for PR44265
Comment 3 Ian Harvey 2010-10-29 23:32:29 UTC
(In reply to comment #2)
> Created attachment 22202 [details]
> Possible patch for PR44265

Apologies - I wrote several paragraphs of reasonably coherent explanation, but it got lost when I added the attachment.

The attached set of patches introduces a new flag for gfc_symbol that is used to indicate when an entity is referenced in a specification expression for a function result; testing of that condition for module procedure local entities and setting of the flag in resolve.c; and changes to the assembly associated with the entity such that the object code for calling procedures in other program units can reference the entity.

The test for the need to export the entity is probably too inclusive.

The assembly name for the entity is of the form __modname_MOD__procname_PROC_entityname.

Note that ->module for a gfc_symbol for a module procedure entity can either be NULL (when the hosting module is being compiled) or a zero length string (when a program unit that USE's the module is being compiled).  I am not sure whether that is by design or accident - I have assumed by design.

Perhaps Tobias had alternative approaches in mind but I am not familiar enough with the gfortran sources to know what he was talking about.

This does not fix the failed assertion around a non-null ->tlink when a subroutine has an argument whose length uses such a specification expression.
Comment 4 Dominique d'Humieres 2015-11-08 12:18:09 UTC
*** Bug 50406 has been marked as a duplicate of this bug. ***
Comment 5 Dominique d'Humieres 2015-11-08 13:58:28 UTC
Created attachment 36666 [details]
Updated patch

I have updated the patch on revision r229946. I have a regression for gfortran.dg/pr65045.f90. Without the patch the errors are

...
/opt/gcc/p_work/gcc/testsuite/gfortran.dg/pr65045.f90:11:6:

    end if        ! { dg-error "Expecting END BLOCK statement" }
      1

Error: Expecting END BLOCK statement at (1)
/opt/gcc/p_work/gcc/testsuite/gfortran.dg/pr65045.f90:13:8:

 print*,i         ! { dg-error "not appropriate for an expression" }
        1

Error: Symbol 'i' at (1) is not appropriate for an expression

With the patch I have two more errors

/opt/gcc/p_work/gcc/testsuite/gfortran.dg/pr65045.f90:11:6:

    end if        ! { dg-error "Expecting END BLOCK statement" }
      1

Error: Expecting END BLOCK statement at (1)
/opt/gcc/p_work/gcc/testsuite/gfortran.dg/pr65045.f90:12:3:

 end block i
   1

Error: Expecting END PROGRAM statement at (1)
/opt/gcc/p_work/gcc/testsuite/gfortran.dg/pr65045.f90:13:8:

 print*,i         ! { dg-error "not appropriate for an expression" }
        1

Error: Symbol at (1) is not appropriate for an expression
f951: Error: Unexpected end of file in '/opt/gcc/p_work/gcc/testsuite/gfortran.dg/pr65045.f90'

I don't understand why the patch changes the errors, but the test can be easily adjusted.
Comment 6 Dominique d'Humieres 2015-11-08 14:06:32 UTC
> Variant: If one adds a
>   subroutine test()
>     print *, get(1)
>   end subroutine test
> in the module itself, one gets an ICE:
>
> foo.f90:18:0: internal compiler error: in gfc_generate_function_code,
> at fortran/trans-decl.c:4378

The ICE is still there with the patch. It is at the same location as for the test in comment 2 of pr44348 and the one in pr66494.
Comment 7 Vittorio Zecca 2016-04-28 07:08:45 UTC
Still in 5.3.0
Comment 8 Dominique d'Humieres 2016-06-06 09:11:47 UTC
While trying to package the patch in comment 5, I stumbled on the following problem in 32 mode: the following code

MODULE Fruits
  IMPLICIT NONE    
  PRIVATE
  PUBLIC :: Get
CONTAINS
  FUNCTION Get(i) RESULT(s)    
    CHARACTER(len=7), PARAMETER :: names(3) = [  &
        'Apple  ',  &
        'Orange ',  &
        'Mango  ' ];              
    INTEGER, INTENT(IN) :: i
    CHARACTER(LEN_TRIM(names(i))) :: s    
    !****    
    s = names(i)    
    print *, len(s)
  END FUNCTION Get
END MODULE Fruits

PROGRAM WheresThatbLinkingConstantGone
  USE Fruits  
  IMPLICIT NONE
  integer :: i
  i = len(Get(1))
  print *, i
END PROGRAM WheresThatbLinkingConstantGone

outputs at run time

           5
           5

when compiled with -m64, but

           5
           7

when compiled with -m32 (x86_64-apple-darwin15).

The function Get(i) works as expected when used as a contained proc or through an interface.
Comment 9 Ian Harvey 2016-06-16 06:49:52 UTC
Created attachment 38708 [details]
Updated patch against r23740
Comment 10 Ian Harvey 2016-06-16 06:51:16 UTC
The patch discussed in #5 applies changes to the wrong location in trans-decl.c.  Corrected patch attached.  

With this latest patch I see no variation in check-fortran test results.
Comment 11 Paul Thomas 2016-06-16 11:35:04 UTC
(In reply to Ian Harvey from comment #10)
> The patch discussed in #5 applies changes to the wrong location in
> trans-decl.c.  Corrected patch attached.  
> 
> With this latest patch I see no variation in check-fortran test results.

Dear Ian,

I was looking to make the same change. I'll apply your patch this afternoon and will check that it deals with the corner cases.

Cheers

Paul
Comment 12 Paul Thomas 2016-06-18 08:08:13 UTC
(In reply to Ian Harvey from comment #10)
> The patch discussed in #5 applies changes to the wrong location in
> trans-decl.c.  Corrected patch attached.  
> 
> With this latest patch I see no variation in check-fortran test results.

Dear Ian,

I agree.

However, the remaining bug in comment #1 is still there. Do you feel up to trying to fix it?

Best regards

Paul
Comment 13 Dominique d'Humieres 2016-06-18 08:12:05 UTC
Created attachment 38722 [details]
Test case

Test case I have prepared for this PR before I saw the problem reported in comment 8.

The test succeeds with the new patch in comment 9.
Comment 14 Ian Harvey 2016-06-18 15:28:47 UTC
I wouldn't know where to start with respect to the internal compiler error.
Comment 15 paul.richard.thomas@gmail.com 2016-06-19 05:55:12 UTC
Dear Ian,

Aaah, OK. I was rather impressed by what you had done with the first bug :-)

For some reason, one of the symbols is not being committed. I will try
and figure out why.

Cheers

Paul

On 18 June 2016 at 17:28, ian_harvey at bigpond dot com
<gcc-bugzilla@gcc.gnu.org> wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44265
>
> --- Comment #14 from Ian Harvey <ian_harvey at bigpond dot com> ---
> I wouldn't know where to start with respect to the internal compiler error.
>
> --
> You are receiving this mail because:
> You are on the CC list for the bug.
Comment 16 Paul Thomas 2016-07-17 19:51:56 UTC
Created attachment 38917 [details]
Further development of the patch

This patch cures the problem described at the end of comment #1. The change in trans-expr.c does the job.

However, for reasons that I cannot see at the moment, the len_trim is not doing the trimming :-(

MODULE Fruits
  IMPLICIT NONE
!  PRIVATE
!  PUBLIC :: Get
CONTAINS
  subroutine fruity3
    print *, get(4)
  end
  FUNCTION Get(i) RESULT(s)
    CHARACTER(*), PARAMETER :: names(4) = [  &
        'Apple  ',  &
        'Orange ',  &
        'Mango  ',  &
        'Pear   ' ];
    INTEGER, INTENT(IN) :: i
    CHARACTER(LEN_trim(names(i))) :: s
    !****
    s = names(i)
    print *, len(s)
  END FUNCTION Get
  subroutine fruity2
    print *, get(3)
  end
END MODULE Fruits

PROGRAM WheresThatbLinkingConstantGone
  USE Fruits
  IMPLICIT NONE
  !****
  WRITE (*, "('Eat the tasty ',A)") Get(1)
  call fruity
  call fruity2
  call fruity3
contains
  subroutine fruity
    print *, get(2)
  end
END PROGRAM WheresThatbLinkingConstantGone

outputs

Eat the tasty            5
Apple
           6
 Orange
           5
 Mangoe
           4
 Pearoe

I am sure that the problem is now trivial... A task for tomorrow.

Paul
Comment 17 Dominique d'Humieres 2016-07-19 10:12:59 UTC
> However, for reasons that I cannot see at the moment, the len_trim
> is not doing the trimming :-(

Seems related to the problem I have reported in comment 8.
Comment 18 Paul Thomas 2016-12-09 11:55:59 UTC
Author: pault
Date: Fri Dec  9 11:55:27 2016
New Revision: 243478

URL: https://gcc.gnu.org/viewcvs?rev=243478&root=gcc&view=rev
Log:
2016-12-09  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/44265
	* gfortran.h : Add fn_result_spec bitfield to gfc_symbol.
	* resolve.c (flag_fn_result_spec): New function.
	(resolve_fntype): Call it for character result lengths.
	* symbol.c (gfc_new_symbol): Set fn_result_spec to zero.
	* trans-decl.c (gfc_sym_mangled_identifier): Include the
	procedure name in the mangled name for symbols with the
	fn_result_spec bit set.
	(gfc_finish_var_decl): Mark the decls of these symbols
	appropriately for the case where the function is external.
	(gfc_get_symbol_decl): Mangle the name of these symbols.
	(gfc_create_module_variable): Allow them through the assert.
	(gfc_generate_function_code): Remove the assert before the
	initialization of sym->tlink because the frontend no longer
	uses this field.
	* trans-expr.c (gfc_map_intrinsic_function): Add a case to
	treat the LEN_TRIM intrinsic.
	(gfc_trans_string_copy): Deal with Wstringop-overflow warning
	that can occur with constant source lengths at -O3.

2016-12-09  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/44265
	* gfortran.dg/char_result_14.f90: New test.
	* gfortran.dg/char_result_15.f90: New test.


Added:
    trunk/gcc/testsuite/gfortran.dg/char_result_14.f90
    trunk/gcc/testsuite/gfortran.dg/char_result_15.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/gfortran.h
    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
Comment 19 Paul Thomas 2016-12-09 12:30:18 UTC
Created attachment 40286 [details]
Failing testcases with -flto under Darwin

The PR is fixed under Linux but gives a link error under Darwin with -flto. From Dominique's message to the list on 7th December:
The tests gfortran.dg/char_result_16.f90 and gfortran.dg/char_result_17.f90 fail with

lto1: error: two or more sections for .gnu.lto___get_PROC_names.3e3ee55b08747e7c
lto1: internal compiler error: cannot read LTO decls from /var/folders/8q/sh_swgz96r7f5vnn08f7fxr00000gn/T//ccEJosbA.o

This may be darwin specific as the linker is more picky than the linux one.

As soon as the cause is identified, the two attached testcases can be added to the testsuite.

Cheers

Paul
Comment 20 Dominique d'Humieres 2016-12-11 15:00:53 UTC
Created attachment 40303 [details]
Assembly for char_result_16 with -flto on darwin
Comment 21 Dominique d'Humieres 2016-12-11 15:02:14 UTC
Note that the test gfortran.dg/char_result_17.f90 should be run only on target supporting LTO.
Comment 22 Iain Sandoe 2016-12-11 15:15:19 UTC
(In reply to Dominique d'Humieres from comment #20)
> Created attachment 40303 [details]
> Assembly for char_result_16 with -flto on darwin

It appears that two identical entries are present:

	.section __GNU_LTO,__wrapper_sects,regular,debug
L_GNU_LTO4:	;# .gnu.lto___get_PROC_names.547da9c50a5f9b09
	.set L$gnu$lto$offs4,L_GNU_LTO4-L_GNU_LTO0
	.set L$gnu$lto$size4,L_GNU_LTO5-L_GNU_LTO4
	.ascii "x\234cc``\250\1bI\6\10\230\302\314\270\254\377\322"
	.ascii "2vE\246\371\15\34s\230\301\2G\377\177?\300\337\315<\207\231\221\221\11\310\375z\352\352D\16E.\204\374\226#\307\333"
	.ascii "8 \362\214@n_\347\372\277\\\212B\10\371k-s\205-\266"
	.ascii "5t,h0\230\303\314\304\300\270\233Q\221q\27\243\14\343N \275\3HogTd`\334\303h\301\300\356\233\230\227\236\257\240\300\356_\4d\244*\260;\26\24\344\244*(\0\0g\2-\203"
	.text

====

	.section __GNU_LTO,__wrapper_sects,regular,debug
L_GNU_LTO2:	;# .gnu.lto___get_PROC_names.547da9c50a5f9b09
	.set L$gnu$lto$offs2,L_GNU_LTO2-L_GNU_LTO0
	.set L$gnu$lto$size2,L_GNU_LTO3-L_GNU_LTO2
	.ascii "x\234cc``\250\1bI\6\10\230\302\314\270\254\377\322"
	.ascii "2vE\246\371\15\34s\230\301\2G\377\177?\300\337\315<\207\231\221\221\11\310\375z\352\352D\16E.\204\374\226#\307\333"
	.ascii "8 \362\214@n_\347\372\277\\\212B\10\371k-s\205-\266"
	.ascii "5t,h0\230\303\314\304\300\270\233Q\221q\27\243\14\343N \275\3HogTd`\334\303h\301\300\356\233\230\227\236\257\240\300\356_\4d\244*\260;\26\24\344\244*(\0\0g\2-\203"
	.text

I assume that's not expected - so we need to determine why (i.e. if there really are two coming in or if we've recorded something incorrectly)
Comment 23 Iain Sandoe 2016-12-11 15:41:22 UTC
(In reply to Paul Thomas from comment #19)
> Created attachment 40286 [details]
> Failing testcases with -flto under Darwin
> 
> The PR is fixed under Linux but gives a link error under Darwin with -flto.
> From Dominique's message to the list on 7th December:
> The tests gfortran.dg/char_result_16.f90 and gfortran.dg/char_result_17.f90
> fail with
> 
> lto1: error: two or more sections for
> .gnu.lto___get_PROC_names.3e3ee55b08747e7c
> lto1: internal compiler error: cannot read LTO decls from
> /var/folders/8q/sh_swgz96r7f5vnn08f7fxr00000gn/T//ccEJosbA.o
> 
> This may be darwin specific as the linker is more picky than the linux one.

It might be Darwin-specific for a number of reasons:
 (a) Darwin doesn't use the linker plugin so there's a different code-path, 
 (b) we have to wrap the LTO sections to accommodate the limitation of 255 sections on darwin 
 (c) Something to do with missing symbol aliases 
 (d) something else ;-)

However, in this case it does not appear to be a Darwin linker issue;
the ICE is in lto1 - the only external Darwin tool involved at that point is the assembler, and AFAICT the assembler is correctly rendering that there are two instances in the input assembly (as posted by Dominique and as per the complaint in the ICE).  Next thing is to figure out how/why we have those two instances.
Comment 24 Vittorio Zecca 2017-03-20 08:48:48 UTC
It works on my x86_64-pc-linux-gnu with gfortran 7.0.1
Comment 25 Martin Liška 2018-11-19 11:56:44 UTC
Can the bug be marked as resolved?