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.
patch-pr60191.diff
Description: Binary data