https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54262

--- Comment #3 from Dominique d'Humieres <dominiq at lps dot ens.fr> ---
> The code in comment 0 compiles with 4.8.5, but gives an error
>
>    p = transfer (loc(x), p)
>                     1
> Error: Assumed-type argument at (1) is not permitted as actual argument
> to the intrinsic loc

LOC is a GNU extension and it is a matter of choice to accept or reject it in
gfortran.

If the choice is to reject it, then this PR should be closed as INVALID.

With the following patch

--- ../_clean/gcc/fortran/intrinsic.c   2019-03-12 16:12:35.000000000 +0100
+++ gcc/fortran/intrinsic.c     2019-03-20 23:03:17.000000000 +0100
@@ -212,7 +212,8 @@ do_ts29113_check (gfc_intrinsic_sym *spe
               && specific->id != GFC_ISYM_SIZEOF
               && specific->id != GFC_ISYM_UBOUND
               && specific->id != GFC_ISYM_IS_CONTIGUOUS
-              && specific->id != GFC_ISYM_C_LOC)
+              && specific->id != GFC_ISYM_C_LOC
+              && specific->id != GFC_ISYM_LOC)
        {
          gfc_error ("Assumed-type argument at %L is not permitted as actual"
                     " argument to the intrinsic %s", &a->expr->where,

the modified test with

  type(*), target, CONTIGUOUS :: x(:) ! or x(:)

is accepted, but the original test is rejected with

    5 |   p = transfer (loc(x), p)
      |                    1
Error: Assumed-rank argument at (1) is only permitted as actual argument to
intrinsic inquiry functions

So far I did not find what to change to make specific->inquiry true for LOC. 
Again as it is an extension, it is not an "intrinsic inquiry function" 
as defined by the standard.

While looking at trans-intrinsic.c, I see in gfc_conv_intrinsic_loc

  /* Create a temporary variable for loc return value.  Without this,
     we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1).  */
  temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
  gfc_add_modify (&se->pre, temp_var, se->expr);
  se->expr = temp_var;

and in conv_isocbinding_function

      /* TODO -- the following two lines shouldn't be necessary, but if
         they're removed, a bug is exposed later in the code path.
         This workaround was thus introduced, but will have to be
         removed; please see PR 35150 for details about the issue.  */
      se->expr = convert (pvoid_type_node, se->expr);
      se->expr = gfc_evaluate_now (se->expr, &se->pre);

These pieces of code look more as empirical hacks than as solid codes.

Reply via email to