Commit 707905d0 by Paul Thomas

re PR fortran/60458 (Error message on associate: deferred type parameter and…

re PR fortran/60458 (Error message on associate: deferred type parameter and requires either the pointer or allocatable attribute)

2017-10-04  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/60458
	PR fortran/77296
	* resolve.c (resolve_assoc_var): Deferred character type
	associate names must not receive an integer conatant length.
	* symbol.c (gfc_is_associate_pointer): Deferred character
	length functions also require an associate pointer.
	* trans-decl.c (gfc_get_symbol_decl): Deferred character
	length functions or derived type components require the assoc
	name to have variable string length.
	* trans-stmt.c (trans_associate_var): Set the string length of
	deferred string length associate names. The address expression
	is not needed for allocatable, pointer or dummy targets. Change
	the comment about defered string length targets.

2017-10-04  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/77296
	* gfortran.dg/associate_32.f03 : New test.

From-SVN: r253400
parent 3e3d1b23
2017-10-04 Paul Thomas <pault@gcc.gnu.org>
PR fortran/60458
PR fortran/77296
* resolve.c (resolve_assoc_var): Deferred character type
associate names must not receive an integer conatant length.
* symbol.c (gfc_is_associate_pointer): Deferred character
length functions also require an associate pointer.
* trans-decl.c (gfc_get_symbol_decl): Deferred character
length functions or derived type components require the assoc
name to have variable string length.
* trans-stmt.c (trans_associate_var): Set the string length of
deferred string length associate names. The address expression
is not needed for allocatable, pointer or dummy targets. Change
the comment about defered string length targets.
2017-10-03 Thomas Koenig <tkoenig@gcc.gnu.org> 2017-10-03 Thomas Koenig <tkoenig@gcc.gnu.org>
* io.c (match_wait_element): Correctly match END and EOR tags. * io.c (match_wait_element): Correctly match END and EOR tags.
......
...@@ -8530,7 +8530,7 @@ resolve_assoc_var (gfc_symbol* sym, bool resolve_target) ...@@ -8530,7 +8530,7 @@ resolve_assoc_var (gfc_symbol* sym, bool resolve_target)
if (!sym->ts.u.cl) if (!sym->ts.u.cl)
sym->ts.u.cl = target->ts.u.cl; sym->ts.u.cl = target->ts.u.cl;
if (!sym->ts.u.cl->length) if (!sym->ts.u.cl->length && !sym->ts.deferred)
sym->ts.u.cl->length sym->ts.u.cl->length
= gfc_get_int_expr (gfc_default_integer_kind, = gfc_get_int_expr (gfc_default_integer_kind,
NULL, target->value.character.length); NULL, target->value.character.length);
......
...@@ -5054,6 +5054,12 @@ gfc_is_associate_pointer (gfc_symbol* sym) ...@@ -5054,6 +5054,12 @@ gfc_is_associate_pointer (gfc_symbol* sym)
if (sym->ts.type == BT_CLASS) if (sym->ts.type == BT_CLASS)
return true; return true;
if (sym->ts.type == BT_CHARACTER
&& sym->ts.deferred
&& sym->assoc->target
&& sym->assoc->target->expr_type == EXPR_FUNCTION)
return true;
if (!sym->assoc->variable) if (!sym->assoc->variable)
return false; return false;
......
...@@ -1695,6 +1695,14 @@ gfc_get_symbol_decl (gfc_symbol * sym) ...@@ -1695,6 +1695,14 @@ gfc_get_symbol_decl (gfc_symbol * sym)
if (sym->ts.type == BT_CHARACTER) if (sym->ts.type == BT_CHARACTER)
{ {
if (sym->attr.associate_var if (sym->attr.associate_var
&& sym->ts.deferred
&& sym->assoc && sym->assoc->target
&& ((sym->assoc->target->expr_type == EXPR_VARIABLE
&& sym->assoc->target->symtree->n.sym->ts.type != BT_CHARACTER)
|| sym->assoc->target->expr_type == EXPR_FUNCTION))
sym->ts.u.cl->backend_decl = NULL_TREE;
if (sym->attr.associate_var
&& sym->ts.u.cl->backend_decl && sym->ts.u.cl->backend_decl
&& VAR_P (sym->ts.u.cl->backend_decl)) && VAR_P (sym->ts.u.cl->backend_decl))
length = gfc_index_zero_node; length = gfc_index_zero_node;
......
...@@ -1533,6 +1533,7 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block) ...@@ -1533,6 +1533,7 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
bool need_len_assign; bool need_len_assign;
bool whole_array = true; bool whole_array = true;
gfc_ref *ref; gfc_ref *ref;
symbol_attribute attr;
gcc_assert (sym->assoc); gcc_assert (sym->assoc);
e = sym->assoc->target; e = sym->assoc->target;
...@@ -1592,6 +1593,17 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block) ...@@ -1592,6 +1593,17 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
gfc_conv_expr_descriptor (&se, e); gfc_conv_expr_descriptor (&se, e);
if (sym->ts.type == BT_CHARACTER
&& sym->ts.deferred
&& !sym->attr.select_type_temporary
&& VAR_P (sym->ts.u.cl->backend_decl)
&& se.string_length != sym->ts.u.cl->backend_decl)
{
gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl,
fold_convert (gfc_charlen_type_node,
se.string_length));
}
/* If we didn't already do the pointer assignment, set associate-name /* If we didn't already do the pointer assignment, set associate-name
descriptor to the one generated for the temporary. */ descriptor to the one generated for the temporary. */
if ((!sym->assoc->variable && !cst_array_ctor) if ((!sym->assoc->variable && !cst_array_ctor)
...@@ -1758,8 +1770,35 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block) ...@@ -1758,8 +1770,35 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
need_len_assign = need_len_assign && sym->ts.type == BT_CHARACTER; need_len_assign = need_len_assign && sym->ts.type == BT_CHARACTER;
} }
tmp = TREE_TYPE (sym->backend_decl); if (sym->ts.type == BT_CHARACTER
tmp = gfc_build_addr_expr (tmp, se.expr); && sym->ts.deferred
&& !sym->attr.select_type_temporary
&& VAR_P (sym->ts.u.cl->backend_decl)
&& se.string_length != sym->ts.u.cl->backend_decl)
{
gfc_add_modify (&se.pre, sym->ts.u.cl->backend_decl,
fold_convert (gfc_charlen_type_node,
se.string_length));
if (e->expr_type == EXPR_FUNCTION)
{
tmp = gfc_call_free (sym->backend_decl);
gfc_add_expr_to_block (&se.post, tmp);
}
}
attr = gfc_expr_attr (e);
if (sym->ts.type == BT_CHARACTER && e->ts.type == BT_CHARACTER
&& (attr.allocatable || attr.pointer || attr.dummy))
{
/* These are pointer types already. */
tmp = fold_convert (TREE_TYPE (sym->backend_decl), se.expr);
}
else
{
tmp = TREE_TYPE (sym->backend_decl);
tmp = gfc_build_addr_expr (tmp, se.expr);
}
gfc_add_modify (&se.pre, sym->backend_decl, tmp); gfc_add_modify (&se.pre, sym->backend_decl, tmp);
gfc_add_init_cleanup (block, gfc_finish_block( &se.pre), gfc_add_init_cleanup (block, gfc_finish_block( &se.pre),
...@@ -1784,7 +1823,7 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block) ...@@ -1784,7 +1823,7 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
gfc_init_se (&se, NULL); gfc_init_se (&se, NULL);
if (e->symtree->n.sym->ts.type == BT_CHARACTER) if (e->symtree->n.sym->ts.type == BT_CHARACTER)
{ {
/* What about deferred strings? */ /* Deferred strings are dealt with in the preceeding. */
gcc_assert (!e->symtree->n.sym->ts.deferred); gcc_assert (!e->symtree->n.sym->ts.deferred);
tmp = e->symtree->n.sym->ts.u.cl->backend_decl; tmp = e->symtree->n.sym->ts.u.cl->backend_decl;
} }
......
2017-10-04 Paul Thomas <pault@gcc.gnu.org>
PR fortran/77296
* gfortran.dg/associate_32.f03 : New test.
2017-10-04 Paolo Carlini <paolo.carlini@oracle.com> 2017-10-04 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/78816 PR c++/78816
......
! { dg-do run }
!
! Tests fix for PR77296 and other bugs found on the way.
!
! Contributed by Matt Thompson <matthew.thompson@nasa.gov>
!
program test
implicit none
type :: str_type
character(len=:), allocatable :: str
end type
character(len=:), allocatable :: s, sd(:)
character(len=2), allocatable :: sf, sfd(:)
character(len=6) :: str
type(str_type) :: string
s = 'ab'
associate(ss => s)
if (ss .ne. 'ab') call abort ! This is the original bug.
ss = 'c'
end associate
if (s .ne. 'c ') call abort ! No reallocation within ASSOCIATE block!
sf = 'c'
associate(ss => sf)
if (ss .ne. 'c ') call abort ! This the bug in comment #2 of the PR.
ss = 'cd'
end associate
sd = [s, sf]
associate(ss => sd)
if (any (ss .ne. ['c ','cd'])) call abort
end associate
sfd = [sd,'ef']
associate(ss => sfd)
if (any (ss .ne. ['c ','cd','ef'])) call abort
ss = ['gh']
end associate
if (any (sfd .ne. ['gh','cd','ef'])) call abort ! No reallocation!
string%str = 'xyz'
associate(ss => string%str)
if (ss .ne. 'xyz') call abort
ss = 'c'
end associate
if (string%str .ne. 'c ') call abort ! No reallocation!
str = "foobar"
call test_char (5 , str)
IF (str /= "abcder") call abort
associate(ss => foo())
if (ss .ne. 'pqrst') call abort
end associate
associate(ss => bar())
if (ss(2) .ne. 'uvwxy') call abort
end associate
! The deallocation is not strictly necessary but it does allow
! other memory leakage to be tested for.
deallocate (s, sd, sf, sfd, string%str)
contains
! This is a modified version of the subroutine in associate_1.f03.
! 'str' is now a dummy.
SUBROUTINE test_char (n, str)
INTEGER, INTENT(IN) :: n
CHARACTER(LEN=n) :: str
ASSOCIATE (my => str)
IF (LEN (my) /= n) call abort
IF (my /= "fooba") call abort
my = "abcde"
END ASSOCIATE
IF (str /= "abcde") call abort
END SUBROUTINE test_char
function foo() result(res)
character (len=:), pointer :: res
allocate (res, source = 'pqrst')
end function
function bar() result(res)
character (len=:), allocatable :: res(:)
allocate (res, source = ['pqrst','uvwxy'])
end function
end program test
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment