mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-22 15:39:57 +08:00
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:
parent
5bb53d1a1d
commit
6052c29931
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
33
gcc/testsuite/gfortran.dg/deferred_type_param_4.f90
Normal file
33
gcc/testsuite/gfortran.dg/deferred_type_param_4.f90
Normal 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
|
33
gcc/testsuite/gfortran.dg/deferred_type_param_6.f90
Normal file
33
gcc/testsuite/gfortran.dg/deferred_type_param_6.f90
Normal 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
|
Loading…
Reference in New Issue
Block a user