------- 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