re PR fortran/50981 ([OOP] Wrong-code for scalarizing ELEMENTAL call with absent OPTIONAL argument)
PR fortran/50981 * trans.h (struct gfc_ss_info): New field data::scalar::can_be_null_ref * trans-array.c: If the reference can be NULL, save the reference instead of the value. * trans-expr.c (gfc_conv_expr): If we have saved a reference, dereference it. From-SVN: r182874
This commit is contained in:
parent
591823cc9a
commit
0192ef204c
4 changed files with 34 additions and 5 deletions
|
@ -1,3 +1,12 @@
|
|||
2012-01-04 Mikael Morin <mikael@gcc.gnu.org>
|
||||
|
||||
PR fortran/50981
|
||||
* trans.h (struct gfc_ss_info): New field data::scalar::can_be_null_ref
|
||||
* trans-array.c: If the reference can be NULL, save the reference
|
||||
instead of the value.
|
||||
* trans-expr.c (gfc_conv_expr): If we have saved a reference,
|
||||
dereference it.
|
||||
|
||||
2012-01-04 Mikael Morin <mikael@gcc.gnu.org>
|
||||
|
||||
* trans-expr.c (gfc_conv_expr): Move address taking...
|
||||
|
|
|
@ -2422,10 +2422,21 @@ gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript,
|
|||
break;
|
||||
|
||||
case GFC_SS_REFERENCE:
|
||||
/* Scalar argument to elemental procedure. Evaluate this
|
||||
now. */
|
||||
/* Scalar argument to elemental procedure. */
|
||||
gfc_init_se (&se, NULL);
|
||||
gfc_conv_expr (&se, expr);
|
||||
if (ss_info->data.scalar.can_be_null_ref)
|
||||
{
|
||||
/* If the actual argument can be absent (in other words, it can
|
||||
be a NULL reference), don't try to evaluate it; pass instead
|
||||
the reference directly. */
|
||||
gfc_conv_expr_reference (&se, expr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, evaluate the argument outside the loop and pass
|
||||
a reference to the value. */
|
||||
gfc_conv_expr (&se, expr);
|
||||
}
|
||||
gfc_add_block_to_block (&outer_loop->pre, &se.pre);
|
||||
gfc_add_block_to_block (&outer_loop->post, &se.post);
|
||||
if (gfc_is_class_scalar_expr (expr))
|
||||
|
|
|
@ -5331,6 +5331,11 @@ gfc_conv_expr (gfc_se * se, gfc_expr * expr)
|
|||
/* Substitute a scalar expression evaluated outside the scalarization
|
||||
loop. */
|
||||
se->expr = ss_info->data.scalar.value;
|
||||
/* If the reference can be NULL, the value field contains the reference,
|
||||
not the value the reference points to (see gfc_add_loop_ss_code). */
|
||||
if (ss_info->data.scalar.can_be_null_ref)
|
||||
se->expr = build_fold_indirect_ref_loc (input_location, se->expr);
|
||||
|
||||
se->string_length = ss_info->string_length;
|
||||
gfc_advance_se_ss_chain (se);
|
||||
return;
|
||||
|
|
|
@ -145,8 +145,9 @@ typedef enum
|
|||
GFC_SS_SCALAR,
|
||||
|
||||
/* Like GFC_SS_SCALAR it evaluates the expression outside the
|
||||
loop. Is always evaluated as a reference to the temporary.
|
||||
Used for elemental function arguments. */
|
||||
loop. Is always evaluated as a reference to the temporary, unless
|
||||
temporary evaluation can result in a NULL pointer dereferencing (case of
|
||||
optional arguments). Used for elemental function arguments. */
|
||||
GFC_SS_REFERENCE,
|
||||
|
||||
/* An array section. Scalarization indices will be substituted during
|
||||
|
@ -196,6 +197,9 @@ typedef struct gfc_ss_info
|
|||
struct
|
||||
{
|
||||
tree value;
|
||||
/* Tells whether the reference can be null in the GFC_SS_REFERENCE case.
|
||||
Used to handle elemental procedures' optional arguments. */
|
||||
bool can_be_null_ref;
|
||||
}
|
||||
scalar;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue