Andre,

I still don't get it, and the present version made it worse for me...

So let's see what I was thinking. There are the following types of functions:

(0) impure, non-elemental functions, which likely have side-effects

(1) pure functions (in the f95 sense), i.e. pure non-elemental

(2) pure elemental functions (in the f95 sense)

(3) impure elemental functions (>= f2008)

Note that I understand "pure elemental" being different from
"pure and elemental" as used in the comment: the first version
really means both pure and elemental, the second could be read
as either pure or elemental or pure elemental.  A native speaker
may correct me if I am wrong...

Back to gfortran: we have in decl.cc::gfc_match_prefix

/* 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_pure (&current_attr, NULL))
        goto error;
    }

This explains the possible attributes we should see.

The change to coarray.cc has:

        case EXPR_FUNCTION:
-         if (!e->symtree->n.sym->attr.pure
-             && !e->symtree->n.sym->attr.elemental
-             && !(e->value.function.isym
-                  && (e->value.function.isym->pure
-                      || e->value.function.isym->elemental)))
-           /* Treat non-pure/non-elemental functions.  */
-           check_add_new_comp_handle_array (e, type, add_data);
+         if ((e->symtree->n.sym->attr.pure
+              && e->symtree->n.sym->attr.elemental)
+             || (e->value.function.isym && e->value.function.isym->pure
+                 && e->value.function.isym->elemental))
+           {
+             /* Only allow pure and elemental function calls in a coarray
+                accessor, because all other may have side effects or access
+ pointers, which may not be possible in the accessor running on
+                another host.  */
+             for (gfc_actual_arglist *actual = e->value.function.actual;
+                  actual; actual = actual->next)
+               check_add_new_component (type, actual->expr, add_data);
+           }
          else
- for (gfc_actual_arglist *actual = e->value.function.actual; actual;
-                actual = actual->next)
-             check_add_new_component (type, actual->expr, add_data);
+ /* Extract the expression, evaluate it and add a temporary with its
+              value to the helper structure.  */
+           check_add_new_comp_handle_array (e, type, add_data);


If I read the comment in the if-branch and match it against my
expectation, I am confused.  Why only "pure elemental"?  Why not
allow simply "pure"?  And wouldn't it be better to move the explaining
comment before the "if" to make it easier to read the following?
E.g. why does a pure non-elemental function need a temporary?

Thanks,
Harald


Am 07.07.25 um 10:40 schrieb Andre Vehreschild:
Hi Harald,

I totally understand your confusion. I also had a hard time figuring what is
needed there. I got to restructure the code fragment and now only allow pure
*and* elemental intrinsic function and pure *and* elemental user-defined
functions (hoping that's the opposite of intrinsics) in a caf accessor. For all
others a temporary is to be created in the helper structure. I also added a
comment to clarify the intention. I think this is better now. Opinions?

Regtests ok on x86_64-pc-linux-gnu / F41. Ok for mainline?

Regards,
        Andre

On Fri, 4 Jul 2025 19:29:08 +0200
Harald Anlauf <anl...@gmx.de> wrote:

Andre,

either your patch to coarray.cc is wrong, or the comment in the code
is not concise, or I am too dense to understand the intent of the
change:

diff --git a/gcc/fortran/coarray.cc b/gcc/fortran/coarray.cc
index ef8fd4e42d0..01aac581a74 100644
--- a/gcc/fortran/coarray.cc
+++ b/gcc/fortran/coarray.cc
@@ -700,7 +700,7 @@ check_add_new_component (gfc_symbol *type, gfc_expr
*e, gfc_symbol *add_data)
              && !e->symtree->n.sym->attr.elemental
              && !(e->value.function.isym
                   && (e->value.function.isym->pure
-                      || e->value.function.isym->elemental)))
+                      && e->value.function.isym->elemental)))
            /* Treat non-pure/non-elemental functions.  */
            check_add_new_comp_handle_array (e, type, add_data);
          else

Can you please elaborate?

I understood the code comment in the way that any pure or elemental
intrinsic should be handled in the else branch.  Or do you have
an example which is different?

The change to trans-decl.cc (fix of decl) looks fine for me.

Harald


m 04.07.25 um 13:43 schrieb Andre Vehreschild:
Hi all,

attached patch narrows the use of intrinsic functions in the caf accessor
down to pure elemental functions. This is needed because functions that get
extracted into the caf accessor routine, have no access to the source
image's memory. E.g. team_number() is marked as pure, but takes a pointer
argument to an object in the source image's memory, which is not available
on the remote image where the accessor is executed. This patch fixes that
and also corrects the type in the decl of the ABI of team_number. It is of
the opaque type team_type aka void* now and not integer as formerly
declared.

Regtest ok on x86_64-pc-linux-gnu / F41. Ok for mainline?

Regards,
        Andre

On Tue, 1 Jul 2025 12:54:49 -0700
Jerry D <jvdelis...@gmail.com> wrote:
On 7/1/25 12:51 PM, Harald Anlauf wrote:
Dear all,

the attached patch fixes the following minor issues found by running
f951 under valgrind for the just added new testcases coindexed_6.f90
and coindexed_7.f90:

- minor front-end memleaks with non-freed strings and lost GMP variables
    (these are simple and obvious fixes)

- an inconsistency between pure/elemental functions being either
    non-intrinsic or intrinsic.  Checking for the latter was likely missed
    from the beginning.

No new testcase.

Regtested on x86_64-pc-linux-gnu.  OK for mainline?

Thanks,
Harald

Yes, OK, straight-forward.

Thanks,

Jerry





Reply via email to