Hi,

in the test cases dynamic_dispatch_1.f03 and dynamic_dispatch_3.f04 there is 
recursive procedure type, make_real,
the front-end generates the equivalent of 

extern "C" float make_real(t1*, ...);

for the call statements, but uses

extern "C" float make_real(t1*)
{
}

for the procedure itself, which is the first invocation of 
gfc_get_function_type.

In the case of arm-linux-gnueabihf these prototypes are not equivalent, see 
arm.c:

  if (TARGET_AAPCS_BASED)
    {
      /* Detect varargs functions.  These always use the base rules
         (no argument is ever a candidate for a co-processor
         register).  */
      bool base_rules = stdarg_p (type);

      if (user_convention)
        {
          if (user_pcs> ARM_PCS_AAPCS_LOCAL)
            sorry ("non-AAPCS derived PCS variant");
          else if (base_rules && user_pcs != ARM_PCS_AAPCS)
            error ("variadic functions must use the base AAPCS variant");
        }

      if (base_rules)
        return ARM_PCS_AAPCS;


But if above stdarg_p  returns false, the calling convention is: 
arm_pcs_default = ARM_PCS_AAPCS_VFP.
To fix this it is sufficient to generate a prototype like

extern "C" float make_real(...);

in case of a recursion or when the argument types are not known, which makes 
strarg_p return false.

note that:

 float func(...); // this syntax is valid only in C++

returns the result in s0, because it is not really considered a variadic,
while

 float func(int, ...);

is incompatible on this target and uses r0 for the result.


Boot-strapped and Regression-tested on arm-linux-gnueabihf and x86_64-linux-gnu.
OK for trunk?


Thanks
Bernd.                                    
2014-03-31  Bernd Edlinger  <bernd.edlin...@hotmail.de>

        PR fortran/60191
        * fortran/trans-types.c (gfc_get_function_type): In case of recursion
        build a variadic function type with empty argument list instead of a
        stdarg-like function type with incomplete argument list.

Attachment: patch-pr60191.diff
Description: Binary data

Reply via email to