Hi all, this patch fixes an ICE on invalid code involving class component declarations. The ICE is avoided by moving forward the error check from resolution to parsing stage. For class components this is possible, because the attributes have to be specified in the same line (in contrast to class variables, where the attributes can be specified in multiple statements, so that checking can only be done during resolution).
Note that this fixes only the original example, but not comment 2 (which is a different issue). Regtests cleanly on x86_64-linux-gnu. Ok for trunk? Cheers, Janus 2016-11-12 Janus Weil <ja...@gcc.gnu.org> PR fortran/66366 * resolve.c (resolve_component): Move check for C437 to ... * decl.c (build_struct): ... here. Fix indentation. 2016-11-12 Janus Weil <ja...@gcc.gnu.org> PR fortran/66366 * gfortran.dg/class_60.f90: New test.
Index: gcc/fortran/decl.c =================================================================== --- gcc/fortran/decl.c (Revision 242339) +++ gcc/fortran/decl.c (Arbeitskopie) @@ -1866,10 +1866,19 @@ build_struct (const char *name, gfc_charlen *cl, g } else if (current_attr.allocatable == 0) { - gfc_error ("Component at %C must have the POINTER attribute"); + gfc_error ("Component at %C must have the POINTER attribute"); + return false; + } + } + + /* F03:C437. */ + if (current_ts.type == BT_CLASS + && !(current_attr.pointer || current_attr.allocatable)) + { + gfc_error ("Component %qs with CLASS at %C must be allocatable " + "or pointer", name); return false; } - } if (gfc_current_block ()->attr.pointer && (*as)->rank != 0) { Index: gcc/fortran/resolve.c =================================================================== --- gcc/fortran/resolve.c (Revision 242339) +++ gcc/fortran/resolve.c (Arbeitskopie) @@ -13587,19 +13587,6 @@ resolve_component (gfc_component *c, gfc_symbol *s return false; } - /* C437. */ - if (c->ts.type == BT_CLASS && c->attr.flavor != FL_PROCEDURE - && (!c->attr.class_ok - || !(CLASS_DATA (c)->attr.class_pointer - || CLASS_DATA (c)->attr.allocatable))) - { - gfc_error ("Component %qs with CLASS at %L must be allocatable " - "or pointer", c->name, &c->loc); - /* Prevent a recurrence of the error. */ - c->ts.type = BT_UNKNOWN; - return false; - } - /* If an allocatable component derived type is of the same type as the enclosing derived type, we need a vtable generating so that the __deallocate procedure is created. */ Index: gcc/testsuite/gfortran.dg/class_57.f90 =================================================================== --- gcc/testsuite/gfortran.dg/class_57.f90 (Revision 242339) +++ gcc/testsuite/gfortran.dg/class_57.f90 (Arbeitskopie) @@ -18,7 +18,7 @@ contains function pc(pd) type(p) :: pc class(d), intent(in), target :: pd - pc%cc => pd ! { dg-error "Non-POINTER in pointer association context" } + pc%cc => pd ! { dg-error "is not a member of" } end function end
! { dg-do compile } ! ! PR 66366: [OOP] ICE on invalid with non-allocatable CLASS variable ! ! Contributed by Andrew Benson <abenso...@gmail.com> module bug type :: t1d contains procedure :: interpolate => interp end type t1d type :: tff class(t1d) :: transfer ! { dg-error "must be allocatable or pointer" } end type tff contains double precision function interp(self) implicit none class(t1d), intent(inout) :: self return end function interp double precision function fvb(self) implicit none class(tff), intent(inout) :: self fvb=self%transfer%interpolate() ! { dg-error "is not a member of" } return end function fvb end module bug