summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordomob <domob@138bc75d-0d04-0410-961f-82ee72b054a4>2010-09-26 19:25:52 +0000
committerdomob <domob@138bc75d-0d04-0410-961f-82ee72b054a4>2010-09-26 19:25:52 +0000
commit62aa667d6ec96cbf1b0f72c8774c5c8f227bbdee (patch)
tree1d9f1efb46f0580469c88e194c71c68ffeef9886
parent5ed38d93ab9471d6f59c56d62bccbba252b48e41 (diff)
downloadgcc-62aa667d6ec96cbf1b0f72c8774c5c8f227bbdee.tar.gz
2010-09-26 Daniel Kraft <d@domob.eu>
PR fortran/45783 PR fortran/45795 * resolve.c (resolve_select_type): Clarify code. (resolve_assoc_var): Only set typespec if it is currently unknown. 2010-09-26 Daniel Kraft <d@domob.eu> PR fortran/45783 PR fortran/45795 * gfortran.dg/select_type_18.f03: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164638 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/fortran/ChangeLog7
-rw-r--r--gcc/fortran/resolve.c10
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gfortran.dg/select_type_18.f0390
4 files changed, 110 insertions, 3 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 33afd97171d..f6655005cab 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,10 @@
+2010-09-26 Daniel Kraft <d@domob.eu>
+
+ PR fortran/45783
+ PR fortran/45795
+ * resolve.c (resolve_select_type): Clarify code.
+ (resolve_assoc_var): Only set typespec if it is currently unknown.
+
2010-09-26 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/45793
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 0dce3f86b18..6b5bbfa742a 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -7570,7 +7570,11 @@ resolve_assoc_var (gfc_symbol* sym, bool resolve_target)
sym->attr.target = (tsym->attr.target || tsym->attr.pointer);
}
- sym->ts = target->ts;
+ /* Get type if this was not already set. Note that it can be
+ some other type than the target in case this is a SELECT TYPE
+ selector! So we must not update when the type is already there. */
+ if (sym->ts.type == BT_UNKNOWN)
+ sym->ts = target->ts;
gcc_assert (sym->ts.type != BT_UNKNOWN);
/* See if this is a valid association-to-variable. */
@@ -7673,8 +7677,8 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
error++;
continue;
}
- else
- default_case = body;
+
+ default_case = body;
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d9853727d4f..536003f3718 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2010-09-26 Daniel Kraft <d@domob.eu>
+
+ PR fortran/45783
+ PR fortran/45795
+ * gfortran.dg/select_type_18.f03: New test.
+
2010-09-25 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/return2.ad[sb]: New test.
diff --git a/gcc/testsuite/gfortran.dg/select_type_18.f03 b/gcc/testsuite/gfortran.dg/select_type_18.f03
new file mode 100644
index 00000000000..e4bacd377e7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/select_type_18.f03
@@ -0,0 +1,90 @@
+! { dg-do compile }
+
+! PR fortran/45783
+! PR fortran/45795
+! This used to fail because of incorrect compile-time typespec on the
+! SELECT TYPE selector.
+
+! This is the test-case from PR 45795.
+! Contributed by Salvatore Filippone, sfilippone@uniroma2.it.
+
+module base_mod
+
+ type :: base
+ integer :: m, n
+ end type base
+
+end module base_mod
+
+module s_base_mod
+
+ use base_mod
+
+ type, extends(base) :: s_base
+ contains
+ procedure, pass(a) :: cp_to_foo => s_base_cp_to_foo
+
+ end type s_base
+
+
+ type, extends(s_base) :: s_foo
+
+ integer :: nnz
+ integer, allocatable :: ia(:), ja(:)
+ real, allocatable :: val(:)
+
+ contains
+
+ procedure, pass(a) :: cp_to_foo => s_cp_foo_to_foo
+
+ end type s_foo
+
+
+ interface
+ subroutine s_base_cp_to_foo(a,b,info)
+ import :: s_base, s_foo
+ class(s_base), intent(in) :: a
+ class(s_foo), intent(inout) :: b
+ integer, intent(out) :: info
+ end subroutine s_base_cp_to_foo
+ end interface
+
+ interface
+ subroutine s_cp_foo_to_foo(a,b,info)
+ import :: s_foo
+ class(s_foo), intent(in) :: a
+ class(s_foo), intent(inout) :: b
+ integer, intent(out) :: info
+ end subroutine s_cp_foo_to_foo
+ end interface
+
+end module s_base_mod
+
+
+subroutine trans2(a,b)
+ use s_base_mod
+ implicit none
+
+ class(s_base), intent(out) :: a
+ class(base), intent(in) :: b
+
+ type(s_foo) :: tmp
+ integer err_act, info
+
+
+ info = 0
+ select type(b)
+ class is (s_base)
+ call b%cp_to_foo(tmp,info)
+ class default
+ info = -1
+ write(*,*) 'Invalid dynamic type'
+ end select
+
+ if (info /= 0) write(*,*) 'Error code ',info
+
+ return
+
+end subroutine trans2
+
+! { dg-final { cleanup-modules "base_mod s_base_mod" } }