diff mbox

[Fortran] PR fortran/38936: ASSOCIATE for derived-types and RFC

Message ID 4CB1A558.7070300@domob.eu
State New
Headers show

Commit Message

Daniel Kraft Oct. 10, 2010, 11:36 a.m. UTC
Hi all,

the attached (simple...) patch helps with ASSOCIATE to derived-types.
Namely, it allows to access components of associate-names with
derived-type targets in certain cases.  I hope that this covers a lot
(or most) of the real-world useful cases, but unfortunately it does not
do so for all possibilities (see the test-case change and the XFAIL'ed
new test for what it does and when it fails).

The problem is that in order to parse component references, we have to
know a symbol's typespec (the corresponding derived-type) during parse
time, but sometimes it is only evaluated during resolution what type the
associate-target has.  I do not see a good way to implement this
fully...  Two possible approaches come to mind:

* Somehow "combine" parsing and resolution such that for instance
certain stuff that is finished parsing can already be resolved (like the
definitions in the main program in associate_9 and the assocoiate-target
expressions) while before other parts of a compilation-unit are parsed
(in this case, the body of the ASSOCIATE).  This sounds very intrusive,
though, and we should probably discuss this in detail before trying
anything like it.  Or can we try to resolve just the few
associate-target expressions (gfc_resolve_expr) even though the "real"
resolution is done later?  But I guess we have to resolve things like
the called function symbols, interfaces, ... to make this work in the
general case.

* Adapt the parsing of component-references such that maybe first only
names as strings are parsed and accepted in any case, and they are
mapped to actual components and all that checked during resolution.
This sounds like the better of those two approaches to me, although it
is still quite intrusive.  And maybe this introduces some ambiguities in
parsing, when we no longer use the information whether something is a
derived-type or not?  (But off-hand, I do not see any such case right now.)

What do you think about that?  Anyways, this is probably a 4.7 item and
at most something to do on the branch only if at all in the near future.

The patch shows no regressions on x86_64-unknown-linux-gnu.  Ok for
trunk?  Note that I wanted to test also with the test-case from 45369,
but that uses CLASS(*) so I wasn't able to do so.

Yours,
Daniel

Comments

Tobias Burnus Oct. 10, 2010, 8:50 p.m. UTC | #1
Daniel Kraft wrote:
> The patch shows no regressions on x86_64-unknown-linux-gnu.  Ok for
> trunk?  Note that I wanted to test also with the test-case from 45369,
> but that uses CLASS(*) so I wasn't able to do so.

OK. Thanks for the patch. With regards to the corner case: I am not sure 
which is the best approach and I have think about it.

Tobias
Mikael Morin Oct. 10, 2010, 10:08 p.m. UTC | #2
Hello,

On Sunday 10 October 2010 13:36:56 Daniel Kraft wrote:
> Hi all,
> 
> the attached (simple...) patch helps with ASSOCIATE to derived-types.
> Namely, it allows to access components of associate-names with
> derived-type targets in certain cases.  I hope that this covers a lot
> (or most) of the real-world useful cases, but unfortunately it does not
> do so for all possibilities (see the test-case change and the XFAIL'ed
> new test for what it does and when it fails).
> 
> The problem is that in order to parse component references, we have to
> know a symbol's typespec (the corresponding derived-type) during parse
> time, but sometimes it is only evaluated during resolution what type the
> associate-target has.  I do not see a good way to implement this
> fully...  Two possible approaches come to mind:
> 
> * Somehow "combine" parsing and resolution such that for instance
> certain stuff that is finished parsing can already be resolved (like the
> definitions in the main program in associate_9 and the assocoiate-target
> expressions) while before other parts of a compilation-unit are parsed
> (in this case, the body of the ASSOCIATE).  This sounds very intrusive,
> though, and we should probably discuss this in detail before trying
> anything like it.  Or can we try to resolve just the few
> associate-target expressions (gfc_resolve_expr) even though the "real"
> resolution is done later?  But I guess we have to resolve things like
> the called function symbols, interfaces, ... to make this work in the
> general case.
I doubt this can work in the general case. Contained functions for example are 
going to be a problem as they can be used before they are defined. 

> 
> * Adapt the parsing of component-references such that maybe first only
> names as strings are parsed and accepted in any case, and they are
> mapped to actual components and all that checked during resolution.
> This sounds like the better of those two approaches to me, although it
> is still quite intrusive. 
I agree.

> And maybe this introduces some ambiguities in
> parsing, when we no longer use the information whether something is a
> derived-type or not?  (But off-hand, I do not see any such case right now.)
Well, I don't know; the code paths would be probably very different indeed.
Anyway, the parse time checks would have to be moved at resolution time, so 
the error reporting should not change that much from a user point of view.
As a general comment, I would say that for statements that are syntactically 
correct, but violate some constraints of the standard, we should emit an 
error, but not reject the statement as a whole. 
So, hem, back to your concern, hem, hem, well, hem, you'll see...

Mikael
Daniel Kraft Oct. 12, 2010, 1:38 p.m. UTC | #3
Tobias Burnus wrote:
>  Daniel Kraft wrote:
>> The patch shows no regressions on x86_64-unknown-linux-gnu.  Ok for
>> trunk?  Note that I wanted to test also with the test-case from 45369,
>> but that uses CLASS(*) so I wasn't able to do so.
> 
> OK. Thanks for the patch. With regards to the corner case: I am not sure 
> which is the best approach and I have think about it.

Committed as rev. 165378, including fixes for the typos found by 
Dominique as obvious (just added two " " as appropriate).

Thanks for the review!  I'll think about the corner cases, too, but this 
is surely nothing for this stage 1.

Yours,
Daniel
diff mbox

Patch

Index: gcc/fortran/parse.c
===================================================================
--- gcc/fortran/parse.c	(revision 165223)
+++ gcc/fortran/parse.c	(working copy)
@@ -3237,6 +3237,13 @@  parse_associate (void)
       sym->assoc = a;
       sym->declared_at = a->where;
       gfc_set_sym_referenced (sym);
+
+      /* Initialize the typespec.  It is not available in all cases,
+	 however, as it may only be set on the target during resolution.
+	 Still, sometimes it helps to have it right now -- especially
+	 for parsing component references on the associate-name
+	 in case of assication to a derived-type.  */
+      sym->ts = a->target->ts;
     }
 
   accept_statement (ST_ASSOCIATE);
Index: gcc/testsuite/gfortran.dg/associate_9.f03
===================================================================
--- gcc/testsuite/gfortran.dg/associate_9.f03	(revision 0)
+++ gcc/testsuite/gfortran.dg/associate_9.f03	(revision 0)
@@ -0,0 +1,51 @@ 
+! { dg-do compile }
+! { dg-options "-std=f2003 -fall-intrinsics" }
+
+! FIXME: Change into run test and remove excess error expectation.
+
+! PR fortran/38936
+! Association to derived-type, where the target type is not know
+! during parsing (only resolution).
+
+! Contributed by Daniel Kraft, d@domob.eu.
+
+MODULE m
+  IMPLICIT NONE
+
+  TYPE :: mynum
+    INTEGER :: comp
+  END TYPE mynum
+
+  INTERFACE OPERATOR(+)
+    MODULE PROCEDURE add
+  END INTERFACE OPERATOR(+)
+
+CONTAINS
+
+  PURE FUNCTION add (a, b)
+    TYPE(mynum), INTENT(IN) :: a, b
+    TYPE(mynum) :: add
+
+    add%comp = a%comp + b%comp
+  END FUNCTION add
+
+END MODULE m
+
+PROGRAM main
+  USE :: m
+  IMPLICIT NONE
+
+  TYPE(mynum) :: a
+  a = mynum (5)
+
+  ASSOCIATE (x => add (a, a))
+    IF (x%comp /= 10) CALL abort ()
+  END ASSOCIATE
+
+  ASSOCIATE (x => a + a)
+    IF (x%comp /= 10) CALL abort ()
+  END ASSOCIATE
+END PROGRAM main
+
+! { dg-excess-errors "Syntex error in IF" }
+! { dg-final { cleanup-modules "m" } }
Index: gcc/testsuite/gfortran.dg/associate_1.f03
===================================================================
--- gcc/testsuite/gfortran.dg/associate_1.f03	(revision 165223)
+++ gcc/testsuite/gfortran.dg/associate_1.f03	(working copy)
@@ -76,9 +76,10 @@  PROGRAM main
   ! Association to derived type and component.
   tp = myt (1)
   ASSOCIATE (x => tp, y => tp%comp)
-    ! FIXME: Parsing of derived-type associate names, tests with x.
+    IF (x%comp /= 1) CALL abort ()
     IF (y /= 1) CALL abort ()
     y = 5
+    IF (x%comp /= 5) CALL abort ()
   END ASSOCIATE
   IF (tp%comp /= 5) CALL abort ()