[Bug fortran/93336] New: BIND(C) and CHARACTER arguments

burnus at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Mon Jan 20 16:02:00 GMT 2020


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93336

            Bug ID: 93336
           Summary: BIND(C) and CHARACTER arguments
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Keywords: diagnostic, wrong-code
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: burnus at gcc dot gnu.org
                CC: tkoenig at gcc dot gnu.org
            Blocks: 85781
  Target Milestone: ---

Came up when testing PR85781.

With C binding, one has a simple "char" and not a "char[lb:up]" variable (plus
arrayness, if needed)

However, gfortran currently does not look at the BIND(C) of the procedure but
whether the CHARACTER kind comes from ISO_C_BINDING or not. Hence,
  CHARACTER(kind=1)  becomes  character(kind=1)[1:1]  (= ARRAY_TYPE node)
while
  CHARACTER(kind=c_char)  becomes  character(kind=1)

This result is completely unexpected as c_char == 1!

Test case and some more wording at:
https://gcc.gnu.org/ml/gcc-patches/2020-01/msg01203.html

 * * *

Another question is what should happen if one uses kind=4; kind = c_char = 1 is
well defined, but kind=4 is not; still, it is accepted.

Hence: Either reject kind=4 with bind(c) – or treat it similar, i.e. instead of
"char" use "int32".

 * * *

In any case, this is all a bit intertwined – i.e. the issue pops up for
function results (cf. below) and arguments – and the fix needs to be done both
for actual arguments and dummy arguments.

For instance, in trans-decl.c's generate_local_decl:

         implies the dummy is a scalar.  */
      if (sym->attr.value == 1 && sym->backend_decl != NULL
          && sym->ts.type == BT_CHARACTER && sym->ts.is_c_interop
          && sym->ns->proc_name != NULL && sym->ns->proc_name->attr.is_bind_c)
        gfc_conv_scalar_char_value (sym, NULL, NULL);

The "sym->ts.is_c_interop" doesn't make much sense!

 * * *

The following is not really interoperable (as "kind=4") – but it is accepted
without any default warning:

function foo() bind(C) result(res)
  character(kind=4) :: res  ! unicode – not really interop, but why not
  res = 4_"c"
end

It gives the unexpected:

foo ()
{
  character(kind=1) res;

Solution:
* In gfc_sym_type:
  if (–)
    type = gfc_character1_type_node;
  else
    type = gfc_typenode_for_spec (&sym->ts, sym->attr.codimension);

The if == true condition causes the kind=4 function-result issue at the very
bottom. — Use "gfc_get_char_type (sym->ts.kind)" instead!

* The other question is, whether one should warn/give an error in this case.
[Note that kind=1 and kind=4 give a -Wall warning but c_char and c_int32_t
don't.]

 * * *

trans-expr.c's gfc_conv_procedure_call has the following, which also looks
suspicious:

                  if (fsym->ts.type == BT_CHARACTER
                      && fsym->ts.is_c_interop
                      && fsym->ns->proc_name != NULL
                      && fsym->ns->proc_name->attr.is_bind_c)


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85781
[Bug 85781] ICE in gfc_build_array_ref, at fortran/trans.c:393


More information about the Gcc-bugs mailing list