|
|
3db796 |
From e4c3d25a9133224535b3142ed31e8a8be1ad356b Mon Sep 17 00:00:00 2001
|
|
|
3db796 |
From: Jim MacArthur <jim.macarthur@codethink.co.uk>
|
|
|
3db796 |
Date: Wed, 7 Oct 2015 17:04:06 -0400
|
|
|
3db796 |
Subject: [PATCH 10/23] Allow mixed string length and array specification in
|
|
|
3db796 |
character declarations.
|
|
|
3db796 |
|
|
|
3db796 |
---
|
|
|
3db796 |
|
|
|
3db796 |
0010-Allow-mixed-string-length-and-array-specification-in.patch
|
|
|
3db796 |
|
|
|
3db796 |
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
|
|
|
3db796 |
index 6d3d28a..c90f9de 100644
|
|
|
3db796 |
--- a/gcc/fortran/decl.c
|
|
|
3db796 |
+++ b/gcc/fortran/decl.c
|
|
|
3db796 |
@@ -2145,6 +2145,35 @@ check_function_name (char *name)
|
|
|
3db796 |
}
|
|
|
3db796 |
|
|
|
3db796 |
|
|
|
3db796 |
+static match
|
|
|
3db796 |
+match_character_length_clause (gfc_charlen **cl, bool *cl_deferred, int elem)
|
|
|
3db796 |
+{
|
|
|
3db796 |
+ gfc_expr* char_len;
|
|
|
3db796 |
+ char_len = NULL;
|
|
|
3db796 |
+
|
|
|
3db796 |
+ match m = match_char_length (&char_len, cl_deferred, false);
|
|
|
3db796 |
+ if (m == MATCH_YES)
|
|
|
3db796 |
+ {
|
|
|
3db796 |
+ *cl = gfc_new_charlen (gfc_current_ns, NULL);
|
|
|
3db796 |
+ (*cl)->length = char_len;
|
|
|
3db796 |
+ }
|
|
|
3db796 |
+ else if (m == MATCH_NO)
|
|
|
3db796 |
+ {
|
|
|
3db796 |
+ if (elem > 1
|
|
|
3db796 |
+ && (current_ts.u.cl->length == NULL
|
|
|
3db796 |
+ || current_ts.u.cl->length->expr_type != EXPR_CONSTANT))
|
|
|
3db796 |
+ {
|
|
|
3db796 |
+ *cl = gfc_new_charlen (gfc_current_ns, NULL);
|
|
|
3db796 |
+ (*cl)->length = gfc_copy_expr (current_ts.u.cl->length);
|
|
|
3db796 |
+ }
|
|
|
3db796 |
+ else
|
|
|
3db796 |
+ *cl = current_ts.u.cl;
|
|
|
3db796 |
+
|
|
|
3db796 |
+ *cl_deferred = current_ts.deferred;
|
|
|
3db796 |
+ }
|
|
|
3db796 |
+ return m;
|
|
|
3db796 |
+}
|
|
|
3db796 |
+
|
|
|
3db796 |
/* Match a variable name with an optional initializer. When this
|
|
|
3db796 |
subroutine is called, a variable is expected to be parsed next.
|
|
|
3db796 |
Depending on what is happening at the moment, updates either the
|
|
|
3db796 |
@@ -2154,7 +2183,7 @@ static match
|
|
|
3db796 |
variable_decl (int elem)
|
|
|
3db796 |
{
|
|
|
3db796 |
char name[GFC_MAX_SYMBOL_LEN + 1];
|
|
|
3db796 |
- gfc_expr *initializer, *char_len;
|
|
|
3db796 |
+ gfc_expr *initializer;
|
|
|
3db796 |
gfc_array_spec *as;
|
|
|
3db796 |
gfc_array_spec *cp_as; /* Extra copy for Cray Pointees. */
|
|
|
3db796 |
gfc_charlen *cl;
|
|
|
3db796 |
@@ -2163,6 +2192,7 @@ variable_decl (int elem)
|
|
|
3db796 |
match m;
|
|
|
3db796 |
bool t;
|
|
|
3db796 |
gfc_symbol *sym;
|
|
|
3db796 |
+ match cl_match;
|
|
|
3db796 |
|
|
|
3db796 |
initializer = NULL;
|
|
|
3db796 |
as = NULL;
|
|
|
3db796 |
@@ -2177,6 +2207,20 @@ variable_decl (int elem)
|
|
|
3db796 |
|
|
|
3db796 |
var_locus = gfc_current_locus;
|
|
|
3db796 |
|
|
|
3db796 |
+
|
|
|
3db796 |
+ cl = NULL;
|
|
|
3db796 |
+ cl_deferred = false;
|
|
|
3db796 |
+ cl_match = MATCH_NO;
|
|
|
3db796 |
+
|
|
|
3db796 |
+ /* Check for a character length clause before an array clause */
|
|
|
3db796 |
+ if ((gfc_option.allow_std & GFC_STD_EXTRA_LEGACY)
|
|
|
3db796 |
+ && current_ts.type == BT_CHARACTER)
|
|
|
3db796 |
+ {
|
|
|
3db796 |
+ cl_match = match_character_length_clause (&cl, &cl_deferred, elem);
|
|
|
3db796 |
+ if (cl_match == MATCH_ERROR)
|
|
|
3db796 |
+ goto cleanup;
|
|
|
3db796 |
+ }
|
|
|
3db796 |
+
|
|
|
3db796 |
/* Now we could see the optional array spec. or character length. */
|
|
|
3db796 |
m = gfc_match_array_spec (&as, true, true);
|
|
|
3db796 |
if (m == MATCH_ERROR)
|
|
|
3db796 |
@@ -2268,40 +2312,12 @@ variable_decl (int elem)
|
|
|
3db796 |
}
|
|
|
3db796 |
}
|
|
|
3db796 |
|
|
|
3db796 |
- char_len = NULL;
|
|
|
3db796 |
- cl = NULL;
|
|
|
3db796 |
- cl_deferred = false;
|
|
|
3db796 |
-
|
|
|
3db796 |
- if (current_ts.type == BT_CHARACTER)
|
|
|
3db796 |
+ /* Second chance for a character length clause */
|
|
|
3db796 |
+ if (cl_match == MATCH_NO && current_ts.type == BT_CHARACTER)
|
|
|
3db796 |
{
|
|
|
3db796 |
- switch (match_char_length (&char_len, &cl_deferred, false))
|
|
|
3db796 |
- {
|
|
|
3db796 |
- case MATCH_YES:
|
|
|
3db796 |
- cl = gfc_new_charlen (gfc_current_ns, NULL);
|
|
|
3db796 |
-
|
|
|
3db796 |
- cl->length = char_len;
|
|
|
3db796 |
- break;
|
|
|
3db796 |
-
|
|
|
3db796 |
- /* Non-constant lengths need to be copied after the first
|
|
|
3db796 |
- element. Also copy assumed lengths. */
|
|
|
3db796 |
- case MATCH_NO:
|
|
|
3db796 |
- if (elem > 1
|
|
|
3db796 |
- && (current_ts.u.cl->length == NULL
|
|
|
3db796 |
- || current_ts.u.cl->length->expr_type != EXPR_CONSTANT))
|
|
|
3db796 |
- {
|
|
|
3db796 |
- cl = gfc_new_charlen (gfc_current_ns, NULL);
|
|
|
3db796 |
- cl->length = gfc_copy_expr (current_ts.u.cl->length);
|
|
|
3db796 |
- }
|
|
|
3db796 |
- else
|
|
|
3db796 |
- cl = current_ts.u.cl;
|
|
|
3db796 |
-
|
|
|
3db796 |
- cl_deferred = current_ts.deferred;
|
|
|
3db796 |
-
|
|
|
3db796 |
- break;
|
|
|
3db796 |
-
|
|
|
3db796 |
- case MATCH_ERROR:
|
|
|
3db796 |
- goto cleanup;
|
|
|
3db796 |
- }
|
|
|
3db796 |
+ m = match_character_length_clause( &cl, &cl_deferred, elem );
|
|
|
3db796 |
+ if (m == MATCH_ERROR)
|
|
|
3db796 |
+ goto cleanup;
|
|
|
3db796 |
}
|
|
|
3db796 |
|
|
|
3db796 |
/* The dummy arguments and result of the abreviated form of MODULE
|