From patchwork Thu Dec 8 02:14:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Kargl X-Patchwork-Id: 87186 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp627518qgi; Wed, 7 Dec 2016 18:15:13 -0800 (PST) X-Received: by 10.99.251.5 with SMTP id o5mr126334581pgh.152.1481163313702; Wed, 07 Dec 2016 18:15:13 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id s68si26498145plb.94.2016.12.07.18.15.13 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 07 Dec 2016 18:15:13 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-443751-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-443751-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-443751-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:reply-to:mime-version:content-type; q=dns; s=default; b=lDQif/fBcuaQY1cgHyJkW9K8HS3/+njj1jHWnRIY/Nx +i/4h8Jqx7FRFLPvyAT9D9AlI5k2JC/a8K4pLigR9zJfy459ce7E5b2YNmUymY04 S2KwY61+DmyyyG5aqqf47jyfROwGwoGu3qT8e3t1fSJmvt2YIeKXZdai1QLRZT4A = 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:date :from:to:subject:message-id:reply-to:mime-version:content-type; s=default; bh=0jVKivZEz6iHNwxSvTVnJ5LEhLA=; b=NcgFa8rN1BzGGhXPv 0RQPxolI/2drd27oWQ7j9hxs9ocuq8rKDkFCtKmhahBjlp0lwMW+7SAFFOtovHkh 7ojfkquexQx//+5W8WWNYh5HbmFr+dOkrUF362zwC1S6E3wKL6W0jHB0J9yTW6Yz VNR2tyA+kDB/50XddhfJNLMAg4= Received: (qmail 70508 invoked by alias); 8 Dec 2016 02:14:53 -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 70427 invoked by uid 89); 8 Dec 2016 02:14:52 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.0 required=5.0 tests=AWL, BAYES_00, KAM_ASCII_DIVIDERS, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=1167, IMPLICIT, gfc_copy_expr, bt_character X-Spam-User: qpsmtpd, 2 recipients X-HELO: troutmask.apl.washington.edu Received: from troutmask.apl.washington.edu (HELO troutmask.apl.washington.edu) (128.95.76.21) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 08 Dec 2016 02:14:42 +0000 Received: from troutmask.apl.washington.edu (localhost [127.0.0.1]) by troutmask.apl.washington.edu (8.15.2/8.15.2) with ESMTPS id uB82Eel2053356 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 7 Dec 2016 18:14:40 -0800 (PST) (envelope-from sgk@troutmask.apl.washington.edu) Received: (from sgk@localhost) by troutmask.apl.washington.edu (8.15.2/8.15.2/Submit) id uB82EYmr053355; Wed, 7 Dec 2016 18:14:34 -0800 (PST) (envelope-from sgk) Date: Wed, 7 Dec 2016 18:14:34 -0800 From: Steve Kargl To: fortran@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH] PR fortran/65173 -- kill off old_cl_list from gfc_namespace. Message-ID: <20161208021434.GA53267@troutmask.apl.washington.edu> Reply-To: kargl@uw.edu MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.6.1 (2016-04-27) All, The attach patch fixes an ICE from a testcase in PR fortran/65173. First, I draw your attention to the comment in gfortran.h above the definition of gfc_charlen. It is /* Character length structures hold the expression that gives the length of a character variable. We avoid putting these into gfc_typespec because doing so prevents us from doing structure copies and forces us to deallocate any typespecs we create, as well as structures that contain typespecs. They also can have multiple character typespecs pointing to them. These structures form a singly linked list within the current namespace and are deallocated with the namespace. It is possible to end up with gfc_charlen structures that have nothing pointing to them. */ The last paragraph is important, here. So, the problematic code was program foo type t character, allocatable :: z1(:), z1(:) end type t end program foo gfortran rightly rejected this code and issues an appropriate error. However, when parse.c (reject_statement) tries to cleanup the parsing of the invalid statement, it manages to corrupt the namespace's cl_list. How? Well, that's a good question on which I wasted too much time given the last paragraph in the gfortran.h comment. Removing the manipulations of the cl_list in reject_statement, then revealed that old_cl_list is unneeded. So, I give unto you 2016-12-07 Steven G. Kargl PR fortran/65173 * gfortran.h (gfc_namespace): Remove old_cl_list member. * parse.c (use_modules, next_statement): old_cl_list is gone. (clear_default_charlen): Remove no longer used function. (reject_statement): Do not try to clean up gfc_charlen structure(s) that may have been added to a cl_list list. * symbol.c (gfc_new_charlen): old_cl_list structure is gone. 2016-12-07 Steven G. Kargl PR fortran/65173 * gfortran.dg/misplaced_implicit_character.f90: Adjust errors. * gfortran.dg/pr65173.f90: New test. The patch is attached and regression tested on x86_64-*-freebsd. OK to commit? -- Steve Index: gcc/fortran/gfortran.h =================================================================== --- gcc/fortran/gfortran.h (revision 243376) +++ gcc/fortran/gfortran.h (working copy) @@ -1768,7 +1768,7 @@ typedef struct gfc_namespace /* !$ACC ROUTINE names. */ gfc_oacc_routine_name *oacc_routine_names; - gfc_charlen *cl_list, *old_cl_list; + gfc_charlen *cl_list; gfc_dt_list *derived_types; Index: gcc/fortran/parse.c =================================================================== --- gcc/fortran/parse.c (revision 243376) +++ gcc/fortran/parse.c (working copy) @@ -116,7 +116,6 @@ use_modules (void) gfc_pop_error (&old_error); gfc_commit_symbols (); gfc_warning_check (); - gfc_current_ns->old_cl_list = gfc_current_ns->cl_list; gfc_current_ns->old_equiv = gfc_current_ns->equiv; gfc_current_ns->old_data = gfc_current_ns->data; last_was_use_stmt = false; @@ -1386,7 +1385,6 @@ next_statement (void) gfc_new_block = NULL; - gfc_current_ns->old_cl_list = gfc_current_ns->cl_list; gfc_current_ns->old_equiv = gfc_current_ns->equiv; gfc_current_ns->old_data = gfc_current_ns->data; for (;;) @@ -2483,41 +2481,13 @@ accept_statement (gfc_statement st) } -/* Clear default character types with charlen pointers that are about - to become invalid. */ - -static void -clear_default_charlen (gfc_namespace *ns, const gfc_charlen *cl, - const gfc_charlen *end) -{ - gfc_typespec *ts; - - for (ts = &ns->default_type[0]; ts < &ns->default_type[GFC_LETTERS]; ts++) - if (ts->type == BT_CHARACTER) - { - const gfc_charlen *cl2; - for (cl2 = cl; cl2 != end; cl2 = cl2->next) - if (ts->u.cl == cl2) - { - ts->u.cl = NULL; - ts->type = BT_UNKNOWN; - break; - } - } -} - -/* Undo anything tentative that has been built for the current - statement. */ +/* Undo anything tentative that has been built for the current statement, + except if a gfc_charlen structure has been added to current namespace's + list of gfc_charlen structure. */ static void reject_statement (void) { - /* Revert to the previous charlen chain. */ - clear_default_charlen (gfc_current_ns, - gfc_current_ns->cl_list, gfc_current_ns->old_cl_list); - gfc_free_charlen (gfc_current_ns->cl_list, gfc_current_ns->old_cl_list); - gfc_current_ns->cl_list = gfc_current_ns->old_cl_list; - gfc_free_equiv_until (gfc_current_ns->equiv, gfc_current_ns->old_equiv); gfc_current_ns->equiv = gfc_current_ns->old_equiv; Index: gcc/fortran/symbol.c =================================================================== --- gcc/fortran/symbol.c (revision 243376) +++ gcc/fortran/symbol.c (working copy) @@ -3794,31 +3794,22 @@ gfc_charlen* gfc_new_charlen (gfc_namespace *ns, gfc_charlen *old_cl) { gfc_charlen *cl; + cl = gfc_get_charlen (); /* Copy old_cl. */ if (old_cl) { - /* Put into namespace, but don't allow reject_statement - to free it if old_cl is given. */ - gfc_charlen **prev = &ns->cl_list; - cl->next = ns->old_cl_list; - while (*prev != ns->old_cl_list) - prev = &(*prev)->next; - *prev = cl; - ns->old_cl_list = cl; cl->length = gfc_copy_expr (old_cl->length); cl->length_from_typespec = old_cl->length_from_typespec; cl->backend_decl = old_cl->backend_decl; cl->passed_length = old_cl->passed_length; cl->resolved = old_cl->resolved; } - else - { - /* Put into namespace. */ - cl->next = ns->cl_list; - ns->cl_list = cl; - } + + /* Put into namespace. */ + cl->next = ns->cl_list; + ns->cl_list = cl; return cl; } Index: gcc/testsuite/gfortran.dg/misplaced_implicit_character.f90 =================================================================== --- gcc/testsuite/gfortran.dg/misplaced_implicit_character.f90 (revision 243376) +++ gcc/testsuite/gfortran.dg/misplaced_implicit_character.f90 (working copy) @@ -3,6 +3,6 @@ subroutine s real x ! { dg-error "" } implicit character (a) ! { dg-error "IMPLICIT statement at .1. cannot follow data declaration statement at .2." } - - a1 = 'z' ! { dg-error "Symbol .a1. at .1. has no IMPLICIT type" } + x = 1 + a = 'a' end subroutine s Index: gcc/testsuite/gfortran.dg/pr65173.f90 =================================================================== --- gcc/testsuite/gfortran.dg/pr65173.f90 (nonexistent) +++ gcc/testsuite/gfortran.dg/pr65173.f90 (working copy) @@ -0,0 +1,7 @@ +! { dg-do compile } +program p + type t + character, allocatable :: z1(:), z1(:) ! { dg-error "already declared" } + end type +end +