diff options
author | Mikael Morin <mikael@gcc.gnu.org> | 2013-03-03 17:52:02 +0000 |
---|---|---|
committer | Mikael Morin <mikael@gcc.gnu.org> | 2013-03-03 17:52:02 +0000 |
commit | d6a5de161587f701089fdafada742cf275ccd7f8 (patch) | |
tree | 542b966e4ddfa5b7b5c9ccf60d29ed08c14b363b /gcc/fortran/array.c | |
parent | cb8a1637a9914fb25bfbc9604fc20ca5e6c0601e (diff) | |
download | gcc-d6a5de161587f701089fdafada742cf275ccd7f8.zip gcc-d6a5de161587f701089fdafada742cf275ccd7f8.tar.gz gcc-d6a5de161587f701089fdafada742cf275ccd7f8.tar.bz2 |
re PR fortran/54730 (ICE in gfc_typenode_for_spec, at fortran/trans-types.c:1066)
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
Diffstat (limited to 'gcc/fortran/array.c')
-rw-r--r-- | gcc/fortran/array.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c index 6787c05..6ee292c 100644 --- a/gcc/fortran/array.c +++ b/gcc/fortran/array.c @@ -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) { |