diff options
author | Daniel Kraft <d@domob.eu> | 2009-12-08 12:39:20 +0100 |
---|---|---|
committer | Daniel Kraft <domob@gcc.gnu.org> | 2009-12-08 12:39:20 +0100 |
commit | 41a394bbf8d47ae58aad6b9068cd6f0f27cc2f2f (patch) | |
tree | 97e379b084f6fe3298f9879b4b2d00a044c7693f /gcc | |
parent | 72d099cb27a5fedea22e2d69ce8d03e71120fddc (diff) | |
download | gcc-41a394bbf8d47ae58aad6b9068cd6f0f27cc2f2f.zip gcc-41a394bbf8d47ae58aad6b9068cd6f0f27cc2f2f.tar.gz gcc-41a394bbf8d47ae58aad6b9068cd6f0f27cc2f2f.tar.bz2 |
re PR fortran/41177 (Wrong base-object checks for type-bound procedures)
2008-12-08 Daniel Kraft <d@domob.eu>
PR fortran/41177
* gfortran.dg/typebound_proc_4.f03: Remove check for wrong error.
* gfortran.dg/typebound_proc_13.f03: New test.
2008-12-08 Daniel Kraft <d@domob.eu>
PR fortran/41177
* gfortran.h (struct symbol_attribute): New flag `class_pointer'.
* symbol.c (gfc_build_class_symbol): Set the new flag.
* resolve.c (update_compcall_arglist): Remove wrong check for
non-scalar base-object.
(check_typebound_baseobject): Add the correct version here as well
as some 'not implemented' message check in the old case.
(resolve_typebound_procedure): Check that the passed-object dummy
argument is scalar, non-pointer and non-allocatable as it should be.
From-SVN: r155086
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fortran/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 5 | ||||
-rw-r--r-- | gcc/fortran/resolve.c | 49 | ||||
-rw-r--r-- | gcc/fortran/symbol.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/typebound_call_4.f03 | 4 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/typebound_proc_13.f03 | 48 |
7 files changed, 113 insertions, 12 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 24db229..2eaf6d0 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,15 @@ +2008-12-08 Daniel Kraft <d@domob.eu> + + PR fortran/41177 + * gfortran.h (struct symbol_attribute): New flag `class_pointer'. + * symbol.c (gfc_build_class_symbol): Set the new flag. + * resolve.c (update_compcall_arglist): Remove wrong check for + non-scalar base-object. + (check_typebound_baseobject): Add the correct version here as well + as some 'not implemented' message check in the old case. + (resolve_typebound_procedure): Check that the passed-object dummy + argument is scalar, non-pointer and non-allocatable as it should be. + 2009-12-08 Tobias Burnus <burnus@net-b.de> PR fortran/40961 diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 3a13cfe..340e014 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -654,6 +654,11 @@ typedef struct dummy:1, result:1, assign:1, threadprivate:1, not_always_present:1, implied_index:1, subref_array_pointer:1, proc_pointer:1; + /* For CLASS containers, the pointer attribute is sometimes set internally + even though it was not directly specified. In this case, keep the + "real" (original) value here. */ + unsigned class_pointer:1; + ENUM_BITFIELD (save_state) save:2; unsigned data:1, /* Symbol is named in a DATA statement. */ diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 6f6cb78..8d2be53 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -4781,12 +4781,6 @@ update_compcall_arglist (gfc_expr* e) if (!po) return FAILURE; - if (po->rank > 0) - { - gfc_error ("Passed-object at %L must be scalar", &e->where); - return FAILURE; - } - if (tbp->nopass || e->value.compcall.ignore_pass) { gfc_free_expr (po); @@ -4889,6 +4883,22 @@ check_typebound_baseobject (gfc_expr* e) return FAILURE; } + /* If the procedure called is NOPASS, the base object must be scalar. */ + if (e->value.compcall.tbp->nopass && base->rank > 0) + { + gfc_error ("Base object for NOPASS type-bound procedure call at %L must" + " be scalar", &e->where); + return FAILURE; + } + + /* FIXME: Remove once PR 41177 (this problem) is fixed completely. */ + if (base->rank > 0) + { + gfc_error ("Non-scalar base object at %L currently not implemented", + &e->where); + return FAILURE; + } + return SUCCESS; } @@ -10038,8 +10048,11 @@ resolve_typebound_procedure (gfc_symtree* stree) me_arg = proc->formal->sym; } - /* Now check that the argument-type matches. */ + /* Now check that the argument-type matches and the passed-object + dummy argument is generally fine. */ + gcc_assert (me_arg); + if (me_arg->ts.type != BT_CLASS) { gfc_error ("Non-polymorphic passed-object dummy argument of '%s'" @@ -10055,7 +10068,27 @@ resolve_typebound_procedure (gfc_symtree* stree) me_arg->name, &where, resolve_bindings_derived->name); goto error; } - + + gcc_assert (me_arg->ts.type == BT_CLASS); + if (me_arg->ts.u.derived->components->as + && me_arg->ts.u.derived->components->as->rank > 0) + { + gfc_error ("Passed-object dummy argument of '%s' at %L must be" + " scalar", proc->name, &where); + goto error; + } + if (me_arg->ts.u.derived->components->attr.allocatable) + { + gfc_error ("Passed-object dummy argument of '%s' at %L must not" + " be ALLOCATABLE", proc->name, &where); + goto error; + } + if (me_arg->ts.u.derived->components->attr.class_pointer) + { + gfc_error ("Passed-object dummy argument of '%s' at %L must not" + " be POINTER", proc->name, &where); + goto error; + } } /* If we are extending some type, check that we don't override a procedure diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c index 6dd0a8a..08477c4 100644 --- a/gcc/fortran/symbol.c +++ b/gcc/fortran/symbol.c @@ -4681,6 +4681,7 @@ gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr, c->ts.type = BT_DERIVED; c->attr.access = ACCESS_PRIVATE; c->ts.u.derived = ts->u.derived; + c->attr.class_pointer = attr->pointer; c->attr.pointer = attr->pointer || attr->dummy; c->attr.allocatable = attr->allocatable; c->attr.dimension = attr->dimension; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3dce570..cafd467 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2008-12-08 Daniel Kraft <d@domob.eu> + + PR fortran/41177 + * gfortran.dg/typebound_proc_4.f03: Remove check for wrong error. + * gfortran.dg/typebound_proc_13.f03: New test. + 2009-12-08 Olga Golovanevsky <olga@il.ibm.com> Jakub Jelinek <jakub@redhat.com> diff --git a/gcc/testsuite/gfortran.dg/typebound_call_4.f03 b/gcc/testsuite/gfortran.dg/typebound_call_4.f03 index cdbbea9..6cb5e69 100644 --- a/gcc/testsuite/gfortran.dg/typebound_call_4.f03 +++ b/gcc/testsuite/gfortran.dg/typebound_call_4.f03 @@ -37,10 +37,6 @@ CONTAINS CALL arr(1)%myobj%proc () WRITE (*,*) arr(2)%myobj%func () - ! Base-object must be scalar. - CALL arr(:)%myobj%proc () ! { dg-error "scalar" } - WRITE (*,*) arr(:)%myobj%func () ! { dg-error "scalar" } - ! Can't CALL a function or take the result of a SUBROUTINE. CALL arr(1)%myobj%func () ! { dg-error "SUBROUTINE" } WRITE (*,*) arr(2)%myobj%proc () ! { dg-error "FUNCTION" } diff --git a/gcc/testsuite/gfortran.dg/typebound_proc_13.f03 b/gcc/testsuite/gfortran.dg/typebound_proc_13.f03 new file mode 100644 index 0000000..3f978f2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/typebound_proc_13.f03 @@ -0,0 +1,48 @@ +! { dg-do compile } + +! PR fortran/41177 +! Test for additional errors with type-bound procedure bindings. +! Namely that non-scalar base objects are rejected for TBP calls which are +! NOPASS, and that passed-object dummy arguments must be scalar, non-POINTER +! and non-ALLOCATABLE. + +MODULE m + IMPLICIT NONE + + TYPE t + CONTAINS + PROCEDURE, NOPASS :: myproc + END TYPE t + + TYPE t2 + CONTAINS + PROCEDURE, PASS :: nonscalar ! { dg-error "must be scalar" } + PROCEDURE, PASS :: is_pointer ! { dg-error "must not be POINTER" } + PROCEDURE, PASS :: is_allocatable ! { dg-error "must not be ALLOCATABLE" } + END TYPE t2 + +CONTAINS + + SUBROUTINE myproc () + END SUBROUTINE myproc + + SUBROUTINE nonscalar (me) + CLASS(t2), INTENT(IN) :: me(:) + END SUBROUTINE nonscalar + + SUBROUTINE is_pointer (me) + CLASS(t2), POINTER, INTENT(IN) :: me + END SUBROUTINE is_pointer + + SUBROUTINE is_allocatable (me) + CLASS(t2), ALLOCATABLE, INTENT(IN) :: me + END SUBROUTINE is_allocatable + + SUBROUTINE test () + TYPE(t) :: arr(2) + CALL arr%myproc () ! { dg-error "must be scalar" } + END SUBROUTINE test + +END MODULE m + +! { dg-final { cleanup-modules "m" } } |