This one was exceedingly difficult to diagnose.  The workings of
array.c are opaque to say the least of it!  However, the fix is
relatively clear.  The testcase in the PR failed because the argument
of ANY is not a gfc_constant_ac.  However, iterating through the
constructor and testing the expressions for constantness yields the
correct result.

Bootstraps and regtests on FC9/x86_64 - OK for trunk?

Cheers

Paul and Jerry

2011-03-06  Paul Thomas  <pa...@gcc.gnu.org>
            Jerry DeLisle  <jvdeli...@gcc.gnu.org>

        PR fortran/47850
        * expr.c (gfc_is_constant_expr): Only use gfc_constant_ac if
        the expression has an iterator.  Otherwise, iterate through the
        array, checking for constant expressions for each element.

2011-03-06  Paul Thomas  <pa...@gcc.gnu.org>
            Jerry DeLisle  <jvdeli...@gcc.gnu.org>

        PR fortran/47850
        * gfortran.dg/array_constructor_37.f90 : New test.
Index: gcc/fortran/expr.c
===================================================================
*** gcc/fortran/expr.c	(revision 170715)
--- gcc/fortran/expr.c	(working copy)
*************** gfc_is_constant_expr (gfc_expr *e)
*** 937,952 ****
        return e->ref == NULL || (gfc_is_constant_expr (e->ref->u.ss.start)
  				&& gfc_is_constant_expr (e->ref->u.ss.end));
  
      case EXPR_STRUCTURE:
!       for (c = gfc_constructor_first (e->value.constructor);
! 	   c; c = gfc_constructor_next (c))
  	if (!gfc_is_constant_expr (c->expr))
  	  return 0;
  
        return 1;
  
-     case EXPR_ARRAY:
-       return gfc_constant_ac (e);
  
      default:
        gfc_internal_error ("gfc_is_constant_expr(): Unknown expression type");
--- 937,954 ----
        return e->ref == NULL || (gfc_is_constant_expr (e->ref->u.ss.start)
  				&& gfc_is_constant_expr (e->ref->u.ss.end));
  
+     case EXPR_ARRAY:
      case EXPR_STRUCTURE:
!       c = gfc_constructor_first (e->value.constructor);
!       if ((e->expr_type == EXPR_ARRAY) && c && c->iterator)
!         return gfc_constant_ac (e);
! 
!       for (; c; c = gfc_constructor_next (c))
  	if (!gfc_is_constant_expr (c->expr))
  	  return 0;
  
        return 1;
  
  
      default:
        gfc_internal_error ("gfc_is_constant_expr(): Unknown expression type");
Index: gcc/testsuite/gfortran.dg/array_constructor_37.f90
===================================================================
*** gcc/testsuite/gfortran.dg/array_constructor_37.f90	(revision 0)
--- gcc/testsuite/gfortran.dg/array_constructor_37.f90	(revision 0)
***************
*** 0 ****
--- 1,32 ----
+ ! { dg-do compile }
+ ! Check the fix for PR47850, in which the argument of ANY, below, was not
+ ! simplified, thereby causing an ICE.
+ !
+ ! Contributed by Tobias Burnus  <bur...@gcc.gnu.org> but based on James van Buskirk's program in
+ ! http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/625faf82578e9af8
+ !
+ !
+ program Cindex
+    implicit none
+    integer,parameter :: SENSOR_CHANNEL(8) = &
+       [10,12,17,20,22,30,33,34]
+    integer,parameter :: NLTE_CHANNEL(3) = [20,22,34]
+    integer,parameter :: N_NLTE_CHANNELS = size(NLTE_CHANNEL)
+    integer,parameter :: N_CHANNELS = size(SENSOR_CHANNEL)
+    integer i
+    integer,parameter :: C_INDEX(8) = unpack( &
+       vector = [(i,i=1,size(SENSOR_CHANNEL))], &
+       mask = [(any(SENSOR_CHANNEL(i) == NLTE_CHANNEL), &
+          i=lbound(SENSOR_CHANNEL,1),ubound(SENSOR_CHANNEL,1))], &
+       field = 0)
+    character(20) fmt
+ 
+    write(fmt,'(a,i0,a)') '(a,t19,',size(SENSOR_CHANNEL),'(i3:","))'
+    write(*,fmt) 'SENSOR_CHANNEL = ',SENSOR_CHANNEL
+    write(fmt,'(a,i0,a)') '(a,t19,',size(NLTE_CHANNEL),'(i3:","))'
+    write(*,fmt) 'NLTE_CHANNEL = ',NLTE_CHANNEL
+    write(*,'(a,t19,i3)') 'N_NLTE_CHANNELS = ',N_NLTE_CHANNELS
+    write(*,'(a,t19,i3)') 'N_CHANNELS = ',N_CHANNELS
+    write(fmt,'(a,i0,a)') '(a,t19,',size(C_INDEX),'(i3:","))'
+    write(*,fmt) 'C_INDEX = ',C_INDEX
+ end program Cindex

Reply via email to