Bug 87689 - PowerPC64 ELFv2 function parameter passing violation
Summary: PowerPC64 ELFv2 function parameter passing violation
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 7.1.0
: P3 normal
Target Milestone: ---
Assignee: Thomas Koenig
URL: https://gcc.gnu.org/ml/gcc-patches/20...
Keywords: patch, wrong-code
Depends on: 33097 40976
Blocks:
  Show dependency treegraph
 
Reported: 2018-10-22 13:29 UTC by Judicaël Grasset
Modified: 2020-02-18 18:37 UTC (History)
6 users (show)

See Also:
Host:
Target: powerpc64le
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-10-22 00:00:00


Attachments
Patch that may work, but causes some regressions (1.86 KB, patch)
2019-02-17 16:14 UTC, Thomas Koenig
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Judicaël Grasset 2018-10-22 13:29:44 UTC
Hello,

I am compiling this code with gfortran 7.1.0 on a power 8 machine:
main.f:
      program main
        implicit none
        character :: c
        character(len=20) :: res, doesntwork_p8
        external doesntwork_p8
        c = 'o'
        res = doesntwork_p8(c,1,2,3,4,5,6)
        write(*,*)res
      end program main

doesnwork_p8.f:
      function doesntwork_p8(c,a1,a2,a3,a4,a5,a6)
        implicit none
        character(len=20) :: doesntwork_p8
        character :: c
        integer :: a1,a2,a3,a4,a5,a6
        write(*,*)a1,a2,a3,a4,a5,a6
        write(*,*)c
        doesntwork_p8 = 'foo'
        return
      end

And when I run it, it prints:
           1           2           3           4           5           0
 �
 foo  

But I expect:
           1           2           3           4           5           6
 o
 foo  

Also if compiled with fcheck=all, a runtime message say:
At line 1 of file doesntwork_p8.f
Fortran runtime error: Actual string length is shorter than the declared one for dummy argument 'c' (0/1)

gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/gpfs/paragon/local/apps/gcc/gcc/7.1.0/bin/../libexec/gcc/powerpc64le-unknown-linux-gnu/7.1.0/lto-wrapper
Target: powerpc64le-unknown-linux-gnu
Configured with: ./configure --prefix=/gpfs/panther/local/apps/gcc/gcc/7.1.0 --enable-languages=c,c++,fortran --disable-multilib --disable-bootstrap --with-system-zlib --enable-__cxa_atexit --disable-nls --disable-linux-futex
Thread model: posix
gcc version 7.1.0 (GCC)
Comment 1 Richard Biener 2018-10-22 13:53:28 UTC
Please try newer versions like 7.3.0 and provide the compiler options you are using.
Comment 2 Judicaël Grasset 2018-10-22 14:04:47 UTC
I have tried with gfortran 8.2.0
I have compiled with:
gfortran -g main.f doesntwork_p8.f -Wall -Wextra -o exe

When running I get:
           1           2           3           4           5           0
 �
 foo      

So it seems the problem still exist.

If I add fcheck=all at the compilation, I do not get any run-time error message when executing the program, but the result is still wrong:
           1           2           3           4           5      -46855
 o
 foo
Comment 3 Thomas Koenig 2018-10-23 22:15:30 UTC
I checked, and it seems that this is an old bug; it occurs both
with gfortran 4.8.5 and 8.1.0.

This goes away with -flto or if you put both procedures into one file,
and does not happen on Linux.

Tree dump looks reasonable with 8.1:

    static integer(kind=4) C.2183 = 1;
    static integer(kind=4) C.2184 = 2;
    static integer(kind=4) C.2185 = 3;
    static integer(kind=4) C.2186 = 4;
    static integer(kind=4) C.2187 = 5;
    static integer(kind=4) C.2188 = 6;
    character(kind=1) str.0[20];

    doesntwork_p8 ((character(kind=1)[1:20] *) &str.0, 20, &c, &C.2183, &C.2184, &C.2185, &C.2186, &C.2187, &C.2188, 1);
    __builtin_memmove ((void *) &res, (void *) &str.0, 20);

vs.

doesntwork_p8 (character(kind=1)[1:20] & __result, integer(kind=8) .__result, character(kind=1)[1:1] & restrict c, integer(kind=4) & restrict a1, integer(kind=4) & restrict a2, integer(kind=4) & restrict a3, integer(kind=4) & restrict a4, integer(kind=4) & restrict a5, integer(kind=4) & restrict a6, integer(kind=8) _c)
{

What looks less reasonable is the debug output:

breakpoint 1, doesntwork_p8 (__result=@0x3fffffffed80: '\224\016\000\020\000\000\000\000\230\016\000\020\000\000\000\000\000\000\000\000', .__result=20, c='`', a1=1, a2=2, a3=3, a4=4, a5=5, 
    a6=<error reading variable: Cannot access memory at address 0x0>, _c=0) at b.f90:6

This looks like the arguments pushed on the stack somehow have the wrong number of bytes...
Comment 4 Thomas Koenig 2018-10-23 22:36:16 UTC
(In reply to Thomas Koenig from comment #3)
> This goes away with -flto or if you put both procedures into one file,
> and does not happen on Linux.

I meant on x86_64.

Wild guess: Do we somehow get the declarations wrong (or different) and this shows up because we trigger some difference in the POWER ABI?

Segher, does this maybe ring a bell?
Comment 5 Segher Boessenkool 2018-10-24 00:02:52 UTC
No, doesn't ring bells.  But I have some more input:

I couldn't get it to fail on powerpc64-linux.
It fails on powerpc64le-linux only if the second file is compiled with -O0.

As output I get just

$ ./87689 |xxd -g1
0000000: 20 20 20 20 20 20 20 20 20 20 20 31 20 20 20 20             1    
0000010: 20 20 20 20 20 20 20 32 20 20 20 20 20 20 20 20         2        
0000020: 20 20 20 33 20 20 20 20 20 20 20 20 20 20 20 34     3           4
0000030: 20 20 20 20 20 20 20 20 20 20 20 35 20 20 20 20             5    
0000040: 20 20 20 20 20 20 20 30 0a 20 00 0a 20 66 6f 6f         0. .. foo
0000050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0000060: 20 0a

so no weird characters other than a zero byte.
Comment 6 Thomas Koenig 2018-10-24 20:45:42 UTC
(In reply to Segher Boessenkool from comment #5)
> No, doesn't ring bells.  But I have some more input:
> 
> I couldn't get it to fail on powerpc64-linux.
> It fails on powerpc64le-linux only if the second file is compiled with -O0.

Not for me:

tkoenig@gcc2-power8 ~]$ ~/bin/gfortran -static-libgfortran main.f doesntwork_p8.f 
[tkoenig@gcc2-power8 ~]$ ./a.out
           1           2           3           4           5           0
 �
 foo                 
[tkoenig@gcc2-power8 ~]$ valgrind ./a.out
==145922== Memcheck, a memory error detector
==145922== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==145922== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==145922== Command: ./a.out
==145922== 
==145922== Conditional jump or move depends on uninitialised value(s)
==145922==    at 0x10013EF8: write_decimal.constprop.10 (write.c:808)
==145922==    by 0x100143F7: write_integer (write.c:1351)
==145922==    by 0x1001584F: list_formatted_write_scalar (write.c:1865)
==145922==    by 0x1001664B: _gfortrani_list_formatted_write (write.c:1943)
==145922==    by 0x10005A47: transfer_integer (transfer.c:2294)
==145922==    by 0x10005A47: _gfortran_transfer_integer_write (transfer.c:2300)
==145922==    by 0x10002563: doesntwork_p8_ (in /home/tkoenig/a.out)
==145922==    by 0x10002443: MAIN__ (in /home/tkoenig/a.out)
==145922==    by 0x100021E3: main (in /home/tkoenig/a.out)
==145922== 
==145922== Conditional jump or move depends on uninitialised value(s)
==145922==    at 0x100100BC: extract_int (write.c:556)
==145922==    by 0x10013F0B: write_decimal.constprop.10 (write.c:810)
==145922==    by 0x1001584F: list_formatted_write_scalar (write.c:1865)
==145922==    by 0x1001664B: _gfortrani_list_formatted_write (write.c:1943)
==145922==    by 0x10005A47: transfer_integer (transfer.c:2294)
==145922==    by 0x10005A47: _gfortran_transfer_integer_write (transfer.c:2300)
==145922==    by 0x100025C7: doesntwork_p8_ (in /home/tkoenig/a.out)
==145922==    by 0x10002443: MAIN__ (in /home/tkoenig/a.out)
==145922==    by 0x100021E3: main (in /home/tkoenig/a.out)
==145922== 
           1           2           3           4           5           0
 o
 foo                 

Also, you have to add the six arguments; it works with five.

Next data point: On a POWER9, it also fails.

There is one other thing: With gcc9 on x86_64, one gets

gfortran -flto main.f doesnwork_p8.f
main.f:7: warning: type of 'doesntwork_p8' does not match original declaration [-Wlto-type-mismatch]
7 |         res = doesntwork_p8(c,1,2,3,4,5,6)
  | 
doesnwork_p8.f:1: note: type mismatch in parameter 3
1 |       function doesntwork_p8(c,a1,a2,a3,a4,a5,a6)
  | 
doesnwork_p8.f:1: note: 'doesntwork_p8' was previously declared here

So, probably something wrong with our decls.
Comment 7 Segher Boessenkool 2018-10-24 21:20:18 UTC
-O0 is the default.
Comment 8 Thomas Koenig 2019-01-13 15:48:22 UTC
This is probably caused by PR40976.
Comment 9 Alan Modra 2019-02-11 14:45:56 UTC
The call in main is wrong.  From comment #3
> Tree dump looks reasonable with 8.1:
> 
>     static integer(kind=4) C.2183 = 1;
>     static integer(kind=4) C.2184 = 2;
>     static integer(kind=4) C.2185 = 3;
>     static integer(kind=4) C.2186 = 4;
>     static integer(kind=4) C.2187 = 5;
>     static integer(kind=4) C.2188 = 6;
>     character(kind=1) str.0[20];
> 
>     doesntwork_p8 ((character(kind=1)[1:20] *) &str.0, 20, &c, &C.2183, &C.2184, &C.2185, &C.2186, &C.2187, &C.2188, 1);

Looking at the assembly, I see r3 is &str.0, r4 is 20, r5 is &c, and so on up to r10 which is &C.2187.  That's all good.  The next arg, &C.2188 is stored on the stack at 32(1).  That's wrong.  It should be 96(1), ie. leaving 64 bytes of parameter save area.  Similarly for the final "1", which is stored at 40(1) instead of 104(1).

Debugging a little, it seems that the cause is that the fndecl found in expand_call is missing args.  These lines in expand_call

#ifdef REG_PARM_STACK_SPACE
  reg_parm_stack_space = REG_PARM_STACK_SPACE (!fndecl ? fntype : fndecl);
#endif

then calculate 0 for reg_parm_stack_space, which is correct for the given bogus fndecl.

 <function_decl 0x7ffff68bd500 doesntwork_p8
    type <function_type 0x7ffff68c1a80
        type <void_type 0x7ffff67b1f18 void VOID
            align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff67b1f18
            pointer_to_this <pointer_type 0x7ffff67ba000>>
        SI
        size <integer_cst 0x7ffff67b60d8 constant 32>
        unit-size <integer_cst 0x7ffff67b60f0 constant 4>
        align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff68c19d8
        attributes <tree_list 0x7ffff68bcd70
            purpose <identifier_node 0x7ffff6813a28 fn spec>
            value <tree_list 0x7ffff68bcd48
                value <string_cst 0x7ffff68b0bd0 constant ".wR">>>
        arg-types <tree_list 0x7ffff68bcd20 value <reference_type 0x7ffff68c1930>
            chain <tree_list 0x7ffff68bccf8 value <integer_type 0x7ffff67b1738 integer(kind=8)>
                chain <tree_list 0x7ffff67b2168 value <void_type 0x7ffff67b1f18 void>>>>
        pointer_to_this <pointer_type 0x7ffff68c1b28>>
    addressable used public external SI /home/alan/src/tmp/pr87689_main.f:7:0 align:32 warn_if_not_align:0 context <translation_unit_decl 0x7ffff68be000 /home/alan/src/tmp/pr87689_main.f> chain <function_decl 0x7ffff68bd600 main>>
Comment 10 Alan Modra 2019-02-11 14:57:36 UTC
Replying to comment #4, yes, the function decl is wrong.  It should have the full  parameter list, or have none (ie. tree.c:prototype_p return false).  The powerpc ELFv2 ABI works fine with non-prototyped function calls, but not with lying prototypes..
Comment 11 Alan Modra 2019-02-12 02:15:25 UTC
This patch avoids the failure.  Be warned, I shouldn't be let loose anywhere near the gcc fortran support.  I'm just presenting it in the hope that someone who does know what they're doing can develop a proper fix.

--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -3092,8 +3092,7 @@ gfc_get_function_type (gfc_symbol * sym)
 	}
     }
 
