/* Notes for DATA statement implementation:
-
+
We first assign initial value to each symbol by gfc_assign_data_value
during resolving DATA statement. Refer to check_data_variable and
traverse_data_list in resolve.c.
-
+
The complexity exists in the handling of array section, implied do
and array of struct appeared in DATA statement.
-
+
We call gfc_conv_structure, gfc_con_array_array_initializer,
etc., to convert the initial value. Refer to trans-expr.c and
trans-array.c. */
}
break;
+ case REF_INQUIRY:
+
+ /* This breaks with the other reference types in that the output
+ constructor has to be of type COMPLEX, whereas the lvalue is
+ of type REAL. The rvalue is copied to the real or imaginary
+ part as appropriate. */
+ gcc_assert (ref->next == NULL && last_ts->type == BT_COMPLEX);
+ expr = gfc_copy_expr (rvalue);
+ if (!gfc_compare_types (&lvalue->ts, &expr->ts))
+ gfc_convert_type (expr, &lvalue->ts, 0);
+
+ if (last_con->expr)
+ gfc_free_expr (last_con->expr);
+
+ last_con->expr = gfc_get_constant_expr (BT_COMPLEX,
+ last_ts->kind,
+ &lvalue->where);
+
+ /* Rejection of LEN and KIND inquiry references is handled
+ elsewhere. The error here is added as backup. The assertion
+ of F2008 for RE and IM is also done elsewhere. */
+ switch (ref->u.i)
+ {
+ case INQUIRY_LEN:
+ case INQUIRY_KIND:
+ gfc_error ("LEN or KIND inquiry ref in DATA statement at %L",
+ &lvalue->where);
+ goto abort;
+ case INQUIRY_RE:
+ mpfr_set (mpc_realref (last_con->expr->value.complex),
+ expr->value.real,
+ GFC_RND_MODE);
+ mpfr_set_ui (mpc_imagref (last_con->expr->value.complex),
+ 0.0, GFC_RND_MODE);
+ break;
+ case INQUIRY_IM:
+ mpfr_set (mpc_imagref (last_con->expr->value.complex),
+ expr->value.real,
+ GFC_RND_MODE);
+ mpfr_set_ui (mpc_realref (last_con->expr->value.complex),
+ 0.0, GFC_RND_MODE);
+ break;
+ }
+
+ gfc_free_expr (expr);
+ mpz_clear (offset);
+ return true;
+
default:
gcc_unreachable ();
}
&& gfc_has_default_initializer (lvalue->ts.u.derived))
{
gfc_error ("Nonpointer object %qs with default initialization "
- "shall not appear in a DATA statement at %L",
+ "shall not appear in a DATA statement at %L",
symbol->name, &lvalue->where);
return false;
}
/* Modify the index of array section and re-calculate the array offset. */
-void
+void
gfc_advance_section (mpz_t *section_index, gfc_array_ref *ar,
mpz_t *offset_ret)
{
int i;
mpz_t delta;
- mpz_t tmp;
+ mpz_t tmp;
bool forwards;
int cmp;
gfc_expr *start, *end, *stride;
forwards = true;
else
forwards = false;
- gfc_free_expr(stride);
+ gfc_free_expr(stride);
}
else
{
mpz_add_ui (section_index[i], section_index[i], 1);
forwards = true;
}
-
+
if (ar->end[i])
{
end = gfc_copy_expr(ar->end[i]);
if(!gfc_simplify_expr(end, 1))
gfc_internal_error("Simplification error");
cmp = mpz_cmp (section_index[i], end->value.integer);
- gfc_free_expr(end);
+ gfc_free_expr(end);
}
else
cmp = mpz_cmp (section_index[i], ar->as->upper[i]->value.integer);
if(!gfc_simplify_expr(start, 1))
gfc_internal_error("Simplification error");
mpz_set (section_index[i], start->value.integer);
- gfc_free_expr(start);
+ gfc_free_expr(start);
}
else
mpz_set (section_index[i], ar->as->lower[i]->value.integer);
mpz_mul (tmp, tmp, delta);
mpz_add (*offset_ret, tmp, *offset_ret);
- mpz_sub (tmp, ar->as->upper[i]->value.integer,
+ mpz_sub (tmp, ar->as->upper[i]->value.integer,
ar->as->lower[i]->value.integer);
mpz_add_ui (tmp, tmp, 1);
mpz_mul (delta, tmp, delta);
/* Get the integer value into RET_AS and SECTION from AS and AR, and return
offset. */
-
+
void
gfc_get_section_index (gfc_array_ref *ar, mpz_t *section_index, mpz_t *offset)
{
gcc_unreachable ();
}
- mpz_sub (tmp, ar->as->upper[i]->value.integer,
+ mpz_sub (tmp, ar->as->upper[i]->value.integer,
ar->as->lower[i]->value.integer);
mpz_add_ui (tmp, tmp, 1);
mpz_mul (delta, tmp, delta);
--- /dev/null
+! { dg-do run }
+!
+! Test the fix for PR98022.
+!
+! Contributed by Arseny Solokha <asolokha@gmx.com>
+!
+module ur
+contains
+! The reporter's test.
+ function kn1() result(hm2)
+ complex :: hm(1:2), hm2(1:2)
+ data (hm(md)%re, md=1,2)/1.0, 2.0/
+ hm2 = hm
+ end function kn1
+
+! Check for derived types with complex components.
+ function kn2() result(hm2)
+ type t
+ complex :: c
+ integer :: i
+ end type
+ type (t) :: hm(1:2)
+ complex :: hm2(1:2)
+ data (hm(md)%c%im, md=1,2)/1.0, 2.0/
+ data (hm(md)%i, md=1,2)/1, 2/
+ hm2 = hm%c
+ end function kn2
+end module ur
+
+ use ur
+ if (any (kn1() .ne. [(1.0,0.0),(2.0,0.0)])) stop 1
+ if (any (kn2() .ne. [(0.0,1.0),(0.0,2.0)])) stop 2
+end