summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/fortran/ChangeLog11
-rw-r--r--gcc/fortran/decl.c12
-rw-r--r--gcc/fortran/intrinsic.c20
-rw-r--r--gcc/fortran/intrinsic.h2
-rw-r--r--gcc/fortran/simplify.c32
5 files changed, 61 insertions, 16 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 38686eeb1a5..51aeeaf14b1 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,14 @@
+2008-03-06 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/33197
+ * intrinsic.c (add_functions): Add simplification routines for
+ ERF, DERF, ERFC and DERFC.
+ * decl.c (gfc_match_suffix, gfc_match_subroutine): Change GNU
+ extensions into Fortran 2008 features.
+ * intrinsic.h (gfc_simplify_erf, gfc_simplify_erfc): New
+ prototypes.
+ * simplify.c (gfc_simplify_erf, gfc_simplify_erfc): New functions.
+
2008-03-03 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/33197
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 892c80a46d3..d6a5633a2f6 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -3999,9 +3999,9 @@ gfc_match_suffix (gfc_symbol *sym, gfc_symbol **result)
/* Fortran 2008 draft allows BIND(C) for internal procedures. */
if (gfc_current_state () == COMP_CONTAINS
&& sym->ns->proc_name->attr.flavor != FL_MODULE
- && gfc_notify_std (GFC_STD_GNU, "Extension: BIND(C) attribute at %L "
- "may not be specified for an internal procedure",
- &gfc_current_locus)
+ && gfc_notify_std (GFC_STD_F2008, "Fortran 2008: BIND(C) attribute "
+ "at %L may not be specified for an internal "
+ "procedure", &gfc_current_locus)
== FAILURE)
return MATCH_ERROR;
@@ -4733,9 +4733,9 @@ gfc_match_subroutine (void)
/* The following is allowed in the Fortran 2008 draft. */
if (gfc_current_state () == COMP_CONTAINS
&& sym->ns->proc_name->attr.flavor != FL_MODULE
- && gfc_notify_std (GFC_STD_GNU, "Extension: BIND(C) attribute at "
- "%L may not be specified for an internal procedure",
- &gfc_current_locus)
+ && gfc_notify_std (GFC_STD_F2008, "Fortran 2008: BIND(C) attribute "
+ "at %L may not be specified for an internal "
+ "procedure", &gfc_current_locus)
== FAILURE)
return MATCH_ERROR;
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index e2f3517b47c..258123b92b5 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -1352,22 +1352,22 @@ add_functions (void)
/* G77 compatibility for the ERF() and ERFC() functions. */
add_sym_1 ("erf", GFC_ISYM_ERF, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr,
- GFC_STD_F2008, gfc_check_fn_r, NULL, gfc_resolve_g77_math1,
- x, BT_REAL, dr, REQUIRED);
+ GFC_STD_F2008, gfc_check_fn_r, gfc_simplify_erf,
+ gfc_resolve_g77_math1, x, BT_REAL, dr, REQUIRED);
- add_sym_1 ("derf", GFC_ISYM_ERF, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dd, GFC_STD_GNU,
- gfc_check_fn_d, NULL, gfc_resolve_g77_math1,
- x, BT_REAL, dd, REQUIRED);
+ add_sym_1 ("derf", GFC_ISYM_ERF, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dd,
+ GFC_STD_GNU, gfc_check_fn_d, gfc_simplify_erf,
+ gfc_resolve_g77_math1, x, BT_REAL, dd, REQUIRED);
make_generic ("erf", GFC_ISYM_ERF, GFC_STD_F2008);
add_sym_1 ("erfc", GFC_ISYM_ERFC, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr,
- GFC_STD_F2008, gfc_check_fn_r, NULL, gfc_resolve_g77_math1,
- x, BT_REAL, dr, REQUIRED);
+ GFC_STD_F2008, gfc_check_fn_r, gfc_simplify_erfc,
+ gfc_resolve_g77_math1, x, BT_REAL, dr, REQUIRED);
- add_sym_1 ("derfc", GFC_ISYM_ERFC, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dd, GFC_STD_GNU,
- gfc_check_fn_d, NULL, gfc_resolve_g77_math1,
- x, BT_REAL, dd, REQUIRED);
+ add_sym_1 ("derfc", GFC_ISYM_ERFC, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dd,
+ GFC_STD_GNU, gfc_check_fn_d, gfc_simplify_erfc,
+ gfc_resolve_g77_math1, x, BT_REAL, dd, REQUIRED);
make_generic ("erfc", GFC_ISYM_ERFC, GFC_STD_F2008);
diff --git a/gcc/fortran/intrinsic.h b/gcc/fortran/intrinsic.h
index 3ae41451742..dc91e77caaf 100644
--- a/gcc/fortran/intrinsic.h
+++ b/gcc/fortran/intrinsic.h
@@ -222,6 +222,8 @@ gfc_expr *gfc_simplify_digits (gfc_expr *);
gfc_expr *gfc_simplify_dim (gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_dprod (gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_epsilon (gfc_expr *);
+gfc_expr *gfc_simplify_erf (gfc_expr *);
+gfc_expr *gfc_simplify_erfc (gfc_expr *);
gfc_expr *gfc_simplify_exp (gfc_expr *);
gfc_expr *gfc_simplify_exponent (gfc_expr *);
gfc_expr *gfc_simplify_float (gfc_expr *);
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index a8277ac7046..2272bb567b5 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -1061,6 +1061,38 @@ gfc_simplify_dprod (gfc_expr *x, gfc_expr *y)
gfc_expr *
+gfc_simplify_erf (gfc_expr *x)
+{
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ mpfr_erf (result->value.real, x->value.real, GFC_RND_MODE);
+
+ return range_check (result, "ERF");
+}
+
+
+gfc_expr *
+gfc_simplify_erfc (gfc_expr *x)
+{
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ mpfr_erfc (result->value.real, x->value.real, GFC_RND_MODE);
+
+ return range_check (result, "ERFC");
+}
+
+
+gfc_expr *
gfc_simplify_epsilon (gfc_expr *e)
{
gfc_expr *result;