Commit 5b130807 by Tobias Burnus Committed by Tobias Burnus

re PR fortran/41872 (wrong-code: Issues with allocatable scalars)

2009-01-04  Tobias Burnus  <burnus@net-b.de>

        PR fortran/41872
        * trans-expr.c (gfc_conv_procedure_call): Add indirect ref
        for functions returning allocatable scalars.
        * trans-stmt.c (gfc_trans_allocate): Emmit error when
        reallocating an allocatable scalar.
        * trans.c (gfc_allocate_with_status): Fix pseudocode syntax
        in comment.
        * trans-decl.c (gfc_trans_deferred_vars): Nullify local
        allocatable scalars.
        (gfc_generate_function_code): Nullify result variable for
        allocatable scalars.
        
        PR fortran/40849
        * module.c (gfc_use_module): Fix warning string to allow
        for translation.

        PR fortran/42517
        * invoke.texi (-fcheck=recursion): Mention that the checking
        is also disabled for -frecursive.
        * trans-decl.c (gfc_generate_function_code): Disable
        -fcheck=recursion when -frecursive is used.

        * intrinsic.texi (iso_c_binding): Improve wording.

2009-01-04  Tobias Burnus  <burnus@net-b.de>

        PR fortran/41872
        * gfortran.dg/allocatable_scalar_5.f90: New test.
        * gfortran.dg/allocatable_scalar_6.f90: New test.

From-SVN: r155606
parent f4262155
2010-01-04 Tobias Burnus <burnus@net-b.de>
PR fortran/41872
* trans-expr.c (gfc_conv_procedure_call): Add indirect ref
for functions returning allocatable scalars.
* trans-stmt.c (gfc_trans_allocate): Emmit error when
reallocating an allocatable scalar.
* trans.c (gfc_allocate_with_status): Fix pseudocode syntax
in comment.
* trans-decl.c (gfc_trans_deferred_vars): Nullify local
allocatable scalars.
(gfc_generate_function_code): Nullify result variable for
allocatable scalars.
PR fortran/40849
* module.c (gfc_use_module): Fix warning string to allow
for translation.
PR fortran/42517
* invoke.texi (-fcheck=recursion): Mention that the checking
is also disabled for -frecursive.
* trans-decl.c (gfc_generate_function_code): Disable
-fcheck=recursion when -frecursive is used.
* intrinsic.texi (iso_c_binding): Improve wording.
Copyright (C) 2010 Free Software Foundation, Inc. Copyright (C) 2010 Free Software Foundation, Inc.
......
...@@ -11350,8 +11350,8 @@ C_INT_LEAST128_T, C_INT_FAST128_T}. ...@@ -11350,8 +11350,8 @@ C_INT_LEAST128_T, C_INT_FAST128_T}.
@item @code{CHARACTER}@tab @code{C_CHAR} @tab @code{char} @item @code{CHARACTER}@tab @code{C_CHAR} @tab @code{char}
@end multitable @end multitable
Additionally, the following @code{(CHARACTER(KIND=C_CHAR))} are Additionally, the following parameters of type @code{CHARACTER(KIND=C_CHAR)}
defined. are defined.
@multitable @columnfractions .20 .45 .15 @multitable @columnfractions .20 .45 .15
@item Name @tab C definition @tab Value @item Name @tab C definition @tab Value
......
...@@ -1258,7 +1258,7 @@ Enable generation of run-time checks for pointers and allocatables. ...@@ -1258,7 +1258,7 @@ Enable generation of run-time checks for pointers and allocatables.
Enable generation of run-time checks for recursively called subroutines and Enable generation of run-time checks for recursively called subroutines and
functions which are not marked as recursive. See also @option{-frecursive}. functions which are not marked as recursive. See also @option{-frecursive}.
Note: This check does not work for OpenMP programs and is disabled if used Note: This check does not work for OpenMP programs and is disabled if used
together with @option{-fopenmp}. together with @option{-frecursive} and @option{-fopenmp}.
@end table @end table
......
...@@ -5491,9 +5491,9 @@ gfc_use_module (void) ...@@ -5491,9 +5491,9 @@ gfc_use_module (void)
if (strcmp (atom_string, MOD_VERSION)) if (strcmp (atom_string, MOD_VERSION))
{ {
gfc_fatal_error ("Wrong module version '%s' (expected '" gfc_fatal_error ("Wrong module version '%s' (expected '%s') "
MOD_VERSION "') for file '%s' opened" "for file '%s' opened at %C", atom_string,
" at %C", atom_string, filename); MOD_VERSION, filename);
} }
} }
......
...@@ -3188,7 +3188,7 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, tree fnbody) ...@@ -3188,7 +3188,7 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, tree fnbody)
|| (sym->ts.type == BT_CLASS || (sym->ts.type == BT_CLASS
&& sym->ts.u.derived->components->attr.allocatable)) && sym->ts.u.derived->components->attr.allocatable))
{ {
/* Automatic deallocatation of allocatable scalars. */ /* Nullify and automatic deallocatation of allocatable scalars. */
tree tmp; tree tmp;
gfc_expr *e; gfc_expr *e;
gfc_se se; gfc_se se;
...@@ -3203,10 +3203,13 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, tree fnbody) ...@@ -3203,10 +3203,13 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, tree fnbody)
gfc_conv_expr (&se, e); gfc_conv_expr (&se, e);
gfc_free_expr (e); gfc_free_expr (e);
/* Nullify when entering the scope. */
gfc_start_block (&block); gfc_start_block (&block);
gfc_add_modify (&block, se.expr, fold_convert (TREE_TYPE (se.expr),
null_pointer_node));
gfc_add_expr_to_block (&block, fnbody); gfc_add_expr_to_block (&block, fnbody);
/* Note: Nullifying is not needed. */ /* Deallocate when leaving the scope. Nullifying is not needed. */
tmp = gfc_deallocate_with_status (se.expr, NULL_TREE, true, NULL); tmp = gfc_deallocate_with_status (se.expr, NULL_TREE, true, NULL);
gfc_add_expr_to_block (&block, tmp); gfc_add_expr_to_block (&block, tmp);
fnbody = gfc_finish_block (&block); fnbody = gfc_finish_block (&block);
...@@ -4319,7 +4322,7 @@ gfc_generate_function_code (gfc_namespace * ns) ...@@ -4319,7 +4322,7 @@ gfc_generate_function_code (gfc_namespace * ns)
|| (sym->attr.entry_master || (sym->attr.entry_master
&& sym->ns->entries->sym->attr.recursive); && sym->ns->entries->sym->attr.recursive);
if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION) && !is_recursive if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION) && !is_recursive
&& !gfc_option.flag_openmp) && !gfc_option.flag_recursive)
{ {
char * msg; char * msg;
...@@ -4384,13 +4387,18 @@ gfc_generate_function_code (gfc_namespace * ns) ...@@ -4384,13 +4387,18 @@ gfc_generate_function_code (gfc_namespace * ns)
result = sym->result->backend_decl; result = sym->result->backend_decl;
if (result != NULL_TREE && sym->attr.function if (result != NULL_TREE && sym->attr.function
&& sym->ts.type == BT_DERIVED && !sym->attr.pointer)
&& sym->ts.u.derived->attr.alloc_comp
&& !sym->attr.pointer)
{ {
rank = sym->as ? sym->as->rank : 0; if (sym->ts.type == BT_DERIVED
tmp2 = gfc_nullify_alloc_comp (sym->ts.u.derived, result, rank); && sym->ts.u.derived->attr.alloc_comp)
gfc_add_expr_to_block (&block, tmp2); {
rank = sym->as ? sym->as->rank : 0;
tmp2 = gfc_nullify_alloc_comp (sym->ts.u.derived, result, rank);
gfc_add_expr_to_block (&block, tmp2);
}
else if (sym->attr.allocatable && sym->attr.dimension == 0)
gfc_add_modify (&block, result, fold_convert (TREE_TYPE (result),
null_pointer_node));
} }
gfc_add_expr_to_block (&block, tmp); gfc_add_expr_to_block (&block, tmp);
......
...@@ -3413,7 +3413,8 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, ...@@ -3413,7 +3413,8 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
something like something like
x = f() x = f()
where f is pointer valued, we have to dereference the result. */ where f is pointer valued, we have to dereference the result. */
if (!se->want_pointer && !byref && sym->attr.pointer if (!se->want_pointer && !byref
&& (sym->attr.pointer || sym->attr.allocatable)
&& !gfc_is_proc_ptr_comp (expr, NULL)) && !gfc_is_proc_ptr_comp (expr, NULL))
se->expr = build_fold_indirect_ref_loc (input_location, se->expr = build_fold_indirect_ref_loc (input_location,
se->expr); se->expr);
......
...@@ -4059,7 +4059,32 @@ gfc_trans_allocate (gfc_code * code) ...@@ -4059,7 +4059,32 @@ gfc_trans_allocate (gfc_code * code)
if (expr->ts.type == BT_CHARACTER && memsz == NULL_TREE) if (expr->ts.type == BT_CHARACTER && memsz == NULL_TREE)
memsz = se.string_length; memsz = se.string_length;
tmp = gfc_allocate_with_status (&se.pre, memsz, pstat); /* Allocate - for non-pointers with re-alloc checking. */
{
gfc_ref *ref;
bool allocatable;
ref = expr->ref;
/* Find the last reference in the chain. */
while (ref && ref->next != NULL)
{
gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT);
ref = ref->next;
}
if (!ref)
allocatable = expr->symtree->n.sym->attr.allocatable;
else
allocatable = ref->u.c.component->attr.allocatable;
if (allocatable)
tmp = gfc_allocate_array_with_status (&se.pre, se.expr, memsz,
pstat, expr);
else
tmp = gfc_allocate_with_status (&se.pre, memsz, pstat);
}
tmp = fold_build2 (MODIFY_EXPR, void_type_node, se.expr, tmp = fold_build2 (MODIFY_EXPR, void_type_node, se.expr,
fold_convert (TREE_TYPE (se.expr), tmp)); fold_convert (TREE_TYPE (se.expr), tmp));
gfc_add_expr_to_block (&se.pre, tmp); gfc_add_expr_to_block (&se.pre, tmp);
......
...@@ -711,6 +711,7 @@ gfc_allocate_with_status (stmtblock_t * block, tree size, tree status) ...@@ -711,6 +711,7 @@ gfc_allocate_with_status (stmtblock_t * block, tree size, tree status)
} }
else else
runtime_error ("Attempting to allocate already allocated array"); runtime_error ("Attempting to allocate already allocated array");
}
} }
expr must be set to the original expression being allocated for its locus expr must be set to the original expression being allocated for its locus
......
2009-01-04 Tobias Burnus <burnus@net-b.de>
PR fortran/41872
* gfortran.dg/allocatable_scalar_5.f90: New test.
* gfortran.dg/allocatable_scalar_6.f90: New test.
2010-01-03 Richard Guenther <rguenther@suse.de> 2010-01-03 Richard Guenther <rguenther@suse.de>
PR testsuite/42583 PR testsuite/42583
......
! { dg-do run }
! { dg-options "-Wall -pedantic" }
!
! PR fortran/41872
!
! More tests for allocatable scalars
!
program test
implicit none
integer, allocatable :: a
integer :: b
if (allocated (a)) call abort ()
if (allocated (func (.false.))) call abort ()
if (.not.allocated (func (.true.))) call abort ()
b = 7
b = func(.true.)
if (b /= 5332) call abort ()
b = 7
b = func(.true.) + 1
if (b /= 5333) call abort ()
call intout (a, .false.)
if (allocated (a)) call abort ()
call intout (a, .true.)
if (.not.allocated (a)) call abort ()
if (a /= 764) call abort ()
call intout2 (a)
if (allocated (a)) call abort ()
if (allocated (func2 ())) call abort ()
contains
function func (alloc)
integer, allocatable :: func
logical :: alloc
if (allocated (func)) call abort ()
if (alloc) then
allocate(func)
func = 5332
end if
end function func
function func2 ()
integer, allocatable :: func2
end function func2
subroutine intout (dum, alloc)
implicit none
integer, allocatable,intent(out) :: dum
logical :: alloc
if (allocated (dum)) call abort()
if (alloc) then
allocate (dum)
dum = 764
end if
end subroutine intout
subroutine intout2 (dum) ! { dg-warning "declared INTENT.OUT. but was not set" }
integer, allocatable,intent(out) :: dum
end subroutine intout2
end program test
! { dg-do run }
! { dg-options "-Wall -pedantic" }
!
! PR fortran/41872
!
! (De)allocate tests
!
program test
implicit none
integer, allocatable :: a, b, c
integer :: stat
stat=99
allocate(a, stat=stat)
if (stat /= 0) call abort ()
allocate(a, stat=stat)
if (stat == 0) call abort ()
allocate (b)
deallocate (b, stat=stat)
if (stat /= 0) call abort ()
deallocate (b, stat=stat)
if (stat == 0) call abort ()
deallocate (c, stat=stat)
if (stat == 0) call abort ()
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