[Patches, Fortran] ALLOCATE & CAF library.
Tobias Burnus
burnus@net-b.de
Thu Jul 21 14:19:00 GMT 2011
On 07/21/2011 01:09 PM, Daniel Carrera wrote:
> This patch now fixes an existing bug in GFortran whereby the ALLOCATE
> statement only gets error checking if you are allocating a scalar.
Somehow that does not seem to work. I just tried a vanilla trunk with
just your patch applied. For the following, I do not get a single
"goto". That's different to your dumps, where you get two (though, in
your case, you had a scalar and a scalar coarray).
integer, allocatable :: A(:), B[:]
integer :: stat
character(len=33) :: str
allocate(A(1), B[*], stat=stat)!, errmsg=str)
end
Thus, I wonder whether you have send the correct patch, if not, the
question is really why we see those large differences.
That also fits with the code:
- if (!gfc_array_allocate (&se, expr, pstat))
+ if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen))
{
...
if (code->expr1 || code->expr2)
{
- tmp = build1_v (GOTO_EXPR, error_label);
+ /* The coarray library already sets the errmsg. */
+ if (gfc_option.coarray == GFC_FCOARRAY_LIB
+ && gfc_expr_attr (expr).codimension)
+ tmp = build1_v (GOTO_EXPR, label_finish);
+ else
+ tmp = build1_v (GOTO_EXPR, label_errmsg);
...
}
Where the code is still in the scalar-allocation loop.
* * *
To the patch itself:
/* Either STAT= and/or ERRMSG is present. */
if (code->expr1 || code->expr2)
> @@ -4709,9 +4712,23 @@ gfc_trans_allocate (gfc_code * code)
> {
> + /* STAT= */
> tree gfc_int4_type_node = gfc_get_int_type (4)
Can you change the "if ()" into "if(code->expr1)", i.e. only checking
whether STAT= is present? There is no point of generating code for
ERRMSG= if STAT= is not present.
Assuming you had: ALLOCATE(A, ERRMSG=str).
a) Everything goes fine. Result: "str" remains unmodified.
b) There is an error: As there is no STAT=, a run-time error is
generated and there is no process left, which an make use of the error
string.
Thus, using "if (code->expr1)" is sufficient.
> + /* ERRMSG= */
> + errmsg = null_pointer_node;
> + errlen = build_int_cst (gfc_charlen_type_node, 0);
> + if (code->expr2)
> + {
> + gfc_init_se (&se, NULL);
> + gfc_conv_expr_lhs (&se, code->expr2);
> +
> + errlen = gfc_get_expr_charlen (code->expr2);
> + errmsg = gfc_build_addr_expr (pchar_type_node, se.expr);
> + }
As said in previous review: Use:
else
{
errmsg = null_pointer_node;
errlen = build_int_cst (gfc_charlen_type_node, 0);
}
That avoids evaluating uselessly build_int_cst, which is cheap but
changing the code comes for free.
> - /* STAT block. */
> - if (code->expr1)
> + /* STAT or ERRMSG. */
> + if (code->expr1 || code->expr2)
I believe here applies the same: The code will be unreachable if there
is no STAT=.
> + /* STAT or ERRMSG. */
> + if (code->expr1 || code->expr2)
Ditto.
Tobias
More information about the Fortran
mailing list