aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/decl.c
diff options
context:
space:
mode:
authorDaniel Kraft <d@domob.eu>2010-08-15 17:28:10 +0200
committerDaniel Kraft <domob@gcc.gnu.org>2010-08-15 17:28:10 +0200
commite6c148988cfe585abf4eb2d3f1839f97a83cc1a9 (patch)
treee3e1c7f09d4ce2dcff79e7b4801680172b017c43 /gcc/fortran/decl.c
parent69f11a1360a23fd4aa0567ab1c4b62dcc5be8127 (diff)
downloadgcc-e6c148988cfe585abf4eb2d3f1839f97a83cc1a9.zip
gcc-e6c148988cfe585abf4eb2d3f1839f97a83cc1a9.tar.gz
gcc-e6c148988cfe585abf4eb2d3f1839f97a83cc1a9.tar.bz2
re PR fortran/45197 ([F2008] Allow IMPURE elemental procedures)
2010-08-15 Daniel Kraft <d@domob.eu> PR fortran/45197 * decl.c (gfc_match_prefix): Match IMPURE prefix and mark ELEMENTAL routines not IMPURE also as PURE. * intrinsic.c (enum klass): New class `CLASS_PURE' and renamed `NO_CLASS' in `CLASS_IMPURE'. (add_sym): Set symbol-attributes `pure' and `elemental' correctly. (add_sym_0s): Renamed `NO_CLASS' in `CLASS_IMPURE'. (add_functions): Ditto. (add_subroutines): Ditto and mark `MOVE_ALLOC' as CLASS_PURE. * resolve.c (gfc_pure): Do not treat ELEMENTAL as automatically PURE. (resolve_formal_arglist): Check that arguments to ELEMENTAL procedures are not ALLOCATABLE and have their INTENT specified. 2010-08-15 Daniel Kraft <d@domob.eu> PR fortran/45197 * gfortran.dg/elemental_args_check_3.f90: New test. * gfortran.dg/impure_1.f08: New test. * gfortran.dg/impure_2.f08: New test. * gfortran.dg/impure_3.f90: New test. * gfortran.dg/typebound_proc_6.f03: Changed expected error message. From-SVN: r163261
Diffstat (limited to 'gcc/fortran/decl.c')
-rw-r--r--gcc/fortran/decl.c80
1 files changed, 58 insertions, 22 deletions
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 91eb710..be41af8 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -4052,45 +4052,81 @@ match
gfc_match_prefix (gfc_typespec *ts)
{
bool seen_type;
+ bool seen_impure;
+ bool found_prefix;
gfc_clear_attr (&current_attr);
- seen_type = 0;
+ seen_type = false;
+ seen_impure = false;
gcc_assert (!gfc_matching_prefix);
gfc_matching_prefix = true;
-loop:
- if (!seen_type && ts != NULL
- && gfc_match_decl_type_spec (ts, 0) == MATCH_YES
- && gfc_match_space () == MATCH_YES)
+ do
{
+ found_prefix = false;
- seen_type = 1;
- goto loop;
- }
+ if (!seen_type && ts != NULL
+ && gfc_match_decl_type_spec (ts, 0) == MATCH_YES
+ && gfc_match_space () == MATCH_YES)
+ {
- if (gfc_match ("elemental% ") == MATCH_YES)
- {
- if (gfc_add_elemental (&current_attr, NULL) == FAILURE)
- goto error;
+ seen_type = true;
+ found_prefix = true;
+ }
+
+ if (gfc_match ("elemental% ") == MATCH_YES)
+ {
+ if (gfc_add_elemental (&current_attr, NULL) == FAILURE)
+ goto error;
- goto loop;
+ found_prefix = true;
+ }
+
+ if (gfc_match ("pure% ") == MATCH_YES)
+ {
+ if (gfc_add_pure (&current_attr, NULL) == FAILURE)
+ goto error;
+
+ found_prefix = true;
+ }
+
+ if (gfc_match ("recursive% ") == MATCH_YES)
+ {
+ if (gfc_add_recursive (&current_attr, NULL) == FAILURE)
+ goto error;
+
+ found_prefix = true;
+ }
+
+ /* IMPURE is a somewhat special case, as it needs not set an actual
+ attribute but rather only prevents ELEMENTAL routines from being
+ automatically PURE. */
+ if (gfc_match ("impure% ") == MATCH_YES)
+ {
+ if (gfc_notify_std (GFC_STD_F2008,
+ "Fortran 2008: IMPURE procedure at %C")
+ == FAILURE)
+ goto error;
+
+ seen_impure = true;
+ found_prefix = true;
+ }
}
+ while (found_prefix);
- if (gfc_match ("pure% ") == MATCH_YES)
+ /* IMPURE and PURE must not both appear, of course. */
+ if (seen_impure && current_attr.pure)
{
- if (gfc_add_pure (&current_attr, NULL) == FAILURE)
- goto error;
-
- goto loop;
+ gfc_error ("PURE and IMPURE must not appear both at %C");
+ goto error;
}
- if (gfc_match ("recursive% ") == MATCH_YES)
+ /* If IMPURE it not seen but the procedure is ELEMENTAL, mark it as PURE. */
+ if (!seen_impure && current_attr.elemental && !current_attr.pure)
{
- if (gfc_add_recursive (&current_attr, NULL) == FAILURE)
+ if (gfc_add_pure (&current_attr, NULL) == FAILURE)
goto error;
-
- goto loop;
}
/* At this point, the next item is not a prefix. */