diff options
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/fortran/primary.c | 5 | ||||
-rw-r--r-- | gcc/fortran/resolve.c | 7 | ||||
-rw-r--r-- | gcc/fortran/trans-decl.c | 15 |
4 files changed, 35 insertions, 5 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index d9e0fea..e91159a 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,16 @@ +2015-01-18 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/55901 + * primary.c (gfc_match_varspec): Exclude dangling associate- + names with dimension 0 from being counted as arrays. + * resolve.c (resolve_assoc_var): Sub-strings are permissible + for associate-names, so exclude characters from the test for + misuse as arrays. + * trans-decl.c (gfc_get_symbol_decl): Associate-names can use + the hidden string length variable of their associated target. + Signal this by setting 'length' to a constant, if the decl for + the string length is a variable. + 2015-01-17 Paul Thomas <pault@gcc.gnu.org> PR fortran/64578 diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c index cbe7aa6..141f8cc 100644 --- a/gcc/fortran/primary.c +++ b/gcc/fortran/primary.c @@ -1857,7 +1857,10 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag, Thus if we have one and parentheses follow, we have to assume that it actually is one for now. The final decision will be made at resolution time, of course. */ - if (sym->assoc && gfc_peek_ascii_char () == '(') + if (sym->assoc && gfc_peek_ascii_char () == '(' + && !(sym->assoc->dangling && sym->assoc->st + && sym->assoc->st->n.sym + && sym->assoc->st->n.sym->attr.dimension == 0)) sym->attr.dimension = 1; if ((equiv_flag && gfc_peek_ascii_char () == '(') diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 7a16add..a9645a0 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -7935,8 +7935,11 @@ resolve_assoc_var (gfc_symbol* sym, bool resolve_target) /* Finally resolve if this is an array or not. */ if (sym->attr.dimension && target->rank == 0) { - gfc_error ("Associate-name %qs at %L is used as array", - sym->name, &sym->declared_at); + /* primary.c makes the assumption that a reference to an associate + name followed by a left parenthesis is an array reference. */ + if (sym->ts.type != BT_CHARACTER) + gfc_error ("Associate-name %qs at %L is used as array", + sym->name, &sym->declared_at); sym->attr.dimension = 0; return; } diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index a73620f..5beb6f7 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -1494,9 +1494,18 @@ gfc_get_symbol_decl (gfc_symbol * sym) gfc_internal_error ("intrinsic variable which isn't a procedure"); /* Create string length decl first so that they can be used in the - type declaration. */ + type declaration. For associate names, the target character + length is used. Set 'length' to a constant so that if the + string lenght is a variable, it is not finished a second time. */ if (sym->ts.type == BT_CHARACTER) - length = gfc_create_string_length (sym); + { + if (sym->attr.associate_var + && sym->ts.u.cl->backend_decl + && TREE_CODE (sym->ts.u.cl->backend_decl) == VAR_DECL) + length = gfc_index_zero_node; + else + length = gfc_create_string_length (sym); + } /* Create the decl for the variable. */ decl = build_decl (sym->declared_at.lb->location, @@ -1558,6 +1567,8 @@ gfc_get_symbol_decl (gfc_symbol * sym) /* Character variables need special handling. */ gfc_allocate_lang_decl (decl); + /* Associate names can use the hidden string length variable + of their associated target. */ if (TREE_CODE (length) != INTEGER_CST) { gfc_finish_var_decl (length, sym); |