intrinsic at %L has more "
"than %d elements", &shape->where, GFC_MAX_DIMENSIONS);
return false;
}
gfc_simplify_expr (shape, 0);
shape_is_const = gfc_is_constant_expr (shape);
if (shape->expr_type == EXPR_ARRAY && shape_is_const)
{
gfc_expr *e;
int i, extent;
for (i = 0; i < shape_size; ++i)
{
e = gfc_constructor_lookup_expr (shape->value.constructor, i);
if (e->expr_type != EXPR_CONSTANT)
continue;
gfc_extract_int (e, &extent);
if (extent < 0)
{
gfc_error ("%qs argument of %qs intrinsic at %L has "
"negative element (%d)",
gfc_current_intrinsic_arg[1]->name,
gfc_current_intrinsic, &shape->where, extent);
return false;
}
}
}
if (pad != NULL)
{
if (!same_type_check (source, 0, pad, 2))
return false;
if (!array_check (pad, 2))
return false;
}
if (order != NULL)
{
if (!array_check (order, 3))
return false;
if (!type_check (order, 3, BT_INTEGER))
return false;
if (order->expr_type == EXPR_ARRAY && gfc_is_constant_expr (order))
{
int i, order_size, dim, perm[GFC_MAX_DIMENSIONS];
gfc_expr *e;
for (i = 0; i < GFC_MAX_DIMENSIONS; ++i)
perm[i] = 0;
gfc_array_size (order, &size);
order_size = mpz_get_ui (size);
mpz_clear (size);
if (order_size != shape_size)
{
gfc_error ("%qs argument of %qs intrinsic at %L "
"has wrong number of elements (%d/%d)",
gfc_current_intrinsic_arg[3]->name,
gfc_current_intrinsic, &order->where,
order_size, shape_size);
return false;
}
for (i = 1; i <= order_size; ++i)
{
e = gfc_constructor_lookup_expr (order->value.constructor, i-1);
if (e->expr_type != EXPR_CONSTANT)
continue;
gfc_extract_int (e, &dim);
if (dim < 1 || dim > order_size)
{
gfc_error ("%qs argument of %qs intrinsic at %L "
"has out-of-range dimension (%d)",
gfc_current_intrinsic_arg[3]->name,
gfc_current_intrinsic, &e->where, dim);
return false;
}
if (perm[dim-1] != 0)
{
gfc_error ("%qs argument of %qs intrinsic at %L has "
"invalid permutation of dimensions (dimension "
"%qd duplicated)",
gfc_current_intrinsic_arg[3]->name,
gfc_current_intrinsic, &e->where, dim);
return false;
}
perm[dim-1] = 1;
}
}
}
if (pad == NULL && shape->expr_type == EXPR_ARRAY && shape_is_const
&& !(source->expr_type == EXPR_VARIABLE && source->symtree->n.sym->as
&& source->symtree->n.sym->as->type == AS_ASSUMED_SIZE))
{
/* Check the match in size between source and destination. */
if (gfc_array_size (source, &nelems))
{
gfc_constructor *c;
bool test;
mpz_init_set_ui (size, 1);
for (c = gfc_constructor_first (shape->value.constructor);
c; c = gfc_constructor_next (c))
mpz_mul (size, size, c->expr->value.integer);
test = mpz_cmp (nelems, size) < 0 && mpz_cmp_ui (size, 0) > 0;
mpz_clear (nelems);
mpz_clear (size);
if (test)
{
gfc_error ("Without padding, there are not enough elements "
"in the intrinsic RESHAPE source at %L to match "
"the shape", &source->where);
return false;
}
}
}
return true;
}
bool
gfc_check_same_type_as (gfc_expr *a, gfc_expr *b)
{
if (a->ts.type != BT_DERIVED && a->ts.type != BT_CLASS)
{
gfc_error ("%qs argument of %qs intrinsic at %L "
"cannot be of type %s",
gfc_current_intrinsic_arg[0]->name,
gfc_current_intrinsic,
&a->where, gfc_typename (a));
return false;
}
if (!(gfc_type_is_extensible (a->ts.u.derived) || UNLIMITED_POLY (a)))
{
gfc_error ("%qs argument of %qs intrinsic at %L "
"must be of an extensible type",
gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic,
&a->where);
return false;
}
if (b->ts.type != BT_DERIVED && b->ts.type != BT_CLASS)
{
gfc_error ("%qs argument of %qs intrinsic at %L "
"cannot be of type %s",
gfc_current_intrinsic_arg[0]->name,
gfc_current_intrinsic,
&b->where, gfc_typename (b));
return false;
}
if (!(gfc_type_is_extensible (b->ts.u.derived) || UNLIMITED_POLY (b)))
{
gfc_error ("%qs argument of %qs intrinsic at %L "
"must be of an extensible type",
gfc_current_intrinsic_arg[1]->name, gfc_current_intrinsic,
&b->where);
return false;
}
return true;
}
bool
gfc_check_scale (gfc_expr *x, gfc_expr *i)
{
if (!type_check (x, 0, BT_REAL))
return false;
if (!type_check (i, 1, BT_INTEGER))
return false;
return true;
}
bool
gfc_check_scan (gfc_expr *x, gfc_expr *y, gfc_expr *z, gfc_expr *kind)
{
if (!type_check (x, 0, BT_CHARACTER))
return false;
if (!type_check (y, 1, BT_CHARACTER))
return false;
if (z != NULL && !type_check (z, 2, BT_LOGICAL))
return false;
if (!kind_check (kind, 3, BT_INTEGER))
return false;
if (kind && !gfc_notify_std (GFC_STD_F2003, "%qs intrinsic "
"with KIND argument at %L",
gfc_current_intrinsic, &kind->where))
return false;
if (!same_type_check (x, 0, y, 1))
return false;
return true;
}
bool
gfc_check_secnds (gfc_expr *r)
{
if (!type_check (r, 0, BT_REAL))
return false;
if (!kind_value_check (r, 0, 4))
return false;
if (!scalar_check (r, 0))
return false;
return true;
}
bool
gfc_check_selected_char_kind (gfc_expr *name)
{
if (!type_check (name, 0, BT_CHARACTER))
return false;
if (!kind_value_check (name, 0, gfc_default_character_kind))
return false;
if (!scalar_check (name, 0))
return false;
return true;
}
bool
gfc_check_selected_int_kind (gfc_expr *r)
{
if (!type_check (r, 0, BT_INTEGER))
return false;
if (!scalar_check (r, 0))
return false;
return true;
}
bool
gfc_check_selected_real_kind (gfc_expr *p, gfc_expr *r, gfc_expr *radix)
{
if (p == NULL && r == NULL
&& !gfc_notify_std (GFC_STD_F2008, "SELECTED_REAL_KIND with"
" neither % nor % argument at %L",
gfc_current_intrinsic_where))
return false;
if (p)
{
if (!type_check (p, 0, BT_INTEGER))
return false;
if (!scalar_check (p, 0))
return false;
}
if (r)
{
if (!type_check (r, 1, BT_INTEGER))
return false;
if (!scalar_check (r, 1))
return false;
}
if (radix)
{
if (!type_check (radix, 1, BT_INTEGER))
return false;
if (!scalar_check (radix, 1))
return false;
if (!gfc_notify_std (GFC_STD_F2008, "%qs intrinsic with "
"RADIX argument at %L", gfc_current_intrinsic,
&radix->where))
return false;
}
return true;
}
bool
gfc_check_set_exponent (gfc_expr *x, gfc_expr *i)
{
if (!type_check (x, 0, BT_REAL))
return false;
if (!type_check (i, 1, BT_INTEGER))
return false;
return true;
}
bool
gfc_check_shape (gfc_expr *source, gfc_expr *kind)
{
gfc_array_ref *ar;
if (gfc_invalid_null_arg (source))
return false;
if (!kind_check (kind, 1, BT_INTEGER))
return false;
if (kind && !gfc_notify_std (GFC_STD_F2003, "%qs intrinsic "
"with KIND argument at %L",
gfc_current_intrinsic, &kind->where))
return false;
if (source->rank == 0 || source->expr_type != EXPR_VARIABLE)
return true;
if (source->ref == NULL)
return false;
ar = gfc_find_array_ref (source);
if (ar->as && ar->as->type == AS_ASSUMED_SIZE && ar->type == AR_FULL)
{
gfc_error ("%