-  if (!vec_safe_is_empty (typelist)
-      || sym->attr.is_main_program
+  if (sym->attr.is_main_program
       || sym->attr.if_source != IFSRC_UNKNOWN)
     is_varargs = false;
Comment 12 Alan Modra 2019-02-12 03:17:36 UTC
A little more sophisticated.

	* fortran/trans-types.c (gfc_get_function_type): Use a varargs decl
	unless we have args other than hidden ones.

--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -3066,6 +3066,7 @@ gfc_get_function_type (gfc_symbol * sym)
 	     actual parameters for a dummy procedure.  */
 
 	  vec_safe_push (typelist, type);
+	  is_varargs = false;
 	}
       else
         {
@@ -3092,8 +3093,7 @@ gfc_get_function_type (gfc_symbol * sym)
 	}
     }
 
-  if (!vec_safe_is_empty (typelist)
-      || sym->attr.is_main_program
+  if (sym->attr.is_main_program
       || sym->attr.if_source != IFSRC_UNKNOWN)
     is_varargs = false;
Comment 13 Thomas Koenig 2019-02-12 08:40:46 UTC
Thanks for the analysis (and the patch).  Now for the
interesting question, what to do with it...

On the one hand, we must avoid at all costs is to break
compatibility with pre-compiled libraries, at least while
we do not change the ABI for another reason.

On the other hand, this is quit a serious bug, which especially
affects old Fortran codes.

At least the problem is on the caller side, which means that
we could fix the caller without affecting the callee.

So, what are the options?

After checking if the patch from comment #12 does the right
thing (which I don't know), we could

a) apply it globally, after checking that it does not break
   binary compatibility on all relevant platforms (quite risky
   for stage 4, I think)

b) apply it #ifdefed for POWER

