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.
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: changelog-pr60191.txt
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20140331/62be5f90/attachment.txt>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch-pr60191.diff
Type: application/octet-stream
Size: 2358 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20140331/62be5f90/attachment.obj>