From patchwork Thu Jan 2 11:41:22 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikael Morin X-Patchwork-Id: 306104 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id D78D22C00A3 for ; Thu, 2 Jan 2014 22:41:44 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=oPWFWIMLaa1AAOxLdLPjObDuB7rSjYKVwW+bUGpnRP7mRU OWZ1yiWU7ip35dSPwR1THslFBIiTA/aVs1TFiDJvTE1XfcV+s8tcb/dTobBEsHnw ZA58zim2kV1+VjGwE5/0orGWz6ctVF/fBChG0ICOvrifa2kvkY/QVcSArc5sQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=wUeJdxBvlNZGY1rzVG8aOrRrip0=; b=auF7EdJVgK1BpZFMCx2j r2ziYb/QquQv+nc1gg/iFTgXy/B5WMMM6/XeymehdaCLHwZK/6ITJIwohx7ieR6q 8PyhWc9mK1oPK6Bu6ePhgplG/iQ1J25nRMwz5GtchOhMQmhdRHumJmcoqMMARagA 6fisY9kmycQpgnSI8ha0Ph8= Received: (qmail 11544 invoked by alias); 2 Jan 2014 11:41:38 -0000 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 Received: (qmail 11525 invoked by uid 89); 2 Jan 2014 11:41:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: smtp22.services.sfr.fr Received: from smtp22.services.sfr.fr (HELO smtp22.services.sfr.fr) (93.17.128.12) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 02 Jan 2014 11:41:35 +0000 Received: from filter.sfr.fr (localhost [127.0.0.1]) by msfrf2213.sfr.fr (SMTP Server) with ESMTP id 822BA70001C8; Thu, 2 Jan 2014 12:41:33 +0100 (CET) Received: from linux-zkgi.site (12.183.72.86.rev.sfr.net [86.72.183.12]) by msfrf2213.sfr.fr (SMTP Server) with ESMTP id A96EA70001B9; Thu, 2 Jan 2014 12:41:32 +0100 (CET) X-SFR-UUID: 20140102114132694.A96EA70001B9@msfrf2213.sfr.fr Message-ID: <52C55062.3000809@sfr.fr> Date: Thu, 02 Jan 2014 12:41:22 +0100 From: Mikael Morin User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0 MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org, fortran@gcc.gnu.org Subject: [Patch, fortran] PR58007: unresolved fixup hell X-IsSubscribed: yes Hello, this patch fixes PR58007, where the compiler was not able to relate a component pointer to any loaded derived type symbol. The problem came from an optimization avoiding loading again a symbol which had already been loaded, skipping by the way the association of component pointers (if the symbol was a derived type) with the corresponding module indexes. The attached patch fixes this by reading the derived type symbol dump's component list and do the pointer<->integer association by hand. Then the regular on demand module loading code works properly and some code in mio_component_ref that was forcing the module loading of the containing derived type can be removed. To associate the component pointers with the module integers, one has to parse the symbol, or at least its components. It is done by hand in this patch and to reduce the maintainance burden (for possible future evolutions of symbol dumping format/content) the component list is moved at the beginning. More exactly just after the symbol attributes, because the check_for_ambiguous function relies on the symbol attributes appearing first in a symbol. This changes the module format, so MOD_VERSION is bumped. Regression tested on x86_64-unknown-linux-gnu. OK for trunk? I plan to submit a variant that doesn't change the module format for the branches (doing more parsing by hand). Mikael 2014-01-02 Mikael Morin PR fortran/58007 * module.c (MOD_VERSION): Bump. (fp2, find_pointer2): Remove. (mio_component_ref): Don't forcedfully set the containing derived type symbol for loading. (mio_symbol): Dump components earlier. (skip_list): New argument nest_level. Initialize level with the new argument. (read_module): Add forced pointer components association for derived type symbols. 2014-01-02 Mikael Morin PR fortran/58007 * gfortran.dg/unresolved_fixup_1.f90 diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c index 98e22df..20bf1ba 100644 --- a/gcc/fortran/module.c +++ b/gcc/fortran/module.c @@ -82,7 +82,7 @@ along with GCC; see the file COPYING3. If not see /* Don't put any single quote (') in MOD_VERSION, if you want it to be recognized. */ -#define MOD_VERSION "11" +#define MOD_VERSION "12" /* Structure that describes a position within a module file. */ @@ -390,37 +390,6 @@ get_integer (int integer) } -/* Recursive function to find a pointer within a tree by brute force. */ - -static pointer_info * -fp2 (pointer_info *p, const void *target) -{ - pointer_info *q; - - if (p == NULL) - return NULL; - - if (p->u.pointer == target) - return p; - - q = fp2 (p->left, target); - if (q != NULL) - return q; - - return fp2 (p->right, target); -} - - -/* During reading, find a pointer_info node from the pointer value. - This amounts to a brute-force search. */ - -static pointer_info * -find_pointer2 (void *p) -{ - return fp2 (pi_root, p); -} - - /* Resolve any fixups using a known pointer. */ static void @@ -2588,45 +2557,13 @@ mio_pointer_ref (void *gp) the namespace and is not loaded again. */ static void -mio_component_ref (gfc_component **cp, gfc_symbol *sym) +mio_component_ref (gfc_component **cp) { - char name[GFC_MAX_SYMBOL_LEN + 1]; - gfc_component *q; pointer_info *p; p = mio_pointer_ref (cp); if (p->type == P_UNKNOWN) p->type = P_COMPONENT; - - if (iomode == IO_OUTPUT) - mio_pool_string (&(*cp)->name); - else - { - mio_internal_string (name); - - if (sym && sym->attr.is_class) - sym = sym->components->ts.u.derived; - - /* It can happen that a component reference can be read before the - associated derived type symbol has been loaded. Return now and - wait for a later iteration of load_needed. */ - if (sym == NULL) - return; - - if (sym->components != NULL && p->u.pointer == NULL) - { - /* Symbol already loaded, so search by name. */ - q = gfc_find_component (sym, name, true, true); - - if (q) - associate_integer_pointer (p, q); - } - - /* Make sure this symbol will eventually be loaded. */ - p = find_pointer2 (sym); - if (p->u.rsym.state == UNUSED) - p->u.rsym.state = NEEDED; - } } @@ -2983,7 +2920,7 @@ mio_ref (gfc_ref **rp) case REF_COMPONENT: mio_symbol_ref (&r->u.c.sym); - mio_component_ref (&r->u.c.component, r->u.c.sym); + mio_component_ref (&r->u.c.component); break; case REF_SUBSTRING: @@ -3865,6 +3802,14 @@ mio_symbol (gfc_symbol *sym) mio_lparen (); mio_symbol_attribute (&sym->attr); + + /* Note that components are always saved, even if they are supposed + to be private. Component access is checked during searching. */ + mio_component_list (&sym->components, sym->attr.vtype); + if (sym->components != NULL) + sym->component_access + = MIO_NAME (gfc_access) (sym->component_access, access_types); + mio_typespec (&sym->ts); if (sym->ts.type == BT_CLASS) sym->attr.class_ok = 1; @@ -3893,15 +3838,6 @@ mio_symbol (gfc_symbol *sym) if (sym->attr.cray_pointee) mio_symbol_ref (&sym->cp_pointer); - /* Note that components are always saved, even if they are supposed - to be private. Component access is checked during searching. */ - - mio_component_list (&sym->components, sym->attr.vtype); - - if (sym->components != NULL) - sym->component_access - = MIO_NAME (gfc_access) (sym->component_access, access_types); - /* Load/save the f2k_derived namespace of a derived-type symbol. */ mio_full_f2k_derived (sym); @@ -4000,11 +3936,11 @@ find_symbol (gfc_symtree *st, const char *name, /* Skip a list between balanced left and right parens. */ static void -skip_list (void) +skip_list (int nest_level = 0) { int level; - level = 0; + level = nest_level; do { switch (parse_atom ()) @@ -4638,7 +4574,6 @@ read_module (void) info->u.rsym.ns = atom_int; get_module_locus (&info->u.rsym.where); - skip_list (); /* See if the symbol has already been loaded by a previous module. If so, we reference the existing symbol and prevent it from @@ -4649,10 +4584,44 @@ read_module (void) if (sym == NULL || (sym->attr.flavor == FL_VARIABLE && info->u.rsym.ns !=1)) - continue; + { + skip_list (); + continue; + } info->u.rsym.state = USED; info->u.rsym.sym = sym; + /* The current symbol has already been loaded, so we can avoid loading + it again. However, if it is a derived type, some of its components + can be used in expressions in the module. To avoid the module loading + failing, we need to associate the module's component pointer indexes + with the existing symbol's component pointers. */ + if (sym->attr.flavor == FL_DERIVED) + { + gfc_component *c; + + mio_lparen (); /* symbol opening. */ + skip_list (); /* skip symbol attribute. */ + + mio_lparen (); /* component list opening. */ + for (c = sym->components; c; c = c->next) + { + pointer_info *p; + int n; + + mio_lparen (); /* component opening. */ + mio_integer (&n); + p = get_integer (n); + if (p->u.pointer == NULL) + associate_integer_pointer (p, c); + skip_list (1); /* component end. */ + } + mio_rparen (); /* component list closing. */ + + skip_list (1); /* symbol end. */ + } + else + skip_list (); /* Some symbols do not have a namespace (eg. formal arguments), so the automatic "unique symtree" mechanism must be suppressed