------- Comment #11 from paulthomas2 at wanadoo dot fr  2006-10-12 15:57 -------
Subject: Re:  LBOUND(TRANSPOSE(I)) doesn't work

FX

!       if (upper)
!     {
!       cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
!       cond2 = fold_build2 (LE_EXPR, boolean_type_node, ubound, lbound);
!       cond3 = fold_build2 (GT_EXPR, boolean_type_node, stride,
!                    gfc_index_zero_node);
!
!       cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, 
cond1);
!       cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond2);
!
!       se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
!                   ubound, gfc_index_zero_node);
!     }
!       else
!     {
!       tree cond1, cond2, cond3;

Repeated declaration

!
!       if (as->type == AS_ASSUMED_SIZE)
!         cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
!                 build_int_cst (TREE_TYPE (bound),
!                            arg->expr->rank));
!       else
!         cond = boolean_false_node;
!
!       cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
!       cond2 = fold_build2 (LE_EXPR, boolean_type_node, ubound, lbound);
!       cond3 = fold_build2 (GT_EXPR, boolean_type_node, stride,
!                    gfc_index_zero_node);

Same assignment for upper and lower - put it before the if

!       cond1 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, 
cond1);
!       cond1 = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond1, 
cond2);
!
!       cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond1);
!
!       se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
!                   lbound, gfc_index_one_node);
!     }

I have tested the above corrections, verified the logic and regtested 
the patch right now.  My version of the diff is attached.  I added a 
comment that consists of the appropriate extracts from the standard.

gfortran and ifort now agree on the testcase in #1, whilst g95 differs 
on the last line.

With an appropriate testcase and ChangeLog entries, this is OK for trunk.

Paul


Index: gcc/fortran/trans-intrinsic.c
===================================================================
*** gcc/fortran/trans-intrinsic.c       (revision 117628)
--- gcc/fortran/trans-intrinsic.c       (working copy)
*************** gfc_conv_intrinsic_bound (gfc_se * se, g
*** 710,718 ****
    tree type;
    tree bound;
    tree tmp;
!   tree cond;
    gfc_se argse;
    gfc_ss *ss;
    int i;

    arg = expr->value.function.actual;
--- 710,722 ----
    tree type;
    tree bound;
    tree tmp;
!   tree cond, cond1, cond2, cond3, size;
!   tree ubound;
!   tree lbound;
    gfc_se argse;
    gfc_ss *ss;
+   gfc_array_spec * as;
+   gfc_ref *ref;
    int i;

    arg = expr->value.function.actual;
*************** gfc_conv_intrinsic_bound (gfc_se * se, g
*** 773,782 ****
          }
      }

!   if (upper)
!     se->expr = gfc_conv_descriptor_ubound(desc, bound);
    else
!     se->expr = gfc_conv_descriptor_lbound(desc, bound);

    type = gfc_typenode_for_spec (&expr->ts);
    se->expr = convert (type, se->expr);
--- 777,883 ----
          }
      }

!   ubound = gfc_conv_descriptor_ubound (desc, bound);
!   lbound = gfc_conv_descriptor_lbound (desc, bound);
!   
!   /* Follow any component references.  */
!   if (arg->expr->expr_type == EXPR_VARIABLE
!       || arg->expr->expr_type == EXPR_CONSTANT)
!     {
!       as = arg->expr->symtree->n.sym->as;
!       for (ref = arg->expr->ref; ref; ref = ref->next)
!       {
!         switch (ref->type)
!           {
!           case REF_COMPONENT:
!             as = ref->u.c.component->as;
!             continue;
! 
!           case REF_SUBSTRING:
!             continue;
! 
!           case REF_ARRAY:
!             {
!               switch (ref->u.ar.type)
!                 {
!                 case AR_ELEMENT:
!                 case AR_SECTION:
!                 case AR_UNKNOWN:
!                   as = NULL;
!                   continue;
! 
!                 case AR_FULL:
!                   break;
!                 }
!             }
!           }
!       }
!     }
!   else
!     as = NULL;
! 
!   /* 13.14.53: Result value for LBOUND
!      Case (i): For an array section or for an array expression other than a
whole
!      array or array structure component, LBOUND(ARRAY, DIM) has the value 1. 
For a
!      whole array or array structure component, LBOUND(ARRAY, DIM) has the
value:
!      (a) equal to the lower bound for subscript DIM of ARRAY if dimension DIM
of
!      does not have extent zero or if ARRAY is an assumed-size array of rank
!      DIM, or 
!      (b) 1 otherwise......
! 
!      13.14.113: Result value for UBOUND
!      Case (i): For an array section or for an array expression other than a
whole
!      array or array structure component, UBOUND(ARRAY, DIM) has the value
equal 
!      to the number of elements in the given dimension; otherwise, it has a
value
!      equal to the upper bound for subscript DIM of ARRAY if dimension DIM of
!      ARRAY does not have size zero and has value zero if dimension DIM has
size
!      zero.  */
! 
!   if (as)
!     {
!       tree stride = gfc_conv_descriptor_stride (desc, bound);
!       cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
!       cond2 = fold_build2 (LE_EXPR, boolean_type_node, ubound, lbound);
!       cond3 = fold_build2 (GT_EXPR, boolean_type_node, stride,
!                          gfc_index_zero_node);
! 
!       if (upper)
!       {
!         cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, cond1);
!         cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond2);
! 
!         se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
!                                 ubound, gfc_index_zero_node);
!       }
!       else
!       {
!         if (as->type == AS_ASSUMED_SIZE)
!           cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
!                               build_int_cst (TREE_TYPE (bound),
!                                              arg->expr->rank));
!         else
!           cond = boolean_false_node;
! 
!         cond1 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3,
cond1);
!         cond1 = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond1, cond2);
! 
!         cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond1);
! 
!         se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
!                                 lbound, gfc_index_one_node);
!       }
!     }
    else
!     {
!       if (upper)
!         {
!         size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound,
lbound);
!         se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
!                                 gfc_index_one_node);
!       }
!       else
!       se->expr = gfc_index_one_node;
!     }

    type = gfc_typenode_for_spec (&expr->ts);
    se->expr = convert (type, se->expr);


-- 


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

Reply via email to