re PR fortran/49110 (Deferred-length character result triggers (false positive) error for pure procedures)

2012-05-14  Tobias Burnus  <burnus@net-b.de>

        PR fortran/49110
        PR fortran/51055
        PR fortran/53329
        * trans-expr.c (gfc_trans_assignment_1): Fix allocation
        handling for assignment of function results to allocatable
        deferred-length strings.
        * trans-decl.c (gfc_create_string_length): For deferred-length
        module variables, include module name in the assembler name.
        (gfc_get_symbol_decl): Don't override the assembler name.

2012-05-14  Tobias Burnus  <burnus@net-b.de>

        PR fortran/49110
        PR fortran/51055
        PR fortran/53329
        * gfortran.dg/deferred_type_param_4.f90: New.
        * gfortran.dg/deferred_type_param_6.f90: New.

From-SVN: r187472
This commit is contained in:
Tobias Burnus 2012-05-14 18:45:16 +02:00 committed by Tobias Burnus
parent 5bb53d1a1d
commit 6052c29931
6 changed files with 107 additions and 21 deletions

View File

@ -1,3 +1,15 @@
2012-05-14 Tobias Burnus <burnus@net-b.de>
PR fortran/49110
PR fortran/51055
PR fortran/53329
* trans-expr.c (gfc_trans_assignment_1): Fix allocation
handling for assignment of function results to allocatable
deferred-length strings.
* trans-decl.c (gfc_create_string_length): For deferred-length
module variables, include module name in the assembler name.
(gfc_get_symbol_decl): Don't override the assembler name.
2012-05-14 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR 53063

View File

@ -1087,11 +1087,14 @@ gfc_create_string_length (gfc_symbol * sym)
if (sym->ts.u.cl->backend_decl == NULL_TREE)
{
tree length;
char name[GFC_MAX_MANGLED_SYMBOL_LEN + 2];
const char *name;
/* Also prefix the mangled name. */
strcpy (&name[1], sym->name);
name[0] = '.';
if (sym->module)
name = gfc_get_string (".__%s_MOD_%s", sym->module, sym->name);
else
name = gfc_get_string (".%s", sym->name);
length = build_decl (input_location,
VAR_DECL, get_identifier (name),
gfc_charlen_type_node);
@ -1101,6 +1104,13 @@ gfc_create_string_length (gfc_symbol * sym)
gfc_defer_symbol_init (sym);
sym->ts.u.cl->backend_decl = length;
if (sym->attr.save || sym->ns->proc_name->attr.flavor == FL_MODULE)
TREE_STATIC (length) = 1;
if (sym->ns->proc_name->attr.flavor == FL_MODULE
&& (sym->attr.access != ACCESS_PRIVATE || sym->attr.public_used))
TREE_PUBLIC (length) = 1;
}
gcc_assert (sym->ts.u.cl->backend_decl != NULL_TREE);
@ -1402,17 +1412,6 @@ gfc_get_symbol_decl (gfc_symbol * sym)
if (TREE_CODE (length) != INTEGER_CST)
{
char name[GFC_MAX_MANGLED_SYMBOL_LEN + 2];
if (sym->module)
{
/* Also prefix the mangled name for symbols from modules. */
strcpy (&name[1], sym->name);
name[0] = '.';
strcpy (&name[1],
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (length)));
gfc_set_decl_assembler_name (decl, get_identifier (name));
}
gfc_finish_var_decl (length, sym);
gcc_assert (!sym->value);
}

View File

@ -7005,13 +7005,14 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
gfc_add_expr_to_block (&loop.post, tmp);
}
/* For a deferred character length function, the function call must
happen before the (re)allocation of the lhs, otherwise the character
length of the result is not known. */
def_clen_func = (((expr2->expr_type == EXPR_FUNCTION)
|| (expr2->expr_type == EXPR_COMPCALL)
|| (expr2->expr_type == EXPR_PPC))
&& expr2->ts.deferred);
/* When assigning a character function result to a deferred-length variable,
the function call must happen before the (re)allocation of the lhs -
otherwise the character length of the result is not known.
NOTE: This relies on having the exact dependence of the length type
parameter available to the caller; gfortran saves it in the .mod files. */
def_clen_func = (expr2->expr_type == EXPR_FUNCTION
|| expr2->expr_type == EXPR_COMPCALL
|| expr2->expr_type == EXPR_PPC);
if (gfc_option.flag_realloc_lhs
&& expr2->ts.type == BT_CHARACTER
&& (def_clen_func || expr2->expr_type == EXPR_OP)

View File

@ -1,3 +1,11 @@
2012-05-14 Tobias Burnus <burnus@net-b.de>
PR fortran/49110
PR fortran/51055
PR fortran/53329
* gfortran.dg/deferred_type_param_4.f90: New.
* gfortran.dg/deferred_type_param_6.f90: New.
2012-05-14 Bernd Schmidt <bernds@codesourcery.com>
* gcc.target/i386/retarg.c: New test.

View File

@ -0,0 +1,33 @@
! { dg-do run }
!
! PR fortran/51055
! PR fortran/49110
!
!
program test
implicit none
character(len=:), allocatable :: str
integer :: i
i = 5
str = f()
call printIt ()
i = 7
str = repeat('X', i)
call printIt ()
contains
function f()
character(len=i) :: f
f = '1234567890'
end function f
subroutine printIt
! print *, len(str)
! print '(3a)', '>',str,'<'
if (i == 5) then
if (str /= "12345" .or. len(str) /= 5) call abort ()
else if (i == 7) then
if (str /= "XXXXXXX" .or. len(str) /= 7) call abort ()
else
call abort ()
end if
end subroutine
end

View File

@ -0,0 +1,33 @@
! { dg-do run }
!
! PR fortran/51055
! PR fortran/49110
!
subroutine test()
implicit none
integer :: i = 5
character(len=:), allocatable :: s1
call sub(s1, i)
if (len(s1) /= 5) call abort()
if (s1 /= "ZZZZZ") call abort()
contains
subroutine sub(str,j)
character(len=:), allocatable :: str
integer :: j
str = REPEAT("Z",j)
if (len(str) /= 5) call abort()
if (str /= "ZZZZZ") call abort()
end subroutine sub
end subroutine test
program a
character(len=:),allocatable :: s
integer :: j=2
s = repeat ('x', j)
if (len(repeat(' ',j)) /= 2) call abort()
if (repeat('y',j) /= "yy") call abort()
if (len(s) /= 2) call abort()
if (s /= "xx") call abort()
call test()
end program a