re PR fortran/54730 (ICE in gfc_typenode_for_spec, at fortran/trans-types.c:1066)
authorMikael Morin <mikael@gcc.gnu.org>
Sun, 3 Mar 2013 17:52:02 +0000 (17:52 +0000)
committerMikael Morin <mikael@gcc.gnu.org>
Sun, 3 Mar 2013 17:52:02 +0000 (17:52 +0000)
fortran/
PR fortran/54730
* array.c (gfc_match_array_constructor): Set a checkpoint before
matching a typespec.  Drop it on success, restore it otherwise.

testsuite/
PR fortran/54730
* gfortran.dg/array_constructor_42.f90: New test.

From-SVN: r196416

gcc/fortran/ChangeLog
gcc/fortran/array.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/array_constructor_42.f90 [new file with mode: 0644]

index c9b0ca6ce571acb1eb2db131bb4e5b23430ba992..c12dd98221934d5112d0c8e2a6178d2e39a315f8 100644 (file)
@@ -1,3 +1,9 @@
+2013-03-03  Mikael Morin  <mikael@gcc.gnu.org>
+
+       PR fortran/54730
+       * array.c (gfc_match_array_constructor): Set a checkpoint before
+       matching a typespec.  Drop it on success, restore it otherwise.
+
 2013-03-03  Mikael Morin  <mikael@gcc.gnu.org>
 
        PR fortran/54730
index 6787c05de8d23c6f646e8433c298e074e82fb87e..6ee292c2a76885d5d35ef942ffd5a10b818648e6 100644 (file)
@@ -1046,6 +1046,7 @@ match
 gfc_match_array_constructor (gfc_expr **result)
 {
   gfc_constructor_base head, new_cons;
+  gfc_undo_change_set changed_syms;
   gfc_expr *expr;
   gfc_typespec ts;
   locus where;
@@ -1074,6 +1075,7 @@ gfc_match_array_constructor (gfc_expr **result)
 
   /* Try to match an optional "type-spec ::"  */
   gfc_clear_ts (&ts);
+  gfc_new_undo_checkpoint (changed_syms);
   if (gfc_match_decl_type_spec (&ts, 0) == MATCH_YES)
     {
       seen_ts = (gfc_match (" ::") == MATCH_YES);
@@ -1082,19 +1084,28 @@ gfc_match_array_constructor (gfc_expr **result)
        {
          if (gfc_notify_std (GFC_STD_F2003, "Array constructor "
                              "including type specification at %C") == FAILURE)
-           goto cleanup;
+           {
+             gfc_restore_last_undo_checkpoint ();
+             goto cleanup;
+           }
 
          if (ts.deferred)
            {
              gfc_error ("Type-spec at %L cannot contain a deferred "
                         "type parameter", &where);
+             gfc_restore_last_undo_checkpoint ();
              goto cleanup;
            }
        }
     }
 
-  if (! seen_ts)
-    gfc_current_locus = where;
+  if (seen_ts)
+    gfc_drop_last_undo_checkpoint ();
+  else
+    {
+      gfc_restore_last_undo_checkpoint ();
+      gfc_current_locus = where;
+    }
 
   if (gfc_match (end_delim) == MATCH_YES)
     {
index 112b6ae37ec817483633b93d7377f0fe9d896f1a..c34cd0f4a74aab085282831d2fa4d6d9d27eb3e2 100644 (file)
@@ -1,3 +1,8 @@
+2013-03-03  Mikael Morin  <mikael@gcc.gnu.org>
+
+       PR fortran/54730
+       * gfortran.dg/array_constructor_42.f90: New test.
+
 2013-03-02  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/52688
diff --git a/gcc/testsuite/gfortran.dg/array_constructor_42.f90 b/gcc/testsuite/gfortran.dg/array_constructor_42.f90
new file mode 100644 (file)
index 0000000..676247c
--- /dev/null
@@ -0,0 +1,22 @@
+! { dg-do compile }
+!
+! PR fortran/54730
+! A symbol 'a' was created while attempting to parse a typespec in the array
+! constructor.  That (invalid) symbol was kept until translation stage
+! where it was leading to an ICE.
+!
+! Original testcase from Paul Kapinos <kapinos@rz.rwth-aachen.de>
+!
+
+  subroutine s
+    implicit none
+    intrinsic :: real
+    real :: vec(1:2)
+    vec = (/ real(a = 1), 1. /)
+  end subroutine s
+
+  program main
+    implicit none
+    intrinsic :: real
+    print *,(/ real(a = 1) /)
+  end