summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>2007-10-02 08:03:07 +0000
committerpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>2007-10-02 08:03:07 +0000
commit87114d2e2a4622f66310057c1252c194f885d03d (patch)
treeff948ff9b958177f1fdfa3f78bf1080922b15f2c /gcc
parent2ddb8ed9cf028f9bd5cbcac595799a04960364b9 (diff)
downloadgcc-87114d2e2a4622f66310057c1252c194f885d03d.tar.gz
2007-10-02 Paul Thomas <pault@gcc.gnu.org>
PR fortran/33554 * trans-decl.c (init_intent_out_dt): New function. (gfc_trans_deferred_vars): Remove the code for default initialization of INTENT(OUT) derived types and put it in the new function. Call it earlier than before, so that array offsets and lower bounds are available. 2007-10-02 Paul Thomas <pault@gcc.gnu.org> PR fortran/33554 * gfortran.dg/intent_out_2.f90: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128950 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog9
-rw-r--r--gcc/fortran/trans-decl.c64
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/intent_out_2.f9080
4 files changed, 97 insertions, 61 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index f35b0dc9456..5af0989013d 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,5 +1,14 @@
2007-10-02 Paul Thomas <pault@gcc.gnu.org>
+ PR fortran/33554
+ * trans-decl.c (init_intent_out_dt): New function.
+ (gfc_trans_deferred_vars): Remove the code for default
+ initialization of INTENT(OUT) derived types and put it
+ in the new function. Call it earlier than before, so
+ that array offsets and lower bounds are available.
+
+2007-10-02 Paul Thomas <pault@gcc.gnu.org>
+
PR fortran/33550
* decl.c (get_proc_name): Return rc if rc is non-zero; ie. if
the name is a reference to an ambiguous symbol.
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index e27a04bd4c7..f04a4d1b904 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -2558,6 +2558,44 @@ gfc_trans_vla_type_sizes (gfc_symbol *sym, stmtblock_t *body)
}
+/* Initialize INTENT(OUT) derived type dummies. */
+static tree
+init_intent_out_dt (gfc_symbol * proc_sym, tree body)
+{
+ stmtblock_t fnblock;
+ gfc_formal_arglist *f;
+ gfc_expr *tmpe;
+ tree tmp;
+ tree present;
+
+ gfc_init_block (&fnblock);
+
+ for (f = proc_sym->formal; f; f = f->next)
+ {
+ if (f->sym && f->sym->attr.intent == INTENT_OUT
+ && f->sym->ts.type == BT_DERIVED
+ && !f->sym->ts.derived->attr.alloc_comp
+ && f->sym->value)
+ {
+ gcc_assert (!f->sym->attr.allocatable);
+ gfc_set_sym_referenced (f->sym);
+ tmpe = gfc_lval_expr_from_sym (f->sym);
+ tmp = gfc_trans_assignment (tmpe, f->sym->value, false);
+
+ present = gfc_conv_expr_present (f->sym);
+ tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present,
+ tmp, build_empty_stmt ());
+ gfc_add_expr_to_block (&fnblock, tmp);
+ gfc_free_expr (tmpe);
+ }
+ }
+
+ gfc_add_expr_to_block (&fnblock, body);
+ return gfc_finish_block (&fnblock);
+}
+
+
+
/* Generate function entry and exit code, and add it to the function body.
This includes:
Allocation and initialization of array variables.
@@ -2612,6 +2650,11 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, tree fnbody)
&& proc_sym->ts.type == BT_COMPLEX);
}
+ /* Initialize the INTENT(OUT) derived type dummy arguments. This
+ should be done here so that the offsets and lbounds of arrays
+ are available. */
+ fnbody = init_intent_out_dt (proc_sym, fnbody);
+
for (sym = proc_sym->tlink; sym != proc_sym; sym = sym->tlink)
{
bool sym_has_alloc_comp = (sym->ts.type == BT_DERIVED)
@@ -2710,27 +2753,6 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, tree fnbody)
if (TREE_CODE (f->sym->ts.cl->backend_decl) == PARM_DECL)
gfc_trans_vla_type_sizes (f->sym, &body);
}
-
- /* If an INTENT(OUT) dummy of derived type has a default
- initializer, it must be initialized here. */
- if (f->sym && f->sym->attr.intent == INTENT_OUT
- && f->sym->ts.type == BT_DERIVED
- && !f->sym->ts.derived->attr.alloc_comp
- && f->sym->value)
- {
- gfc_expr *tmpe;
- tree tmp, present;
- gcc_assert (!f->sym->attr.allocatable);
- gfc_set_sym_referenced (f->sym);
- tmpe = gfc_lval_expr_from_sym (f->sym);
- tmp = gfc_trans_assignment (tmpe, f->sym->value, false);
-
- present = gfc_conv_expr_present (f->sym);
- tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present,
- tmp, build_empty_stmt ());
- gfc_add_expr_to_block (&body, tmp);
- gfc_free_expr (tmpe);
- }
}
if (gfc_return_by_reference (proc_sym) && proc_sym->ts.type == BT_CHARACTER
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8bc1d28b99b..62187039a5d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2007-10-02 Paul Thomas <pault@gcc.gnu.org>
+ PR fortran/33554
+ * gfortran.dg/intent_out_2.f90: New test.
+
+2007-10-02 Paul Thomas <pault@gcc.gnu.org>
+
PR fortran/33550
* gfortran.dg/ambiguous_reference_1.f90: New test.
diff --git a/gcc/testsuite/gfortran.dg/intent_out_2.f90 b/gcc/testsuite/gfortran.dg/intent_out_2.f90
index 0fad1b8f3fe..4dc5191e9a2 100644
--- a/gcc/testsuite/gfortran.dg/intent_out_2.f90
+++ b/gcc/testsuite/gfortran.dg/intent_out_2.f90
@@ -1,47 +1,47 @@
-! { dg-do -run }
+! { dg-do run }
! Tests the fix for PR33554, in which the default initialization
! of temp, in construct_temp, caused a segfault because it was
! being done before the array offset and lower bound were
! available.
!
! Contributed by Harald Anlauf <anlauf@gmx.de>
-!
-module gfcbug72
- implicit none
-
- type t_datum
- character(len=8) :: mn = 'abcdefgh'
- end type t_datum
-
- type t_temp
- type(t_datum) :: p
- end type t_temp
-
-contains
-
- subroutine setup ()
- integer :: i
- type (t_temp), pointer :: temp(:) => NULL ()
-
- do i=1,2
- allocate (temp (2))
- call construct_temp (temp)
- if (any (temp % p% mn .ne. 'ijklmnop')) call abort ()
- deallocate (temp)
- end do
- end subroutine setup
- !--
- subroutine construct_temp (temp)
- type (t_temp), intent(out) :: temp (:)
- if (any (temp % p% mn .ne. 'abcdefgh')) call abort ()
- temp(:)% p% mn = 'ijklmnop'
- end subroutine construct_temp
-end module gfcbug72
-
-program test
- use gfcbug72
- implicit none
- call setup ()
-end program test
+!
+module gfcbug72
+ implicit none
+
+ type t_datum
+ character(len=8) :: mn = 'abcdefgh'
+ end type t_datum
+
+ type t_temp
+ type(t_datum) :: p
+ end type t_temp
+
+contains
+
+ subroutine setup ()
+ integer :: i
+ type (t_temp), pointer :: temp(:) => NULL ()
+
+ do i=1,2
+ allocate (temp (2))
+ call construct_temp (temp)
+ if (any (temp % p% mn .ne. 'ijklmnop')) call abort ()
+ deallocate (temp)
+ end do
+ end subroutine setup
+ !--
+ subroutine construct_temp (temp)
+ type (t_temp), intent(out) :: temp (:)
+ if (any (temp % p% mn .ne. 'abcdefgh')) call abort ()
+ temp(:)% p% mn = 'ijklmnop'
+ end subroutine construct_temp
+end module gfcbug72
+
+program test
+ use gfcbug72
+ implicit none
+ call setup ()
+end program test
! { dg-final { cleanup-modules "gfcbug72" } }
-
+