From patchwork Sun Oct 10 11:36:56 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Kraft X-Patchwork-Id: 67346 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 76E00B7043 for ; Sun, 10 Oct 2010 22:31:15 +1100 (EST) Received: (qmail 19153 invoked by alias); 10 Oct 2010 11:31:13 -0000 Received: (qmail 19139 invoked by uid 22791); 10 Oct 2010 11:31:11 -0000 X-SWARE-Spam-Status: No, hits=-2.7 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from tatiana.utanet.at (HELO tatiana.utanet.at) (213.90.36.46) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 10 Oct 2010 11:31:05 +0000 Received: from patricia.xoc.tele2net.at ([213.90.36.9]) by tatiana.utanet.at with esmtp (Exim 4.71) (envelope-from ) id 1P4u7K-0004Gm-H5; Sun, 10 Oct 2010 13:31:02 +0200 Received: from d91-128-60-43.cust.tele2.at ([91.128.60.43] helo=[10.0.0.18]) by patricia.xoc.tele2net.at with esmtpa (Exim 4.71) (envelope-from ) id 1P4u7K-0005qi-Cu; Sun, 10 Oct 2010 13:31:02 +0200 Message-ID: <4CB1A558.7070300@domob.eu> Date: Sun, 10 Oct 2010 13:36:56 +0200 From: Daniel Kraft User-Agent: Thunderbird 2.0.0.0 (X11/20070425) MIME-Version: 1.0 To: Fortran List , gcc-patches Subject: [Patch, Fortran] PR fortran/38936: ASSOCIATE for derived-types and RFC Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 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 ()