Bug 52832 - [F03] ASSOCIATE construct with proc-pointer selector is rejected
Summary: [F03] ASSOCIATE construct with proc-pointer selector is rejected
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Keywords: rejects-valid
Depends on:
Reported: 2012-04-02 09:58 UTC by Tobias Burnus
Modified: 2013-08-19 13:56 UTC (History)
1 user (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed: 2013-01-24 00:00:00


Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2012-04-02 09:58:09 UTC
Encountered when looking at PR 52729. I have not checked whether the following program is valid, but my feeling is that it is.

Currently, gfortran rejects it with:

    associate (k=>r)
Error: Expected association at (1)

  subroutine testSub()
    procedure(real), pointer :: r
    associate (k=>r)
    end associate
  end subroutine testSub
Comment 1 Tobias Burnus 2012-04-02 10:30:43 UTC
From Fortran 2008:

 R804  association  is  associate-name => selector
 R805  selector  is  expr
                 or  variable

 R602  variable  is  designator
                 or  expr
 R601  designator  is  object-name

and "expr" boils down to:

R701 primary  is  constant
              or  designator  ! See above
              or ...

Thus, it boils down to the question whether that's fulfilled for a procedure pointer.

Note that there such entries, which make me inclined that it is not valid:

R554 saved-entity  is  object-name
                   or  proc-pointer-name
R639 pointer-object  is  variable-name [or ...]
                     or  proc-pointer-name

Possible usage of proc-pointer selectors:
  associate(f => very%long%name%procptr)
    f => something  ! << usage as "variable"
    a = f(4) + f(7) * f(x) + ... ! << usage as "expr"
where the latter is more useful.

A quick test shows that ifort, pgf95 and crayftn accept proc-pointers in ASSOCIATE.
Comment 2 janus 2013-01-24 13:50:34 UTC
Here is a patch to accept the test case in comment 0:

Index: gcc/fortran/match.c
--- gcc/fortran/match.c	(revision 195411)
+++ gcc/fortran/match.c	(working copy)
@@ -1830,12 +1830,14 @@ gfc_match_associate (void)
       gfc_association_list* a;
       /* Match the next association.  */
+      gfc_matching_procptr_assignment = 1;
       if (gfc_match (" %n => %e", newAssoc->name, &newAssoc->target)
 	    != MATCH_YES)
 	  gfc_error ("Expected association at %C");
 	  goto assocListError;
+      gfc_matching_procptr_assignment = 0;
       newAssoc->where = gfc_current_locus;
       /* Check that the current name is not yet in the list.  */

I feels a bit like a hack and I'm not sure if it might break something (will regtest now).

Also, I haven't checked yet if anything more is needed for a full runtime test, where the associate symbol is actually used in some way.
Comment 3 janus 2013-01-24 14:52:48 UTC
(In reply to comment #2)
> Here is a patch to accept the test case in comment 0:

It fails on:
FAIL: gfortran.dg/associate_6.f03  -O  (test for excess errors)


  ASSOCIATE (arr => func (4))
Error: Expected ')' or ',' at (1)

Since we're fooling the parser to believe that we're matching a proc-ptr assignment, it does not swallow the parens after the function name (but expects a 'bare' function name as a proc-ptr target).

(I wonder whether we properly handle proc-ptr-valued functions as target in a proc-ptr assignment. Should check that ...)
Comment 4 janus 2013-08-19 13:56:18 UTC
(In reply to janus from comment #3)
> (I wonder whether we properly handle proc-ptr-valued functions as target in
> a proc-ptr assignment. Should check that ...)

Apparently this works, cf. PR 36704 etc. Not sure why it fails here.

One problem is of course that in an actual proc-ptr assignment, we can tell for sure that we're dealing with a proc-ptr assignment (because the lhs is declared as a procedure pointer), while in an ASSOCIATE statement we have no prior information on the identify of the lhs (but have to deduce it from the rhs).