I think both options would need an OK from a release manager due
to us being in stage 4 (plus from a POWER maintainer for option b)

Or we could defer this to gcc 10, but I would prefer for this bug
to be fixed sooner rather than later.
Comment 14 rguenther@suse.de 2019-02-12 08:53:46 UTC
On February 12, 2019 9:40:46 AM GMT+01:00, "tkoenig at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org> wrote:
>https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87689
>
>Thomas Koenig <tkoenig at gcc dot gnu.org> changed:
>
>           What    |Removed                     |Added
>----------------------------------------------------------------------------
>             CC|                            |rguenth at gcc dot gnu.org
>
>--- Comment #13 from Thomas Koenig <tkoenig at gcc dot gnu.org> ---
>Thanks for the analysis (and the patch).  Now for the
>interesting question, what to do with it...
>
>On the one hand, we must avoid at all costs is to break
>compatibility with pre-compiled libraries, at least while
>we do not change the ABI for another reason.
>
>On the other hand, this is quit a serious bug, which especially
>affects old Fortran codes.
>
>At least the problem is on the caller side, which means that
>we could fix the caller without affecting the callee.
>
>So, what are the options?
>
>After checking if the patch from comment #12 does the right
>thing (which I don't know), we could
>
>a) apply it globally, after checking that it does not break
>   binary compatibility on all relevant platforms (quite risky
>   for stage 4, I think)
>
>b) apply it #ifdefed for POWER
>
>I think both options would need an OK from a release manager due
>to us being in stage 4 (plus from a POWER maintainer for option b)
>
>Or we could defer this to gcc 10, but I would prefer for this bug
>to be fixed sooner rather than later.

I haven't checked the details of the incorrectness of the function decl or its type. Given the error is on the caller side only the chances of breakage are low. Still I would suggest to fix on trunk only for now and skip the imminent 8.3 to allow for fallout to pop up.

Richard.
Comment 15 Alan Modra 2019-02-12 11:28:00 UTC
I've regression tested the patch on powerpc64le-linux, and of course verified that it fixes the testcase.  I'm also fairly certain the patch intent is correct in the narrow sense of it correcting gfc_get_function_type behaviour.  My comment about not being let loose near the gcc fortran support is because I have no idea whether the patch is the best patch possible.  Also, as with any patch, reviewers should check the actual patch matches the intent. ;-)  gfc_get_function_type currently calls build_varargs_function_type_vec for "normal" functions without arg info, which seems a perfectly reasonable way to say the function isn't prototyped.  So the patch isn't introducing new behaviour..

By "normal" I mean functions that don't have hidden args for return values or multiple entry points.  Just because you have arg info for the return type shouldn't make the function prototyped.
Comment 16 Thomas Koenig 2019-02-12 20:39:45 UTC
(In reply to Alan Modra from comment #12)
> A little more sophisticated.
> 
> 	* fortran/trans-types.c (gfc_get_function_type): Use a varargs decl
> 	unless we have args other than hidden ones.

Without having looked at exactly what the patch does: This sounds wrong
to em. On platforms where varargs have a different calling
signature from normal functions, this would be an ABI change.

It would probably make more sense to build the decl from the call
itself.
Comment 17 Alan Modra 2019-02-13 05:56:15 UTC
> On platforms where varargs have a different calling
> signature from normal functions, this would be an ABI change.

True, but in C terms, gfortran is currently doing this:
void f (char *res, int reslen);
..
  f (res, 20, &c, &i1, &i2, &i3, &i4, &i5, &i6);
That's why I said we have "lying prototypes".

The patch in comment #12 changes things to
void f (char *res, int reslen, ...);
..
  f (res, 20, &c, &i1, &i2, &i3, &i4, &i5, &i6);

Which at least makes the prototype and call compatible in that translation unit.  We have ABI violations in both cases as neither prototype matches the actual function definition.  Yes, my patch is just a hack, but..

> It would probably make more sense to build the decl from the call
> itself.
This would require major surgery, I think.  Another option would be to pass info to the backend that the call is really not prototyped despite the presence of those "hidden" args.

For now, I'm going to post a backend patch for this problem, in rs6000_function_parms_need_stack:

  /* FIXME: Fortran arg lists can contain hidden parms, fooling
     prototype_p into saying the function is prototyped when in fact
     the number and type of args is unknown.  See PR 87689.  */
  if (!incoming && (strcmp (lang_hooks.name, "GNU F77") == 0
		    || lang_GNU_Fortran ()))
    return true;
Comment 18 rguenther@suse.de 2019-02-13 08:21:59 UTC
On February 13, 2019 6:56:15 AM GMT+01:00, amodra at gmail dot com <gcc-bugzilla@gcc.gnu.org> wrote:
>https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87689
>
>--- Comment #17 from Alan Modra <amodra at gmail dot com> ---
>> On platforms where varargs have a different calling
>> signature from normal functions, this would be an ABI change.
>
>True, but in C terms, gfortran is currently doing this:
>void f (char *res, int reslen);
>..
>  f (res, 20, &c, &i1, &i2, &i3, &i4, &i5, &i6);
>That's why I said we have "lying prototypes".
>
>The patch in comment #12 changes things to
>void f (char *res, int reslen, ...);
>..
>  f (res, 20, &c, &i1, &i2, &i3, &i4, &i5, &i6);
>
>Which at least makes the prototype and call compatible in that
>translation
>unit.  

Both indeed look wrong. Afaics if Fortran doesn't require a visible function definition or declaration it indeed has to build one from the actual call. In theory it could use a unprototyped function declaration void f() and then use only a
CALL_EXPR_FNTYPE function type matching the call signature (and hope backends will be happy with that). That has the advantage of not needing to deal with mismatches from multiple calls
(multiple decls would be even worse I think) 

We have ABI violations in both cases as neither prototype
>matches the
>actual function definition.  Yes, my patch is just a hack, but..
>
>> It would probably make more sense to build the decl from the call
>> itself.
>This would require major surgery, I think.  Another option would be to
>pass
>info to the backend that the call is really not prototyped despite the
>presence
>of those "hidden" args.
>
>For now, I'm going to post a backend patch for this problem, in
>rs6000_function_parms_need_stack:
>
>  /* FIXME: Fortran arg lists can contain hidden parms, fooling
>     prototype_p into saying the function is prototyped when in fact
>     the number and type of args is unknown.  See PR 87689.  */
>  if (!incoming && (strcmp (lang_hooks.name, "GNU F77") == 0
>                    || lang_GNU_Fortran ()))
>    return true;
Comment 19 Thomas Koenig 2019-02-16 23:09:31 UTC
This is worse than I thought.

It seems that, if we compile

subroutine foo(a)
  real :: a
end subroutine foo

program main
  real :: x
  call foo(x)
end program main

we call build_function_type_vec (type, typelist)

and if we just compile

program main
  real :: x
  call foo(x)
end program main

we call build_varargs_function_type_vec (type, typelist);

(which is in trans-types.c (gfc_get_function_type), in the
code snippet

  if (is_varargs)
    type = build_varargs_function_type_vec (type, typelist);
  else
    type = build_function_type_vec (type, typelist);
  type = create_fn_spec (sym, type);

This only "works" for calling conventions where varargs
do not matter.

Now, this is caller-side, so I do not think a fix to
generate the correct function decl from the call should
hurt.

I guess that if we really fix this one, we will also fix quite a few
latent bugs...
Comment 20 Alan Modra 2019-02-17 02:55:43 UTC
That is what I thought too at first, and why I though that making calls with hidden args to be varargs was not going to be a problem.  However, calling build_varargs_function_type_vec with an empty typelist does not build a varargs function.  Instead, you get a function decl with a NULL TYPE_ARG_TYPES, which is an unprototyped function.
Comment 21 Thomas Koenig 2019-02-17 13:45:31 UTC
Think I might have something.
Comment 22 Thomas Koenig 2019-02-17 16:14:27 UTC
Created attachment 45742 [details]
Patch that may work, but causes some regressions

The regressions are:

FAIL: gfortran.dg/lto/20091028-1 f_lto_20091028-1_0.o-f_lto_20091028-1_1.o link, -O0 -flto -flto-partition=none -fuse-linker-plugin
FAIL: gfortran.dg/lto/20091028-1 f_lto_20091028-1_0.o-f_lto_20091028-1_1.o link, -O2 -flto -flto-partition=none -fuse-linker-plugin -fno-fat-lto-objects 
FAIL: gfortran.dg/lto/20091028-1 f_lto_20091028-1_0.o-f_lto_20091028-1_1.o link, -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin 
FAIL: gfortran.dg/lto/20091028-1 f_lto_20091028-1_0.o-f_lto_20091028-1_1.o link, -O2 -flto -flto-partition=1to1 -fno-use-linker-plugin 
FAIL: gfortran.dg/lto/20091028-1 f_lto_20091028-1_0.o-f_lto_20091028-1_1.o link, -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects 
FAIL: gfortran.dg/lto/20091028-1 f_lto_20091028-1_0.o-f_lto_20091028-1_1.o link, -O2 -flto -fuse-linker-plugin
Running /home/ig25/Gcc/trunk/gcc/testsuite/gfortran.fortran-torture/compile/compile.exp ...
FAIL: gfortran.dg/lto/20091028-2 f_lto_20091028-2_0.o-f_lto_20091028-2_1.o link, -O0 -flto -flto-partition=none -fuse-linker-plugin
FAIL: gfortran.dg/lto/20091028-2 f_lto_20091028-2_0.o-f_lto_20091028-2_1.o link, -O2 -flto -flto-partition=none -fuse-linker-plugin -fno-fat-lto-objects 
FAIL: gfortran.dg/lto/20091028-2 f_lto_20091028-2_0.o-f_lto_20091028-2_1.o link, -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin 
FAIL: gfortran.dg/lto/20091028-2 f_lto_20091028-2_0.o-f_lto_20091028-2_1.o link, -O2 -flto -flto-partition=1to1 -fno-use-linker-plugin 
FAIL: gfortran.dg/lto/20091028-2 f_lto_20091028-2_0.o-f_lto_20091028-2_1.o link, -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects 
FAIL: gfortran.dg/lto/20091028-2 f_lto_20091028-2_0.o-f_lto_20091028-2_1.o link, -O2 -flto -fuse-linker-plugin

I will have to see if I can make any sense out of this.
Comment 23 Thomas Koenig 2019-02-17 16:33:28 UTC
(In reply to Thomas Koenig from comment #22)

> FAIL: gfortran.dg/lto/20091028-1 f_lto_20091028-1_0.o-f_lto_20091028-1_1.o
> link, -O0 -flto -flto-partition=none -fuse-linker-plugin

These test cases are invalid:


SUBROUTINE int_gen_ti_header_char( hdrbuf, hdrbufsize, itypesize, &
                              DataHandle, Element, VarName, Data, code )
  CALL int_gen_ti_header_c ( hdrbuf, hdrbufsize, itypesize, 1, &
                             DataHandle, DummyData, DummyCount, code )
END SUBROUTINE int_gen_ti_header_char

certainly does not fit 

void int_gen_ti_header_c_ (char * hdrbuf, int * hdrbufsize,
                           int * itypesize, int * typesize,
                           int * DataHandle, char * Data,
                           int * Count, int * code)
{
  memcpy (typesize, p, sizeof(int)) ;
  memcpy (Data, p, *Count * *typesize) ;
}

so it is a good sign that they are caught now :-)
Comment 24 Thomas Koenig 2019-02-17 22:44:54 UTC
I just checked that the patch at https://gcc.gnu.org/ml/gcc-patches/2019-02/msg01415.html does indeed fix the test case on POWER9.
Comment 25 Thomas Koenig 2019-02-18 18:29:30 UTC
Author: tkoenig
Date: Mon Feb 18 18:28:58 2019
New Revision: 268992

URL: https://gcc.gnu.org/viewcvs?rev=268992&root=gcc&view=rev
Log:
2019-02-18  Thomas Koenig  <tkoenig@gcc.gnu.org>

    PR fortran/87689
    * trans-decl.c (gfc_get_extern_function_decl): Add argument
    actual_args and pass it through to gfc_get_function_type.
    * trans-expr.c (conv_function_val): Add argument actual_args
    and pass it on to gfc_get_extern_function_decl.
    (conv_procedure_call): Pass actual arguments to conv_function_val.
    * trans-types.c (get_formal_from_actual_arglist): New function.
    (gfc_get_function_type): Add argument actual_args.  Generate
    formal args from actual args if necessary.
    * trans-types.h (gfc_get_function_type): Add optional argument.
    * trans.h (gfc_get_extern_function_decl): Add optional argument.

2019-02-18  Thomas Koenig  <tkoenig@gcc.gnu.org>

    PR fortran/87689
    * gfortran.dg/lto/20091028-1_0.f90: Add -Wno-lto-type-mismatch to
    options.
    * gfortran.dg/lto/20091028-2_0.f90: Likewise.
    * gfortran.dg/lto/pr87689_0.f: New file.
    * gfortran.dg/lto/pr87689_1.f: New file.


Added:
    trunk/gcc/testsuite/gfortran.dg/lto/pr87689_0.f
    trunk/gcc/testsuite/gfortran.dg/lto/pr87689_1.f
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans-types.c
    trunk/gcc/fortran/trans-types.h
    trunk/gcc/fortran/trans.h
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/lto/20091028-1_0.f90
    trunk/gcc/testsuite/gfortran.dg/lto/20091028-2_0.f90
Comment 26 Thomas Koenig 2019-02-18 19:45:30 UTC
Fixed on gcc 9 so far. I will backport this to the other
open branches, but only after the release of the next
version of gcc 8.3.
Comment 27 Thomas Koenig 2019-03-03 09:04:55 UTC
Author: tkoenig
Date: Sun Mar  3 09:04:23 2019
New Revision: 269349

URL: https://gcc.gnu.org/viewcvs?rev=269349&root=gcc&view=rev
Log:
2019-03-03  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/87689
	Backport from trunk
	* trans-decl.c (gfc_get_extern_function_decl): Add argument
	actual_args and pass it through to gfc_get_function_type.
	* trans-expr.c (conv_function_val): Add argument actual_args
	and pass it on to gfc_get_extern_function_decl.
	(conv_procedure_call): Pass actual arguments to conv_function_val.
	* trans-types.c (get_formal_from_actual_arglist): New function.
	(gfc_get_function_type): Add argument actual_args.  Generate
	formal args from actual args if necessary.
	* trans-types.h (gfc_get_function_type): Add optional argument.
	* trans.h (gfc_get_extern_function_decl): Add optional argument.

2019-03-03  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/87689
	Backport from trunk
	* gfortran.dg/lto/20091028-1_0.f90: Add -Wno-lto-type-mismatch to
	options.
	* gfortran.dg/lto/20091028-2_0.f90: Likewise.
	* gfortran.dg/lto/pr87689_0.f: New file.
	* gfortran.dg/lto/pr87689_1.f: New file.
	* gfortran.dg/altreturn_9_0.f90: New file.
	* gfortran.dg/altreturn_9_1.f90: New file.


Added:
    branches/gcc-8-branch/gcc/testsuite/gfortran.dg/altreturn_9_0.f90
    branches/gcc-8-branch/gcc/testsuite/gfortran.dg/altreturn_9_1.f90
    branches/gcc-8-branch/gcc/testsuite/gfortran.dg/lto/pr87689_0.f
    branches/gcc-8-branch/gcc/testsuite/gfortran.dg/lto/pr87689_1.f
Modified:
    branches/gcc-8-branch/gcc/fortran/ChangeLog
    branches/gcc-8-branch/gcc/fortran/trans-decl.c
    branches/gcc-8-branch/gcc/fortran/trans-expr.c
    branches/gcc-8-branch/gcc/fortran/trans-types.c
    branches/gcc-8-branch/gcc/fortran/trans-types.h
    branches/gcc-8-branch/gcc/fortran/trans.h
    branches/gcc-8-branch/gcc/testsuite/ChangeLog
    branches/gcc-8-branch/gcc/testsuite/gfortran.dg/lto/20091028-1_0.f90
    branches/gcc-8-branch/gcc/testsuite/gfortran.dg/lto/20091028-2_0.f90
Comment 28 Thomas Koenig 2019-03-03 09:20:41 UTC
Author: tkoenig
Date: Sun Mar  3 09:20:09 2019
New Revision: 269350

URL: https://gcc.gnu.org/viewcvs?rev=269350&root=gcc&view=rev
Log:
2019-03-03  Thomas Koenig  <tkoenig@gcc.gnu.org>

    PR fortran/87689
    Backport from trunk
    * trans-decl.c (gfc_get_extern_function_decl): Add argument
    actual_args and pass it through to gfc_get_function_type.
    * trans-expr.c (conv_function_val): Add argument actual_args
    and pass it on to gfc_get_extern_function_decl.
    (conv_procedure_call): Pass actual arguments to conv_function_val.
    * trans-types.c (get_formal_from_actual_arglist): New function.
    (gfc_get_function_type): Add argument actual_args.  Generate
    formal args from actual args if necessary.
    * trans-types.h (gfc_get_function_type): Add optional argument.
    * trans.h (gfc_get_extern_function_decl): Add optional argument.

2019-03-03  Thomas Koenig  <tkoenig@gcc.gnu.org>

    PR fortran/87689
    Backport from trunk
    * gfortran.dg/lto/20091028-1_0.f90: Add -Wno-lto-type-mismatch to
    options.
    * gfortran.dg/lto/20091028-2_0.f90: Likewise.
    * gfortran.dg/lto/pr87689_0.f: New file.
    * gfortran.dg/lto/pr87689_1.f: New file.
    * gfortran.dg/altreturn_9_0.f90: New file.
    * gfortran.dg/altreturn_9_1.f90: New file.


Added:
    branches/gcc-7-branch/gcc/testsuite/gfortran.dg/altreturn_9_0.f90
    branches/gcc-7-branch/gcc/testsuite/gfortran.dg/altreturn_9_1.f90
    branches/gcc-7-branch/gcc/testsuite/gfortran.dg/lto/pr87689_0.f
    branches/gcc-7-branch/gcc/testsuite/gfortran.dg/lto/pr87689_1.f
Modified:
    branches/gcc-7-branch/gcc/fortran/ChangeLog
    branches/gcc-7-branch/gcc/fortran/trans-decl.c
    branches/gcc-7-branch/gcc/fortran/trans-expr.c
    branches/gcc-7-branch/gcc/fortran/trans-types.c
    branches/gcc-7-branch/gcc/fortran/trans-types.h
    branches/gcc-7-branch/gcc/fortran/trans.h
    branches/gcc-7-branch/gcc/testsuite/ChangeLog
    branches/gcc-7-branch/gcc/testsuite/gfortran.dg/lto/20091028-1_0.f90
    branches/gcc-7-branch/gcc/testsuite/gfortran.dg/lto/20091028-2_0.f90
Comment 29 Thomas Koenig 2019-03-03 09:21:32 UTC
Fixed on all open branches, closing.

Thanks a lot for the bug report!
Comment 30 Bill Schmidt 2019-03-03 18:39:48 UTC
Thanks, Thomas!