This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug fortran/34686] New: Aliasing bug when returning character pointers


char_pointer_func.f90 is failing at -O3 on mips-linux-gnu because
of an aliasing bug.  We have a function sfoo() that returns a pointer
to a string of length 4:

  function sfoo () result (sc1)
    character*4, pointer       :: sc1
    allocate (sc1)
    sc1 = "abcd"
  end function sfoo

It gets the C prototype:

  static void sfoo (character(kind=1)[1:4] * &, integer(kind=4));

However, the first caller is:

  c1 = sfoo ()

and it passes a 0-based array, pstr.3:

  {
    character(kind=1)[4] * pstr.3;

    sfoo (&pstr.3, 4);
    __builtin_memmove ((void *) c1, (void *) pstr.3, 4);
  }

So after inlining sfoo(), we get the following code at final_cleanup:

  D.617 = (character(kind=1)[1:4] *) D.616;
  *(character(kind=1)[1:4] * &) &pstr.3 = D.617;
  __builtin_memcpy (D.617, &"abcd"[1]{lb: 1 sz: 1}, 4);
  __builtin_memmove (c1, pstr.3, 4);

where __builtin_memcpy is small enough to open-code; we do not use a call.
The two pointer types ([4]-based and [1:4]-based) have different alias sets,
so in the failing case, we then schedule the read of pstr.3 before the
store to *(character(kind=1)[1:4] * &) &pstr.3.

The problem appears to be in this part of gfc_conv_function_call.
which deliberately ignores the bounds on the return value:

          /* Pass the string length.  */
          type = gfc_get_character_type (ts.kind, ts.cl);
          type = build_pointer_type (type);

          /* Return an address to a char[0:len-1]* temporary for
             character pointers.  */
          if (sym->attr.pointer || sym->attr.allocatable)
            {
              /* Build char[0:len-1] * pstr.  */
              tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
                                 build_int_cst (gfc_charlen_type_node, 1));
              tmp = build_range_type (gfc_array_index_type,
                                      gfc_index_zero_node, tmp);
              tmp = build_array_type (gfc_character1_type_node, tmp);
              var = gfc_create_var (build_pointer_type (tmp), "pstr");

              /* Provide an address expression for the function arguments.  */
              var = build_fold_addr_expr (var);
            }
          else
            var = gfc_conv_string_tmp (se, type, len);

(I believe TYPE is unused in the sym->attr.pointer || sym->attr.allocatable
case).


-- 
           Summary: Aliasing bug when returning character pointers
           Product: gcc
           Version: 4.3.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: fortran
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: rsandifo at gcc dot gnu dot org
GCC target triplet: mips-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34686


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]