aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/decl.c')
-rw-r--r--gcc/fortran/decl.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index d8988fd..b2f401f 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -74,6 +74,20 @@ gfc_symbol *gfc_new_block;
/********************* DATA statement subroutines *********************/
+static bool in_match_data = false;
+
+bool
+gfc_in_match_data (void)
+{
+ return in_match_data;
+}
+
+void
+gfc_set_in_match_data (bool set_value)
+{
+ in_match_data = set_value;
+}
+
/* Free a gfc_data_variable structure and everything beneath it. */
static void
@@ -455,6 +469,8 @@ gfc_match_data (void)
gfc_data *new;
match m;
+ gfc_set_in_match_data (true);
+
for (;;)
{
new = gfc_get_data ();
@@ -477,6 +493,8 @@ gfc_match_data (void)
gfc_match_char (','); /* Optional comma */
}
+ gfc_set_in_match_data (false);
+
if (gfc_pure (NULL))
{
gfc_error ("DATA statement at %C is not allowed in a PURE procedure");
@@ -486,6 +504,7 @@ gfc_match_data (void)
return MATCH_YES;
cleanup:
+ gfc_set_in_match_data (false);
gfc_free_data (new);
return MATCH_ERROR;
}
@@ -743,7 +762,7 @@ build_sym (const char *name, gfc_charlen * cl,
truncated. */
void
-gfc_set_constant_character_len (int len, gfc_expr * expr)
+gfc_set_constant_character_len (int len, gfc_expr * expr, bool array)
{
char * s;
int slen;
@@ -758,6 +777,18 @@ gfc_set_constant_character_len (int len, gfc_expr * expr)
memcpy (s, expr->value.character.string, MIN (len, slen));
if (len > slen)
memset (&s[slen], ' ', len - slen);
+
+ if (gfc_option.warn_character_truncation && slen > len)
+ gfc_warning_now ("CHARACTER expression at %L is being truncated "
+ "(%d/%d)", &expr->where, slen, len);
+
+ /* Apply the standard by 'hand' otherwise it gets cleared for
+ initializers. */
+ if (array && slen < len && !(gfc_option.allow_std & GFC_STD_GNU))
+ gfc_error_now ("The CHARACTER elements of the array constructor "
+ "at %L must have the same length (%d/%d)",
+ &expr->where, slen, len);
+
s[len] = '\0';
gfc_free (expr->value.character.string);
expr->value.character.string = s;
@@ -909,13 +940,13 @@ add_init_expr_to_sym (const char *name, gfc_expr ** initp,
gfc_constructor * p;
if (init->expr_type == EXPR_CONSTANT)
- gfc_set_constant_character_len (len, init);
+ gfc_set_constant_character_len (len, init, false);
else if (init->expr_type == EXPR_ARRAY)
{
gfc_free_expr (init->ts.cl->length);
init->ts.cl->length = gfc_copy_expr (sym->ts.cl->length);
for (p = init->value.constructor; p; p = p->next)
- gfc_set_constant_character_len (len, p->expr);
+ gfc_set_constant_character_len (len, p->expr, false);
}
}
}
@@ -4025,7 +4056,7 @@ do_parm (void)
&& init->ts.type == BT_CHARACTER
&& init->ts.kind == 1)
gfc_set_constant_character_len (
- mpz_get_si (sym->ts.cl->length->value.integer), init);
+ mpz_get_si (sym->ts.cl->length->value.integer), init, false);
sym->value = init;
return MATCH_YES;