diff options
author | Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2015-08-07 15:02:15 +0000 |
---|---|---|
committer | François-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2015-08-07 15:02:15 +0000 |
commit | 0e360db97091f31bf8a16ec50e99b31ebe6c52e1 (patch) | |
tree | 8a5b785abc55fa5c397eb33f2c98ba742798a57c /gcc/fortran/simplify.c | |
parent | a044d2b1b6c85f88451e83649977ad908011b1f4 (diff) | |
download | gcc-0e360db97091f31bf8a16ec50e99b31ebe6c52e1.zip gcc-0e360db97091f31bf8a16ec50e99b31ebe6c52e1.tar.gz gcc-0e360db97091f31bf8a16ec50e99b31ebe6c52e1.tar.bz2 |
re PR fortran/64104 ([F2003][IEEE] Allow IEEE functions in specification expressions)
PR fortran/64104
* expr.c (gfc_check_init_expr): Allow some IEEE functions in
constant expressions.
(external_spec_function): Allow some IEEE functions in specification
expressions.
* simplify.c (gfc_simplify_ieee_selected_real_kind): Remove.
(simplify_ieee_selected_real_kind, simplify_ieee_support,
matches_ieee_function_name, gfc_simplify_ieee_functions): New
functions.
* gfortran.h (gfc_simplify_ieee_selected_real_kind): Remove
prototype.
(gfc_simplify_ieee_functions): Add prototype.
* gfortran.dg/ieee/ieee_8.f90: New test.
From-SVN: r226723
Diffstat (limited to 'gcc/fortran/simplify.c')
-rw-r--r-- | gcc/fortran/simplify.c | 73 |
1 files changed, 59 insertions, 14 deletions
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index f0fdfbd..124558e 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -5553,20 +5553,6 @@ gfc_simplify_selected_real_kind (gfc_expr *p, gfc_expr *q, gfc_expr *rdx) gfc_expr * -gfc_simplify_ieee_selected_real_kind (gfc_expr *expr) -{ - gfc_actual_arglist *arg = expr->value.function.actual; - gfc_expr *p = arg->expr, *q = arg->next->expr, - *rdx = arg->next->next->expr; - - /* Currently, if IEEE is supported and this module is built, it means - all our floating-point types conform to IEEE. Hence, we simply handle - IEEE_SELECTED_REAL_KIND like SELECTED_REAL_KIND. */ - return gfc_simplify_selected_real_kind (p, q, rdx); -} - - -gfc_expr * gfc_simplify_set_exponent (gfc_expr *x, gfc_expr *i) { gfc_expr *result; @@ -6955,3 +6941,62 @@ gfc_simplify_compiler_version (void) return gfc_get_character_expr (gfc_default_character_kind, &gfc_current_locus, buffer, len); } + +/* Simplification routines for intrinsics of IEEE modules. */ + +gfc_expr * +simplify_ieee_selected_real_kind (gfc_expr *expr) +{ + gfc_actual_arglist *arg = expr->value.function.actual; + gfc_expr *p = arg->expr, *q = arg->next->expr, + *rdx = arg->next->next->expr; + + /* Currently, if IEEE is supported and this module is built, it means + all our floating-point types conform to IEEE. Hence, we simply handle + IEEE_SELECTED_REAL_KIND like SELECTED_REAL_KIND. */ + return gfc_simplify_selected_real_kind (p, q, rdx); +} + +gfc_expr * +simplify_ieee_support (gfc_expr *expr) +{ + /* We consider that if the IEEE modules are loaded, we have full support + for flags, halting and rounding, which are the three functions + (IEEE_SUPPORT_{FLAG,HALTING,ROUNDING}) allowed in constant + expressions. One day, we will need libgfortran to detect support and + communicate it back to us, allowing for partial support. */ + + return gfc_get_logical_expr (gfc_default_logical_kind, &expr->where, + true); +} + +bool +matches_ieee_function_name (gfc_symbol *sym, const char *name) +{ + int n = strlen(name); + + if (!strncmp(sym->name, name, n)) + return true; + + /* If a generic was used and renamed, we need more work to find out. + Compare the specific name. */ + if (sym->generic && !strncmp(sym->generic->sym->name, name, n)) + return true; + + return false; +} + +gfc_expr * +gfc_simplify_ieee_functions (gfc_expr *expr) +{ + gfc_symbol* sym = expr->symtree->n.sym; + + if (matches_ieee_function_name(sym, "ieee_selected_real_kind")) + return simplify_ieee_selected_real_kind (expr); + else if (matches_ieee_function_name(sym, "ieee_support_flag") + || matches_ieee_function_name(sym, "ieee_support_halting") + || matches_ieee_function_name(sym, "ieee_support_rounding")) + return simplify_ieee_support (expr); + else + return NULL; +} |