mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
a044d2b1b6
commit
0e360db970
|
|
@ -1,3 +1,18 @@
|
||||||
|
2015-08-07 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
2015-08-06 Mikael Morin <mikael@gcc.gnu.org>
|
2015-08-06 Mikael Morin <mikael@gcc.gnu.org>
|
||||||
|
|
||||||
* trans.h (gfc_trans_scalar_assign): Remove fourth argument.
|
* trans.h (gfc_trans_scalar_assign): Remove fourth argument.
|
||||||
|
|
|
||||||
|
|
@ -2474,13 +2474,14 @@ gfc_check_init_expr (gfc_expr *e)
|
||||||
gfc_intrinsic_sym* isym;
|
gfc_intrinsic_sym* isym;
|
||||||
gfc_symbol* sym = e->symtree->n.sym;
|
gfc_symbol* sym = e->symtree->n.sym;
|
||||||
|
|
||||||
/* Special case for IEEE_SELECTED_REAL_KIND from the intrinsic
|
/* Simplify here the intrinsics from the IEEE_ARITHMETIC and
|
||||||
module IEEE_ARITHMETIC, which is allowed in initialization
|
IEEE_EXCEPTIONS modules. */
|
||||||
expressions. */
|
int mod = sym->from_intmod;
|
||||||
if (!strcmp(sym->name, "ieee_selected_real_kind")
|
if (mod == INTMOD_NONE && sym->generic)
|
||||||
&& sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
|
mod = sym->generic->sym->from_intmod;
|
||||||
|
if (mod == INTMOD_IEEE_ARITHMETIC || mod == INTMOD_IEEE_EXCEPTIONS)
|
||||||
{
|
{
|
||||||
gfc_expr *new_expr = gfc_simplify_ieee_selected_real_kind (e);
|
gfc_expr *new_expr = gfc_simplify_ieee_functions (e);
|
||||||
if (new_expr)
|
if (new_expr)
|
||||||
{
|
{
|
||||||
gfc_replace_expr (e, new_expr);
|
gfc_replace_expr (e, new_expr);
|
||||||
|
|
@ -2738,6 +2739,29 @@ external_spec_function (gfc_expr *e)
|
||||||
|
|
||||||
f = e->value.function.esym;
|
f = e->value.function.esym;
|
||||||
|
|
||||||
|
/* IEEE functions allowed are "a reference to a transformational function
|
||||||
|
from the intrinsic module IEEE_ARITHMETIC or IEEE_EXCEPTIONS", and
|
||||||
|
"inquiry function from the intrinsic modules IEEE_ARITHMETIC and
|
||||||
|
IEEE_EXCEPTIONS". */
|
||||||
|
if (f->from_intmod == INTMOD_IEEE_ARITHMETIC
|
||||||
|
|| f->from_intmod == INTMOD_IEEE_EXCEPTIONS)
|
||||||
|
{
|
||||||
|
if (!strcmp (f->name, "ieee_selected_real_kind")
|
||||||
|
|| !strcmp (f->name, "ieee_support_rounding")
|
||||||
|
|| !strcmp (f->name, "ieee_support_flag")
|
||||||
|
|| !strcmp (f->name, "ieee_support_halting")
|
||||||
|
|| !strcmp (f->name, "ieee_support_datatype")
|
||||||
|
|| !strcmp (f->name, "ieee_support_denormal")
|
||||||
|
|| !strcmp (f->name, "ieee_support_divide")
|
||||||
|
|| !strcmp (f->name, "ieee_support_inf")
|
||||||
|
|| !strcmp (f->name, "ieee_support_io")
|
||||||
|
|| !strcmp (f->name, "ieee_support_nan")
|
||||||
|
|| !strcmp (f->name, "ieee_support_sqrt")
|
||||||
|
|| !strcmp (f->name, "ieee_support_standard")
|
||||||
|
|| !strcmp (f->name, "ieee_support_underflow_control"))
|
||||||
|
goto function_allowed;
|
||||||
|
}
|
||||||
|
|
||||||
if (f->attr.proc == PROC_ST_FUNCTION)
|
if (f->attr.proc == PROC_ST_FUNCTION)
|
||||||
{
|
{
|
||||||
gfc_error ("Specification function %qs at %L cannot be a statement "
|
gfc_error ("Specification function %qs at %L cannot be a statement "
|
||||||
|
|
@ -2766,6 +2790,7 @@ external_spec_function (gfc_expr *e)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function_allowed:
|
||||||
return restricted_args (e->value.function.actual);
|
return restricted_args (e->value.function.actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2881,8 +2881,6 @@ gfc_formal_arglist *gfc_sym_get_dummy_args (gfc_symbol *);
|
||||||
/* intrinsic.c -- true if working in an init-expr, false otherwise. */
|
/* intrinsic.c -- true if working in an init-expr, false otherwise. */
|
||||||
extern bool gfc_init_expr_flag;
|
extern bool gfc_init_expr_flag;
|
||||||
|
|
||||||
gfc_expr *gfc_simplify_ieee_selected_real_kind (gfc_expr *);
|
|
||||||
|
|
||||||
/* Given a symbol that we have decided is intrinsic, mark it as such
|
/* Given a symbol that we have decided is intrinsic, mark it as such
|
||||||
by placing it into a special module that is otherwise impossible to
|
by placing it into a special module that is otherwise impossible to
|
||||||
read or write. */
|
read or write. */
|
||||||
|
|
@ -3245,6 +3243,7 @@ int gfc_code_walker (gfc_code **, walk_code_fn_t, walk_expr_fn_t, void *);
|
||||||
/* simplify.c */
|
/* simplify.c */
|
||||||
|
|
||||||
void gfc_convert_mpz_to_signed (mpz_t, int);
|
void gfc_convert_mpz_to_signed (mpz_t, int);
|
||||||
|
gfc_expr *gfc_simplify_ieee_functions (gfc_expr *);
|
||||||
|
|
||||||
/* trans-array.c */
|
/* trans-array.c */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5552,20 +5552,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_expr *
|
||||||
gfc_simplify_set_exponent (gfc_expr *x, gfc_expr *i)
|
gfc_simplify_set_exponent (gfc_expr *x, gfc_expr *i)
|
||||||
{
|
{
|
||||||
|
|
@ -6955,3 +6941,62 @@ gfc_simplify_compiler_version (void)
|
||||||
return gfc_get_character_expr (gfc_default_character_kind,
|
return gfc_get_character_expr (gfc_default_character_kind,
|
||||||
&gfc_current_locus, buffer, len);
|
&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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
2015-08-07 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR fortran/64104
|
||||||
|
* gfortran.dg/ieee/ieee_8.f90: New test.
|
||||||
|
|
||||||
2015-08-07 Jiong Wang <jiong.wang@arm.com>
|
2015-08-07 Jiong Wang <jiong.wang@arm.com>
|
||||||
|
|
||||||
* gcc.target/aarch64/noplt_1.c: Check branch type instead of relocation
|
* gcc.target/aarch64/noplt_1.c: Check branch type instead of relocation
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
! { dg-do run }
|
||||||
|
|
||||||
|
module foo
|
||||||
|
use :: ieee_exceptions
|
||||||
|
use :: ieee_arithmetic
|
||||||
|
end module foo
|
||||||
|
|
||||||
|
module bar
|
||||||
|
use foo
|
||||||
|
use :: ieee_arithmetic, yyy => ieee_support_rounding
|
||||||
|
use :: ieee_arithmetic, zzz => ieee_selected_real_kind
|
||||||
|
end module
|
||||||
|
|
||||||
|
program test
|
||||||
|
use :: bar
|
||||||
|
use :: ieee_arithmetic, xxx => ieee_support_rounding
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
! IEEE functions allowed in constant expressions
|
||||||
|
|
||||||
|
integer, parameter :: n1 = ieee_selected_real_kind(0, 0)
|
||||||
|
logical, parameter :: l1 = ieee_support_halting(ieee_overflow)
|
||||||
|
logical, parameter :: l2 = ieee_support_flag(ieee_overflow)
|
||||||
|
logical, parameter :: l3 = ieee_support_flag(ieee_overflow, 0.)
|
||||||
|
logical, parameter :: l4 = ieee_support_rounding(ieee_to_zero)
|
||||||
|
logical, parameter :: l5 = ieee_support_rounding(ieee_to_zero, 0.d0)
|
||||||
|
|
||||||
|
logical, parameter :: l6 = xxx(ieee_to_zero, 0.d0)
|
||||||
|
logical, parameter :: l7 = yyy(ieee_to_zero, 0.d0)
|
||||||
|
integer, parameter :: n2 = zzz(0, 0)
|
||||||
|
|
||||||
|
call gee(8, ieee_to_zero, ieee_overflow)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
! IEEE functions allowed in specification expressions
|
||||||
|
|
||||||
|
subroutine gee(n, rounding, flag)
|
||||||
|
use :: bar
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer :: n
|
||||||
|
type(ieee_round_type) :: rounding
|
||||||
|
type(ieee_flag_type) :: flag
|
||||||
|
|
||||||
|
character(len=ieee_selected_real_kind(n)) :: s1
|
||||||
|
character(len=ieee_selected_real_kind(n,2*n)) :: s2
|
||||||
|
character(len=ieee_selected_real_kind(n,2*n,2)) :: s3
|
||||||
|
|
||||||
|
character(len=merge(4,2,ieee_support_rounding(rounding))) :: s4
|
||||||
|
character(len=merge(4,2,ieee_support_rounding(rounding, 0.d0))) :: s5
|
||||||
|
|
||||||
|
character(len=merge(4,2,ieee_support_flag(flag))) :: s6
|
||||||
|
character(len=merge(4,2,ieee_support_flag(flag, 0.))) :: s7
|
||||||
|
|
||||||
|
character(len=merge(4,2,ieee_support_halting(flag))) :: s8
|
||||||
|
|
||||||
|
character(len=merge(4,2,ieee_support_datatype())) :: s9
|
||||||
|
character(len=merge(4,2,ieee_support_datatype(0.))) :: s10
|
||||||
|
|
||||||
|
character(len=merge(4,2,ieee_support_denormal())) :: s11
|
||||||
|
character(len=merge(4,2,ieee_support_denormal(0.))) :: s12
|
||||||
|
|
||||||
|
character(len=merge(4,2,ieee_support_divide())) :: s13
|
||||||
|
character(len=merge(4,2,ieee_support_divide(0.))) :: s14
|
||||||
|
|
||||||
|
character(len=merge(4,2,ieee_support_inf())) :: s15
|
||||||
|
character(len=merge(4,2,ieee_support_inf(0.))) :: s16
|
||||||
|
|
||||||
|
character(len=merge(4,2,ieee_support_io())) :: s17
|
||||||
|
character(len=merge(4,2,ieee_support_io(0.))) :: s18
|
||||||
|
|
||||||
|
character(len=merge(4,2,ieee_support_nan())) :: s19
|
||||||
|
character(len=merge(4,2,ieee_support_nan(0.))) :: s20
|
||||||
|
|
||||||
|
character(len=merge(4,2,ieee_support_sqrt())) :: s21
|
||||||
|
character(len=merge(4,2,ieee_support_sqrt(0.))) :: s22
|
||||||
|
|
||||||
|
character(len=merge(4,2,ieee_support_standard())) :: s23
|
||||||
|
character(len=merge(4,2,ieee_support_standard(0.))) :: s24
|
||||||
|
|
||||||
|
character(len=merge(4,2,ieee_support_underflow_control())) :: s25
|
||||||
|
character(len=merge(4,2,ieee_support_underflow_control(0.))) :: s26
|
||||||
|
|
||||||
|
! Now, check that runtime values match compile-time constants
|
||||||
|
! (for those that are allowed)
|
||||||
|
|
||||||
|
integer, parameter :: x1 = ieee_selected_real_kind(8)
|
||||||
|
integer, parameter :: x2 = ieee_selected_real_kind(8,2*8)
|
||||||
|
integer, parameter :: x3 = ieee_selected_real_kind(8,2*8,2)
|
||||||
|
|
||||||
|
integer, parameter :: x4 = merge(4,2,ieee_support_rounding(rounding))
|
||||||
|
integer, parameter :: x5 = merge(4,2,ieee_support_rounding(rounding, 0.d0))
|
||||||
|
|
||||||
|
integer, parameter :: x6 = merge(4,2,ieee_support_flag(ieee_overflow))
|
||||||
|
integer, parameter :: x7 = merge(4,2,ieee_support_flag(ieee_overflow, 0.))
|
||||||
|
|
||||||
|
integer, parameter :: x8 = merge(4,2,ieee_support_halting(ieee_overflow))
|
||||||
|
|
||||||
|
if (len(s1) /= x1) call abort
|
||||||
|
if (len(s2) /= x2) call abort
|
||||||
|
if (len(s3) /= x3) call abort
|
||||||
|
|
||||||
|
if (len(s4) /= x4) call abort
|
||||||
|
if (len(s5) /= x5) call abort
|
||||||
|
|
||||||
|
if (len(s6) /= x6) call abort
|
||||||
|
if (len(s7) /= x7) call abort
|
||||||
|
|
||||||
|
if (len(s8) /= x8) call abort
|
||||||
|
|
||||||
|
end subroutine
|
||||||
|
|
||||||
|
! { dg-final { cleanup-modules "foo bar" } }
|
||||||
Loading…
Reference in New Issue