https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103828
Bug ID: 103828 Summary: Type generated for CHARACTER(C_CHAR), VALUE arguments is wrong Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: fortran Assignee: unassigned at gcc dot gnu.org Reporter: fxcoudert at gcc dot gnu.org Target Milestone: --- On the aarch64-apple-darwin port (Apple Silicon), currently in late-stage development, the runtime test gfortran.dg/c_kind_params.f90 fails. After reducing it (https://github.com/iains/gcc-darwin-arm64/issues/73) we have determined that the front-end is emitting wrong trees. Take this function: subroutine param_test (a, b, c, d, e, f, g, h, v, w) bind(c) use, intrinsic :: iso_c_binding implicit none integer(c_int), value :: a, b, c, d, e, f, g, h character(c_char), value :: v integer(c_signed_char), value :: w if (w /= 1) call foo end subroutine where argument V is a scalar, pass-by-value, C char (an unsigned char, although it does not matter for interoperability, because that's how the Fortran front-end does things). The equivalent C function is therefore: void param_test(int a, int b, int c, int d, int e, int f, int g, int h, unsigned char v, signed char w) { if (w != 1) foo_(); } But gcc can emit different arguments for the Fortran and C versions. The reason is because of the tree type for the V argument, which is invalid as emitted by the Fortran front-end. Inserting a call to debug_tree() in gfc_get_function_type() shows that the type for the V argument is: <array_type 0x1059e9260 type <integer_type 0x105844348 character(kind=1) public unsigned QI size <integer_cst 0x105804db0 constant 8> unit-size <integer_cst 0x105804dc8 constant 1> align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x105844348 precision:8 min <integer_cst 0x105804de0 0> max <integer_cst 0x105804d80 255> pointer_to_this <pointer_type 0x105847f00>> string-flag QI size <integer_cst 0x105804db0 8> unit-size <integer_cst 0x105804dc8 1> align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x1059e9260 domain <integer_type 0x1059e9110 type <integer_type 0x105844738 integer(kind=8) public DI size <integer_cst 0x105804cc0 constant 64> unit-size <integer_cst 0x105804cd8 constant 8> align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x105844738 precision:64 min <integer_cst 0x105804f48 -9223372036854775808> max <integer_cst 0x105804f60 9223372036854775807> pointer_to_this <pointer_type 0x1058575d0>> DI size <integer_cst 0x105804cc0 64> unit-size <integer_cst 0x105804cd8 8> align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x1059e9110 precision:64 min <integer_cst 0x105889c80 1> max <integer_cst 0x105889c80 1>>> See how this is actually not a scalar character(kind=1), but as an array type. On aarch64-apple-darwin, this leads to a different passing of the argument, and therefore to the testcase failure. Where is this type tree generated? It comes from gfc_sym_type(), where the is a special treatment for BT_CHARACTER. Weirdly, we don't follow that (not sure why the conditions don't cover this case). We go instead into gfc_typenode_for_spec(), which calls gfc_get_character_type(), which returns an array, which is wrong.