re PR fortran/41044 (internal compiler error: in gfc_conv_intrinsic_function)
authorPaul Thomas <pault@gcc.gnu.org>
Sun, 24 Jan 2010 16:59:51 +0000 (16:59 +0000)
committerPaul Thomas <pault@gcc.gnu.org>
Sun, 24 Jan 2010 16:59:51 +0000 (16:59 +0000)
2010-01-24  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/41044
PR fortran/41167
* expr.c (remove_subobject_ref): If the constructor is NULL use
the expression as the source.
(simplify_const_ref): Change the type of expression if
there are component references.  Allow for substring to be at
the end of an arbitrarily long chain of references.  If an
element is found that is not in an EXPR_ARRAY, assume that this
is scalar initialization of array. Call remove_subobject_ref in
this case with NULL second argument.

2010-01-24  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/41044
* gfortran.dg/parameter_array_ref_2.f90 : New test.

PR fortran/41167
* gfortran.dg/char_array_arg_1.f90 : New test.

* gfortran.dg/pr25923.f90 : Remove XFAIL.

From-SVN: r156197

gcc/fortran/ChangeLog
gcc/fortran/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/char_array_arg_1.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/parameter_array_ref_2.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/pr25923.f90

index ae4fa519b68255d8871f999e248279309ed6601e..760fc24f451ba437433458f603c6c0ca0c9ada2d 100644 (file)
@@ -1,3 +1,16 @@
+2010-01-24  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/41044
+       PR fortran/41167
+       * expr.c (remove_subobject_ref): If the constructor is NULL use
+       the expression as the source.
+       (simplify_const_ref): Change the type of expression if
+       there are component references.  Allow for substring to be at
+       the end of an arbitrarily long chain of references.  If an
+       element is found that is not in an EXPR_ARRAY, assume that this
+       is scalar initialization of array. Call remove_subobject_ref in
+       this case with NULL second argument.
+
 2010-01-24  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/39304
