Commit 87c789f1 by Paul Thomas

re PR fortran/45305 (Array-valued calles to elementals are not simplified)

2018-07-02  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/45305
	* expr.c : Add a prototype for scalarize_intrinsic_call.
	(gfc_simplify_expr): Use scalarize_intrinsic_call for elemental
	intrinsic function calls.
	(scalarize_intrinsic_call): Add 'init_flag' argument. Check if
	the expression or any of the actual argument expressions are
	NULL. Before calling gfc_check_init_expr, check 'init_flag'.
	Only simplify the scalarized expressions if there are no errors
	on the stack.
	(gfc_check_init_expr): Set 'init_flag' true in the call to
	scalarize_intrinsic_call.

2018-07-02  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/45305
	* gfortran.dg/scalarize_parameter_array_2.f90: New test.

From-SVN: r262299
parent 61c74e84
2018-07-02 Paul Thomas <pault@gcc.gnu.org>
PR fortran/45305
* expr.c : Add a prototype for scalarize_intrinsic_call.
(gfc_simplify_expr): Use scalarize_intrinsic_call for elemental
intrinsic function calls.
(scalarize_intrinsic_call): Add 'init_flag' argument. Check if
the expression or any of the actual argument expressions are
NULL. Before calling gfc_check_init_expr, check 'init_flag'.
Only simplify the scalarized expressions if there are no errors
on the stack.
(gfc_check_init_expr): Set 'init_flag' true in the call to
scalarize_intrinsic_call.
2018-06-28 Fritz Reese <fritzoreese@gmail.com> 2018-06-28 Fritz Reese <fritzoreese@gmail.com>
PR fortran/82865 PR fortran/82865
......
...@@ -1896,6 +1896,10 @@ simplify_parameter_variable (gfc_expr *p, int type) ...@@ -1896,6 +1896,10 @@ simplify_parameter_variable (gfc_expr *p, int type)
return t; return t;
} }
static bool
scalarize_intrinsic_call (gfc_expr *, bool init_flag);
/* Given an expression, simplify it by collapsing constant /* Given an expression, simplify it by collapsing constant
expressions. Most simplification takes place when the expression expressions. Most simplification takes place when the expression
tree is being constructed. If an intrinsic function is simplified tree is being constructed. If an intrinsic function is simplified
...@@ -1919,6 +1923,8 @@ bool ...@@ -1919,6 +1923,8 @@ bool
gfc_simplify_expr (gfc_expr *p, int type) gfc_simplify_expr (gfc_expr *p, int type)
{ {
gfc_actual_arglist *ap; gfc_actual_arglist *ap;
gfc_intrinsic_sym* isym = NULL;
if (p == NULL) if (p == NULL)
return true; return true;
...@@ -1938,6 +1944,14 @@ gfc_simplify_expr (gfc_expr *p, int type) ...@@ -1938,6 +1944,14 @@ gfc_simplify_expr (gfc_expr *p, int type)
&& gfc_intrinsic_func_interface (p, 1) == MATCH_ERROR) && gfc_intrinsic_func_interface (p, 1) == MATCH_ERROR)
return false; return false;
if (p->expr_type == EXPR_FUNCTION)
{
if (p->symtree)
isym = gfc_find_function (p->symtree->n.sym->name);
if (isym && isym->elemental)
scalarize_intrinsic_call (p, false);
}
break; break;
case EXPR_SUBSTRING: case EXPR_SUBSTRING:
...@@ -2051,7 +2065,7 @@ et0 (gfc_expr *e) ...@@ -2051,7 +2065,7 @@ et0 (gfc_expr *e)
/* Scalarize an expression for an elemental intrinsic call. */ /* Scalarize an expression for an elemental intrinsic call. */
static bool static bool
scalarize_intrinsic_call (gfc_expr *e) scalarize_intrinsic_call (gfc_expr *e, bool init_flag)
{ {
gfc_actual_arglist *a, *b; gfc_actual_arglist *a, *b;
gfc_constructor_base ctor; gfc_constructor_base ctor;
...@@ -2059,6 +2073,15 @@ scalarize_intrinsic_call (gfc_expr *e) ...@@ -2059,6 +2073,15 @@ scalarize_intrinsic_call (gfc_expr *e)
gfc_constructor *ci, *new_ctor; gfc_constructor *ci, *new_ctor;
gfc_expr *expr, *old; gfc_expr *expr, *old;
int n, i, rank[5], array_arg; int n, i, rank[5], array_arg;
int errors = 0;
if (e == NULL)
return false;
a = e->value.function.actual;
for (; a; a = a->next)
if (a->expr && !gfc_is_constant_expr (a->expr))
return false;
/* Find which, if any, arguments are arrays. Assume that the old /* Find which, if any, arguments are arrays. Assume that the old
expression carries the type information and that the first arg expression carries the type information and that the first arg
...@@ -2093,7 +2116,7 @@ scalarize_intrinsic_call (gfc_expr *e) ...@@ -2093,7 +2116,7 @@ scalarize_intrinsic_call (gfc_expr *e)
for (; a; a = a->next) for (; a; a = a->next)
{ {
/* Check that this is OK for an initialization expression. */ /* Check that this is OK for an initialization expression. */
if (a->expr && !gfc_check_init_expr (a->expr)) if (a->expr && init_flag && !gfc_check_init_expr (a->expr))
goto cleanup; goto cleanup;
rank[n] = 0; rank[n] = 0;
...@@ -2118,6 +2141,7 @@ scalarize_intrinsic_call (gfc_expr *e) ...@@ -2118,6 +2141,7 @@ scalarize_intrinsic_call (gfc_expr *e)
n++; n++;
} }
gfc_get_errors (NULL, &errors);
/* Using the array argument as the master, step through the array /* Using the array argument as the master, step through the array
calling the function for each element and advancing the array calling the function for each element and advancing the array
...@@ -2152,7 +2176,8 @@ scalarize_intrinsic_call (gfc_expr *e) ...@@ -2152,7 +2176,8 @@ scalarize_intrinsic_call (gfc_expr *e)
/* Simplify the function calls. If the simplification fails, the /* Simplify the function calls. If the simplification fails, the
error will be flagged up down-stream or the library will deal error will be flagged up down-stream or the library will deal
with it. */ with it. */
gfc_simplify_expr (new_ctor->expr, 0); if (errors == 0)
gfc_simplify_expr (new_ctor->expr, 0);
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
if (args[i]) if (args[i])
...@@ -2626,7 +2651,7 @@ gfc_check_init_expr (gfc_expr *e) ...@@ -2626,7 +2651,7 @@ gfc_check_init_expr (gfc_expr *e)
array argument. */ array argument. */
isym = gfc_find_function (e->symtree->n.sym->name); isym = gfc_find_function (e->symtree->n.sym->name);
if (isym && isym->elemental if (isym && isym->elemental
&& (t = scalarize_intrinsic_call (e))) && (t = scalarize_intrinsic_call (e, true)))
break; break;
} }
...@@ -5344,7 +5369,7 @@ gfc_is_simply_contiguous (gfc_expr *expr, bool strict, bool permit_element) ...@@ -5344,7 +5369,7 @@ gfc_is_simply_contiguous (gfc_expr *expr, bool strict, bool permit_element)
s = expr->symtree->n.sym; s = expr->symtree->n.sym;
if (s->ts.type != BT_CLASS) if (s->ts.type != BT_CLASS)
return false; return false;
rc = NULL; rc = NULL;
for (r = expr->ref; r; r = r->next) for (r = expr->ref; r; r = r->next)
if (r->type == REF_COMPONENT) if (r->type == REF_COMPONENT)
......
2018-07-02 Paul Thomas <pault@gcc.gnu.org>
PR fortran/45305
* gfortran.dg/scalarize_parameter_array_2.f90: New test.
2018-07-02 Martin Liska <mliska@suse.cz> 2018-07-02 Martin Liska <mliska@suse.cz>
PR ipa/86279 PR ipa/86279
......
! { dg-do compile }
!
! Test the fix for PR45305. The if statements should simplify away so
! that 'I_do_not_exist' is not referenced.
!
! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
!
if (any (abs(bessel_jn([1,2], 1.0) - bessel_jn([1,2], 1.0)) &
> epsilon(0.0))) &
call I_do_not_exist()
if (any (abs(bessel_jn(1, 2, 1.0) - bessel_jn([1,2], 1.0)) &
> epsilon(0.0))) &
call I_do_not_exist()
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment