diff options
author | Paul Thomas <pault@gcc.gnu.org> | 2006-04-16 03:45:24 +0000 |
---|---|---|
committer | Paul Thomas <pault@gcc.gnu.org> | 2006-04-16 03:45:24 +0000 |
commit | f5f701ad0010445cfff157bda3d08441ab0e82f4 (patch) | |
tree | 91336ea3d66ad4b06a4314c5493b7032adfe1c58 /gcc/fortran | |
parent | 7fe25d1a558e736813076d49f7e7ef8a502ee37c (diff) | |
download | gcc-f5f701ad0010445cfff157bda3d08441ab0e82f4.zip gcc-f5f701ad0010445cfff157bda3d08441ab0e82f4.tar.gz gcc-f5f701ad0010445cfff157bda3d08441ab0e82f4.tar.bz2 |
re PR fortran/26822 (Scalarization of non-elemental intrinsic: __logical_4_l4)
2006-04-16 Paul Thomas <pault@gcc.gnu.org>
PR fortran/26822
* intrinsic.c (add_functions): Mark LOGICAL as elemental.
PR fortran/26787
* expr.c (gfc_check_assign): Extend scope of error to include
assignments to a procedure in the main program or, from a
module or internal procedure that is not that represented by
the lhs symbol. Use VARIABLE rather than l-value in message.
PR fortran/27096
* trans-array.c (gfc_trans_deferred_array): If the backend_decl
is not a descriptor, dereference and then test and use the type.
PR fortran/25597
* trans-decl.c (gfc_trans_deferred_vars): Check if an array
result, is also automatic character length. If so, process
the character length.
PR fortran/18803
PR fortran/25669
PR fortran/26834
* trans_intrinsic.c (gfc_walk_intrinsic_bound): Set
data.info.dimen for bound intrinsics.
* trans_array.c (gfc_conv_ss_startstride): Pick out LBOUND and
UBOUND intrinsics and supply their shape information to the ss
and the loop.
PR fortran/27124
* trans_expr.c (gfc_trans_function_call): Add a new block, post,
in to which all the argument post blocks are put. Add this block
to se->pre after a byref call or to se->post, otherwise.
2006-04-16 Paul Thomas <pault@gcc.gnu.org>
PR fortran/26787
* gfortran.dg/proc_assign_1.f90: New test.
* gfortran.dg/procedure_lvalue.f90: Change message.
* gfortran.dg/namelist_4.f90: Add new error.
PR fortran/27096
* gfortran.dg/auto_pointer_array_result_1.f90
PR fortran/27089
* gfortran.dg/specification_type_resolution_1.f90
PR fortran/18803
PR fortran/25669
PR fortran/26834
* gfortran.dg/bounds_temporaries_1.f90: New test.
PR fortran/27124
* gfortran.dg/array_return_value_1.f90: New test.
From-SVN: r112981
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 34 | ||||
-rw-r--r-- | gcc/fortran/expr.c | 46 | ||||
-rw-r--r-- | gcc/fortran/intrinsic.c | 2 | ||||
-rw-r--r-- | gcc/fortran/resolve.c | 10 | ||||
-rw-r--r-- | gcc/fortran/trans-array.c | 32 | ||||
-rw-r--r-- | gcc/fortran/trans-decl.c | 6 | ||||
-rw-r--r-- | gcc/fortran/trans-expr.c | 10 | ||||
-rw-r--r-- | gcc/fortran/trans-intrinsic.c | 1 |
8 files changed, 132 insertions, 9 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index df5a576..24af5f6 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,37 @@ +2006-04-16 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/26822 + * intrinsic.c (add_functions): Mark LOGICAL as elemental. + + PR fortran/26787 + * expr.c (gfc_check_assign): Extend scope of error to include + assignments to a procedure in the main program or, from a + module or internal procedure that is not that represented by + the lhs symbol. Use VARIABLE rather than l-value in message. + + PR fortran/27096 + * trans-array.c (gfc_trans_deferred_array): If the backend_decl + is not a descriptor, dereference and then test and use the type. + + PR fortran/25597 + * trans-decl.c (gfc_trans_deferred_vars): Check if an array + result, is also automatic character length. If so, process + the character length. + + PR fortran/18803 + PR fortran/25669 + PR fortran/26834 + * trans_intrinsic.c (gfc_walk_intrinsic_bound): Set + data.info.dimen for bound intrinsics. + * trans_array.c (gfc_conv_ss_startstride): Pick out LBOUND and + UBOUND intrinsics and supply their shape information to the ss + and the loop. + + PR fortran/27124 + * trans_expr.c (gfc_trans_function_call): Add a new block, post, + in to which all the argument post blocks are put. Add this block + to se->pre after a byref call or to se->post, otherwise. + 2006-04-14 Roger Sayle <roger@eyesopen.com> * trans-io.c (set_string): Use fold_build2 and build_int_cst instead diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index dfbbed2..5ecc829 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -1863,13 +1863,49 @@ gfc_check_assign (gfc_expr * lvalue, gfc_expr * rvalue, int conform) return FAILURE; } - if (sym->attr.flavor == FL_PROCEDURE && sym->attr.use_assoc) +/* 12.5.2.2, Note 12.26: The result variable is very similar to any other + variable local to a function subprogram. Its existence begins when + execution of the function is initiated and ends when execution of the + function is terminated..... + Therefore, the left hand side is no longer a varaiable, when it is:*/ + if (sym->attr.flavor == FL_PROCEDURE + && sym->attr.proc != PROC_ST_FUNCTION + && !sym->attr.external) { - gfc_error ("'%s' in the assignment at %L cannot be an l-value " - "since it is a procedure", sym->name, &lvalue->where); - return FAILURE; - } + bool bad_proc; + bad_proc = false; + + /* (i) Use associated; */ + if (sym->attr.use_assoc) + bad_proc = true; + + /* (ii) The assignement is in the main program; or */ + if (gfc_current_ns->proc_name->attr.is_main_program) + bad_proc = true; + + /* (iii) A module or internal procedure.... */ + if ((gfc_current_ns->proc_name->attr.proc == PROC_INTERNAL + || gfc_current_ns->proc_name->attr.proc == PROC_MODULE) + && gfc_current_ns->parent + && (!(gfc_current_ns->parent->proc_name->attr.function + || gfc_current_ns->parent->proc_name->attr.subroutine) + || gfc_current_ns->parent->proc_name->attr.is_main_program)) + { + /* .... that is not a function.... */ + if (!gfc_current_ns->proc_name->attr.function) + bad_proc = true; + + /* .... or is not an entry and has a different name. */ + if (!sym->attr.entry && sym->name != gfc_current_ns->proc_name->name) + bad_proc = true; + } + if (bad_proc) + { + gfc_error ("'%s' at %L is not a VALUE", sym->name, &lvalue->where); + return FAILURE; + } + } if (rvalue->rank != 0 && lvalue->rank != rvalue->rank) { diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c index 707fe5b..7828922 100644 --- a/gcc/fortran/intrinsic.c +++ b/gcc/fortran/intrinsic.c @@ -1670,7 +1670,7 @@ add_functions (void) make_generic ("log10", GFC_ISYM_LOG10, GFC_STD_F77); - add_sym_2 ("logical", 0, 1, BT_LOGICAL, dl, GFC_STD_F95, + add_sym_2 ("logical", 1, 1, BT_LOGICAL, dl, GFC_STD_F95, gfc_check_logical, gfc_simplify_logical, gfc_resolve_logical, l, BT_LOGICAL, dl, REQUIRED, kind, BT_INTEGER, di, OPTIONAL); diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index bde11a5..f7acb73 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -952,9 +952,17 @@ resolve_generic_f0 (gfc_expr * expr, gfc_symbol * sym) { expr->value.function.name = s->name; expr->value.function.esym = s; - expr->ts = s->ts; + + if (s->ts.type != BT_UNKNOWN) + expr->ts = s->ts; + else if (s->result != NULL && s->result->ts.type != BT_UNKNOWN) + expr->ts = s->result->ts; + if (s->as != NULL) expr->rank = s->as->rank; + else if (s->result != NULL && s->result->as != NULL) + expr->rank = s->result->as->rank; + return MATCH_YES; } diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 4bdc784..fe8d13c 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -2393,6 +2393,18 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) loop->dimen = ss->data.info.dimen; break; + /* As usual, lbound and ubound are exceptions!. */ + case GFC_SS_INTRINSIC: + switch (ss->expr->value.function.isym->generic_id) + { + case GFC_ISYM_LBOUND: + case GFC_ISYM_UBOUND: + loop->dimen = ss->data.info.dimen; + + default: + break; + } + default: break; } @@ -2418,6 +2430,17 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) gfc_conv_section_startstride (loop, ss, n); break; + case GFC_SS_INTRINSIC: + switch (ss->expr->value.function.isym->generic_id) + { + /* Fall through to supply start and stride. */ + case GFC_ISYM_LBOUND: + case GFC_ISYM_UBOUND: + break; + default: + continue; + } + case GFC_SS_CONSTRUCTOR: case GFC_SS_FUNCTION: for (n = 0; n < ss->data.info.dimen; n++) @@ -4391,7 +4414,14 @@ gfc_trans_deferred_array (gfc_symbol * sym, tree body) /* Get the descriptor type. */ type = TREE_TYPE (sym->backend_decl); - gcc_assert (GFC_DESCRIPTOR_TYPE_P (type)); + if (!GFC_DESCRIPTOR_TYPE_P (type)) + { + /* If the backend_decl is not a descriptor, we must have a pointer + to one. */ + descriptor = build_fold_indirect_ref (sym->backend_decl); + type = TREE_TYPE (descriptor); + gcc_assert (GFC_DESCRIPTOR_TYPE_P (type)); + } /* NULLIFY the data pointer. */ gfc_conv_descriptor_data_set (&fnblock, descriptor, null_pointer_node); diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 2a9c0db..4efe4bd 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -2536,6 +2536,12 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, tree fnbody) { tree result = TREE_VALUE (current_fake_result_decl); fnbody = gfc_trans_dummy_array_bias (proc_sym, result, fnbody); + + /* An automatic character length, pointer array result. */ + if (proc_sym->ts.type == BT_CHARACTER + && TREE_CODE (proc_sym->ts.cl->backend_decl) == VAR_DECL) + fnbody = gfc_trans_dummy_character (proc_sym, proc_sym->ts.cl, + fnbody); } else if (proc_sym->ts.type == BT_CHARACTER) { diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index 81e0a7c..4eceab6 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -1832,6 +1832,7 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym, gfc_charlen cl; gfc_expr *e; gfc_symbol *fsym; + stmtblock_t post; arglist = NULL_TREE; retargs = NULL_TREE; @@ -1861,6 +1862,7 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym, else info = NULL; + gfc_init_block (&post); gfc_init_interface_mapping (&mapping); need_interface_mapping = ((sym->ts.type == BT_CHARACTER && sym->ts.cl->length @@ -1970,7 +1972,7 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym, gfc_add_interface_mapping (&mapping, fsym, &parmse); gfc_add_block_to_block (&se->pre, &parmse.pre); - gfc_add_block_to_block (&se->post, &parmse.post); + gfc_add_block_to_block (&post, &parmse.post); /* Character strings are passed as two parameters, a length and a pointer. */ @@ -2177,6 +2179,12 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym, } } + /* Follow the function call with the argument post block. */ + if (byref) + gfc_add_block_to_block (&se->pre, &post); + else + gfc_add_block_to_block (&se->post, &post); + return has_alternate_specifier; } diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index b69ffef..1abc79a 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -3710,6 +3710,7 @@ gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr) newss->type = GFC_SS_INTRINSIC; newss->expr = expr; newss->next = ss; + newss->data.info.dimen = 1; return newss; } |