index 8fa46d82f708557f35ab8e9ca25f87275bba850c..d846c0f121ebad8f859f0464628d98df17331482 100644 (file)
@@ -1154,8 +1154,13 @@ remove_subobject_ref (gfc_expr *p, gfc_constructor *cons)
 {
   gfc_expr *e;
 
-  e = cons->expr;
-  cons->expr = NULL;
+  if (cons)
+    {
+      e = cons->expr;
+      cons->expr = NULL;
+    }
+  else
+    e = gfc_copy_expr (p);
   e->ref = p->ref->next;
   p->ref->next =  NULL;
   gfc_replace_expr (p, e);
@@ -1464,6 +1469,7 @@ simplify_const_ref (gfc_expr *p)
 {
   gfc_constructor *cons;
   gfc_expr *newp;
+  gfc_ref *last_ref;
 
   while (p->ref)
     {
@@ -1473,6 +1479,13 @@ simplify_const_ref (gfc_expr *p)
          switch (p->ref->u.ar.type)
            {
            case AR_ELEMENT:
+             /* <type/kind spec>, parameter :: x(<int>) = scalar_expr
+                will generate this.  */
+             if (p->expr_type != EXPR_ARRAY)
+               {
+                 remove_subobject_ref (p, NULL);
+                 break;
+               }
              if (find_array_element (p->value.constructor, &p->ref->u.ar,
                                      &cons) == FAILURE)
                return FAILURE;
@@ -1502,18 +1515,25 @@ simplify_const_ref (gfc_expr *p)
                        return FAILURE;
                    }
 
-                 /* If this is a CHARACTER array and we possibly took a
-                    substring out of it, update the type-spec's character
-                    length according to the first element (as all should have
-                    the same length).  */
-                 if (p->ts.type == BT_CHARACTER)
+                 if (p->ts.type == BT_DERIVED
+                       && p->ref->next
+                       && p->value.constructor)
                    {
-                     int string_len;
+                     /* There may have been component references.  */
+                     p->ts = p->value.constructor->expr->ts;
+                   }
 
-                     gcc_assert (p->ref->next);
-                     gcc_assert (!p->ref->next->next);
-                     gcc_assert (p->ref->next->type == REF_SUBSTRING);
+                 last_ref = p->ref;
+                 for (; last_ref->next; last_ref = last_ref->next) {};
 
+                 if (p->ts.type == BT_CHARACTER
+                       && last_ref->type == REF_SUBSTRING)
+                   {
+                     /* If this is a CHARACTER array and we possibly took
+                        a substring out of it, update the type-spec's
+                        character length according to the first element
+                        (as all should have the same length).  */
+                     int string_len;
                      if (p->value.constructor)
                        {
                          const gfc_expr* first = p->value.constructor->expr;
index c9a6fdc92f4aef3c79c6285c2a2be0c83d44f1c7..b9dd12432d0a8e65b4cf9f81188e8d59cb108d13 100644 (file)
@@ -1,3 +1,13 @@
+2010-01-24  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/41044
+       * gfortran.dg/parameter_array_ref_2.f90 : New test.
+
+       PR fortran/41167
+       * gfortran.dg/char_array_arg_1.f90 : New test.
+
+       * gfortran.dg/pr25923.f90 : Remove XFAIL.
+
 2010-01-24  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/39304
diff --git a/gcc/testsuite/gfortran.dg/char_array_arg_1.f90 b/gcc/testsuite/gfortran.dg/char_array_arg_1.f90
new file mode 100644 (file)
index 0000000..097fbc6
--- /dev/null
@@ -0,0 +1,17 @@
+! { dg-do compile }
+! Test the fix for pr41167, in which the first argument of 'pack', below,
+! was simplified incorrectly, with the results indicated.
+!
+! Contributed by Harald Anlauf <anlauf@gmx.de>
+!
+program gfcbug88
+  implicit none
+  type t
+     character(len=8) :: name
+  end type t
+  type(t) ,parameter :: obstyp(2)= (/ t ('A'), t ('B') /)
+  character(9) :: chr(1)
+
+  print *, pack (" "//obstyp(:)% name, (/ .true., .false. /))  ! Used to ICE on compilation
+  chr = pack (" "//obstyp(:)% name, (/ .true., .false. /))  ! Used to give conversion error
+end program gfcbug88
diff --git a/gcc/testsuite/gfortran.dg/parameter_array_ref_2.f90 b/gcc/testsuite/gfortran.dg/parameter_array_ref_2.f90
new file mode 100644 (file)
index 0000000..30f300f
--- /dev/null
@@ -0,0 +1,39 @@
+! { dg-do compile }
+! Test the fix for the problems in PR41044
+!
+! Contributed by <ros@rzg.mpg.de>
+! Reduced by Joos VandeVondele <jv244@cam.ac.uk>
+!
+  Subroutine PS_INIT (bkgd, punit, pform, psize, rot90, bbox, clip, eps,  &
+                        caller)
+    type psfd                          ! paper size and frame defaults
+      character(3)                     :: n
+      real                             :: p(2)
+      real                             :: f(4)
+    end type psfd
+    character(4)                       :: fn, orich, pfmt
+    type(psfd), parameter              :: pfd(0:11)=(/  &
+         psfd('   ',(/   0.0,   0.0/),(/200.,120.,800.,560./)), &    ! A0_L
+         psfd('A0 ',(/ 840.9,1189.2/),(/140., 84.,560.,400./)), &    ! A0_P
+         psfd('A1 ',(/ 594.6, 840.9/),(/100., 60.,400.,280./)), &    ! A1_P
+         psfd('A2 ',(/ 420.4, 594.6/),(/ 70., 42.,280.,200./)), &    ! A2_P
+         psfd('A3 ',(/ 297.3, 420.4/),(/ 50., 30.,200.,140./)), &    ! A3_P
+         psfd('A4 ',(/ 210.2, 297.3/),(/ 35., 21.,140.,100./)), &    ! A4_P
+         psfd('A5 ',(/ 148.7, 210.2/),(/ 25., 15.,100., 70./)), &    ! A5_P
+         psfd('A6 ',(/ 105.1, 148.7/),(/ 18., 11., 70., 50./)), &    ! A6_P
+         psfd('   ',(/   0.0,   0.0/),(/ 50., 30.,200.,140./)), &    ! Letter_L
+         psfd('LET',(/ 215.9, 279.4/),(/ 35., 21.,140.,100./)), &    ! Letter_P
+         psfd('   ',(/   0.0,   0.0/),(/ 50., 30.,200.,140./)), &    ! Legal_L
+         psfd('LEG',(/ 215.9, 355.6/),(/ 35., 21.,140.,100./))/)     ! Legal_P
+    if (len_trim(pfmt) > 0) then       ! set paper format
+      idx=sum(maxloc(index(pfd%n,pfmt(1:3))))-1
+    end if
+  end subroutine PS_INIT
+
+! This, additional problem, was posted as comment #8 by Tobias Burnus <burnus@gcc.gnu.org>
+  type t
+    integer :: i
+  end type t
+  type(t), parameter :: a(1) = t(4) ! [t(4)] worked OK
+  real(a(1)%i) :: b
+end
index b6979ec8896bb9c1f3b3e51a8e74a327d7e0a233..f075944b92bd1778aa7e6117a75c1830e888b928 100644 (file)
@@ -10,7 +10,7 @@ implicit none
 
 contains
 
-  function baz(arg) result(res) ! { dg-warning "res.yr' may be" "" { xfail *-*-* } }
+  function baz(arg) result(res) ! { dg-warning "res.yr' may be" }
     type(bar), intent(in) :: arg
     type(bar) :: res
     logical, external:: some_func