From 5ac13b8e0c688dcf1251aee3f90eddfc1e5ba43f Mon Sep 17 00:00:00 2001 From: Janus Weil Date: Wed, 27 Oct 2010 23:41:52 +0200 Subject: re PR fortran/46161 ([OOP] Invalid: Passing non-polymorphic to allocatable polymorphic dummy) 2010-10-27 Janus Weil PR fortran/46161 * interface.c (compare_allocatable): Handle polymorphic allocatables. (compare_parameter): Add two error messages for polymorphic dummies. 2010-10-27 Janus Weil PR fortran/46161 * gfortran.dg/class_dummy_3.f03: New. From-SVN: r166018 --- gcc/fortran/ChangeLog | 6 ++++++ gcc/fortran/interface.c | 25 +++++++++++++++++++++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/class_dummy_3.f03 | 30 +++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gfortran.dg/class_dummy_3.f03 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index c4c3608..f64d530 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2010-10-27 Janus Weil + + PR fortran/46161 + * interface.c (compare_allocatable): Handle polymorphic allocatables. + (compare_parameter): Add two error messages for polymorphic dummies. + 2010-10-26 Janus Weil PR fortran/42647 diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index 6ae36c2..16b941c 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -1375,7 +1375,8 @@ compare_allocatable (gfc_symbol *formal, gfc_expr *actual) { symbol_attribute attr; - if (formal->attr.allocatable) + if (formal->attr.allocatable + || (formal->ts.type == BT_CLASS && CLASS_DATA (formal)->attr.allocatable)) { attr = gfc_expr_attr (actual); if (!attr.allocatable) @@ -1519,6 +1520,28 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual, gfc_typename (&formal->ts)); return 0; } + + /* F2003, 12.5.2.5. */ + if (formal->ts.type == BT_CLASS + && (CLASS_DATA (formal)->attr.class_pointer + || CLASS_DATA (formal)->attr.allocatable)) + { + if (actual->ts.type != BT_CLASS) + { + if (where) + gfc_error ("Actual argument to '%s' at %L must be polymorphic", + formal->name, &actual->where); + return 0; + } + if (CLASS_DATA (actual)->ts.u.derived + != CLASS_DATA (formal)->ts.u.derived) + { + if (where) + gfc_error ("Actual argument to '%s' at %L must have the same " + "declared type", formal->name, &actual->where); + return 0; + } + } if (formal->attr.codimension) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d7e5e8d..a749c49 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-10-27 Janus Weil + + PR fortran/46161 + * gfortran.dg/class_dummy_3.f03: New. + 2010-10-27 H.J. Lu * gcc.target/i386/avx-vzeroupper-1.c: Add -mtune=generic. diff --git a/gcc/testsuite/gfortran.dg/class_dummy_3.f03 b/gcc/testsuite/gfortran.dg/class_dummy_3.f03 new file mode 100644 index 0000000..6b12eb8 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/class_dummy_3.f03 @@ -0,0 +1,30 @@ +! { dg-do compile } +! +! PR 46161: [OOP] Invalid: Passing non-polymorphic to allocatable polymorphic dummy +! +! Contributed by Janus Weil + + implicit none + + type :: base + end type + + type, extends(base) :: ext + end type + + type(base), allocatable :: a + class(base), pointer :: b + class(ext), allocatable :: c + + call test(a) ! { dg-error "must be polymorphic" } + call test(b) ! { dg-error "must be ALLOCATABLE" } + call test(c) ! { dg-error "must have the same declared type" } + +contains + + subroutine test(arg) + implicit none + class(base), allocatable :: arg + end subroutine + +end -- cgit v1.1