Re: [PATCH] fortran: [PR53800] Wrong copy-in/out with array actual to, TARGET dummy

Jerry D <[email protected]>
Newsgroups gmane.comp.gcc.patches,gmane.comp.gcc.fortran
Message-ID <[email protected]>
Excellent comments! That new test case passes on 16 so a regression hiding on me.

I am working on this.

Jerry


On 8/10/26 7:32 AM, Mikael Morin wrote:
> Le 08/08/2026 à 21:31, Jerry D a écrit :
>> See the attached patch. This is several iterations after Mikael's comments 
>> which were very helpful. I took a different approach on the use of macros and 
>> this addresses the non derived type examples Mikael provided in the previous 
>> review.
>>
>> I have added additional test cases.
>>
>> Regression tested on x86_64.
>>
>> OK for mainline?
>>
> There is one important thing that I missed in the first review, it's that 
> gfc_build_dummy_array_decl creates array declarations like:
>      integer(kind=4)[0:D.4797] * a.0;
> i.e. a pointer to an array.  For the target dummy arguments we are interested in 
> with this patch, this is lying to the middle-end, as those arguments can only be 
> used with span and pointer arithmetics.  I think the decl should be instead:
>      integer(kind=4) * a.0;
> i.e. the array type should be unwrapped.  But the easiest is probably to return 
> early in gfc_build_dummy_array_decl and drop the variable decl completely. 
> That's already what is done for pointers, classes, and a few others.  And then, 
> all the GFC_DECL_SAVED_DESCRIPTOR business disappears, ...
> 
>> diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
>> index 47b28c1d003..621899b3dbe 100644
>> --- a/gcc/fortran/trans-decl.cc
>> +++ b/gcc/fortran/trans-decl.cc
>> @@ -1408,6 +1408,11 @@ gfc_build_dummy_array_decl (gfc_symbol * sym, tree dummy)>
>>    GFC_DECL_SAVED_DESCRIPTOR (decl) = dummy;
>>
>> +  if (!is_classarray && sym->attr.target && !sym->attr.value
>> +      && !sym->attr.contiguous && as->type == AS_ASSUMED_SHAPE
>> +      && packed == PACKED_NO)
>> +    GFC_DECL_PTR_ARRAY_P (decl) = 1;
>> +
> ... and this needs to be moved ...
>>    if (sym->ns->proc_name->backend_decl == current_function_decl
>>        || sym->attr.contained)
>>      gfc_add_decl_to_function (decl);
> 
> 
>> @@ -1786,7 +1791,10 @@ gfc_get_symbol_decl (gfc_symbol * sym)
>>        && sym->attr.allocatable)
>>      gfc_defer_symbol_init (sym);
>>
>> -      if (sym->attr.pointer && sym->attr.dimension && sym->ts.type != 
>> BT_CLASS)> +      if (sym->attr.dimension && sym->ts.type != BT_CLASS
>> +      && (sym->attr.pointer
>> +          || (sym->attr.target && !sym->attr.contiguous
>> +          && sym->as && sym->as->type == AS_ASSUMED_RANK)))
>>      GFC_DECL_PTR_ARRAY_P (sym->backend_decl) = 1;
> ... here, ...
>>
>>        /* Create a character length variable.  */
> 
> ... and the couple of new utilility functions need to be updated as well.
> 
> I have one more comment, and one additional testcase.
> 
>> diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
>> index 7d23515e5d8..0146cbd318a 100644
>> --- a/gcc/fortran/trans-array.cc
>> +++ b/gcc/fortran/trans-array.cc
>> @@ -553,6 +571,8 @@ gfc_get_array_span (tree desc, gfc_expr *expr)
>>    tree tmp;
>>    gfc_symbol *sym = (expr && expr->expr_type == EXPR_VARIABLE) ?
>>              expr->symtree->n.sym : NULL;
>> +  tree span_desc = (sym && sym->backend_decl)
>> +           ? saved_desc_pointer_array (sym->backend_decl) : NULL_TREE;
>>
>>    if (is_pointer_array (desc)
>>        || (get_CFI_desc (NULL, expr, &desc, NULL)
>> @@ -560,11 +580,8 @@ gfc_get_array_span (tree desc, gfc_expr *expr)
>>            ? GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (desc)))
>>            : GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))))
>>      {
>> -      if (POINTER_TYPE_P (TREE_TYPE (desc)))
>> -    desc = build_fold_indirect_ref_loc (input_location, desc);
>> -
>>        /* This will have the span field set.  */
>> -      tmp = gfc_conv_descriptor_span_get (desc);
>> +      tmp = gfc_conv_descriptor_span_get (gfc_get_span_descriptor (desc));
>>      }
>>    else if (expr->ts.type == BT_ASSUMED)
>>      {
>> @@ -588,6 +605,25 @@ gfc_get_array_span (tree desc, gfc_expr *expr)
>>      /* Having escaped the above, this can only be a class array dummy.  */
>>      tmp = class_array_element_size (sym->backend_decl,
>>                      UNLIMITED_POLY (sym));
>> +  else if (span_desc
>> +       && (expr->ref == NULL
>> +           || (expr->ref->type == REF_ARRAY && expr->ref->next == NULL)))
> 
> It doesn't seem to be correct to check the absence of any subreference.
> The span is a property of the array; it doesn't depend on subreferences.
> Even if there is a subreference after it, the array reference should
> continue to use spanned array indexing.  The program below regresses for
> example (not sure it's related to this condition).  Surprisingly it
> doesn't seem to be covered by the testsuite.
> 
> program p
>    implicit none
>    type :: t
>      integer :: c1, c2
>    end type
>    type, extends(t) :: u
>      integer :: c3
>    end type
>    type, extends(u) :: v
>      integer :: c4
>    end type
>    type(v), target :: x(12)
>    integer :: i
>    x = [(v(i,i*i,i,i), i=1,size(x))]
>    call s1(x(2::3)%c2, 1)
>    call s2(x%u)
> contains
>    subroutine s1(a, error_idx)
>      integer, intent(in) :: error_idx
>      integer, target :: a(:)
>      print *, a
>      if (any(a /= [4, 25, 64, 121])) error stop error_idx * 10 + 1
>    end subroutine
>    subroutine s2(a)
>      type(u), target :: a(:)
>      print *, a(2::3)%c2
>      if (any(a(2::3)%c2 /= [4, 25, 64, 121])) error stop 2
>      call s1(a(2::3)%c2, 2)
>    end subroutine
> end program
> 
>> +    {
>> +      /* A descriptorless dummy re-passed to another procedure. Read its
>> +     span from the saved descriptor.  */
>> +      if (POINTER_TYPE_P (TREE_TYPE (span_desc)))
>> +    span_desc = build_fold_indirect_ref_loc (input_location, span_desc);
>> +      tmp = gfc_conv_descriptor_span_get (span_desc);
>> +
>> +      /* An absent optional dummy has no valid saved descriptor to read;
>> +     avoid trying to use it and fall back to the static element size. */
>> +      if (sym->attr.dummy && sym->attr.optional)
>> +    tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
>> +               gfc_conv_expr_present (sym), tmp,
>> +               fold_convert (TREE_TYPE (tmp),
>> +                     TYPE_SIZE_UNIT (
>> +                       gfc_get_element_type (TREE_TYPE (desc)))));
>> +    }
>>    else
>>      {
>>        /* If none of the fancy stuff works, the span is the element
> 
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.