From patchwork Thu Mar 21 16:27:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikael Morin X-Patchwork-Id: 1914549 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=Q3o/JpC+; dkim=pass (2048-bit key; unprotected) header.d=wanadoo.fr header.i=@wanadoo.fr header.a=rsa-sha256 header.s=t20230301 header.b=kU4cThzY; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4V0rVw6Pmrz1yWs for ; Fri, 22 Mar 2024 03:28:40 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C7322385843A for ; Thu, 21 Mar 2024 16:28:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C7322385843A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1711038518; bh=BRI8AAFFUiXDzY0a5P+fYfd32U7t47pfAfUWLVtfeJg=; h=From:To:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From; b=Q3o/JpC+w1MBjwQ1WCrgwC7w94Df3yXD0cciz839OKua+slQWPAblWH+Om0T3vNG8 MJ0lOwTi/HsjKN0HnvUk8Vri/g5Z9WDLgA2lcijFRnjcAQhbDROl544MhOvplYj9wt TM+9aDMeKqrC3nmuHP2lMR0ceHO9HfKbrjANc/Ss= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from out.smtpout.orange.fr (out-18.smtpout.orange.fr [193.252.22.18]) by sourceware.org (Postfix) with ESMTPS id 5D7C93858D28; Thu, 21 Mar 2024 16:28:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5D7C93858D28 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=gcc.gnu.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 5D7C93858D28 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=193.252.22.18 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1711038486; cv=none; b=Q6ZxBCD9c4BMDKdjQFZLxEw8VdOOtOtaZiJG9otwHVOVoCH4qWPE4okV6lzAQa/uatRe3vsAxQlnZio975IPFm8LjxyyBRRUJt5uNtQ+QT+8kJthTHFnmu3ZqMleINmKmsMIGM9h1J5/eGqqxT9ZMn+vT0pulFAFzpbJl8hg6no= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1711038486; c=relaxed/simple; bh=Oak3nDDK3TskLSJg4+is6v62y+Rrvqz/bJ6WhwikWFA=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=P9WYJfGq3J5oRVjmOzEpnmNqSJccsR147eIZs+PXjarNRxxREfHEo+CC0SDvCxIE21Ac2+1JpkSo8X5/sUzXt4XX/spypEyMVvEaK5I8XSZ7Q2nQMRxHg1GOEd88V4sdxnnXTvv1AeqnU8Ry+dQeY9lTAvbEG61aXIuHoFTbD58= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from cyrano.home ([86.215.161.51]) by smtp.orange.fr with ESMTPA id nLGkrhTxekG4NnLGprrLkP; Thu, 21 Mar 2024 17:27:59 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=wanadoo.fr; s=t20230301; t=1711038480; bh=BRI8AAFFUiXDzY0a5P+fYfd32U7t47pfAfUWLVtfeJg=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=kU4cThzY2UGnScOZR/gYXzdpoWxzjcf6qbex5zlRaTzlO3BiXxy8YeofiKrFW2h0Y +N2vdpxCe76X+TgCXw8kJzuuU82VWPjl/wd7Fusnh32paQ/NYX0wsg4Lm/VbVCTKqr er7ChHd/EIjLqJ0nbYk88sjwfOX9KB+hzH5YjFJLCLR1tcmhvBhqBfpNqNAzXSxdN0 jKqOkhU35zA1mSfsIP0lpks67wSil+g+YE66S841TWSRq3rOCKGzQOFrkEGL5o/gYI iCNLh4nVQcbPt93CSIgU7zknvERhPLhSj61YI/ndLRo2kxIYSmFHZcb8OtggGt5UE3 3O4o/6NaQ6Fow== X-ME-Helo: cyrano.home X-ME-Auth: bW9yaW4tbWlrYWVsQG9yYW5nZS5mcg== X-ME-Date: Thu, 21 Mar 2024 17:28:00 +0100 X-ME-IP: 86.215.161.51 From: Mikael Morin To: fortran@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH] fortran: Ignore use statements on error [PR107426] Date: Thu, 21 Mar 2024 17:27:54 +0100 Message-ID: <20240321162754.1353561-1-mikael@gcc.gnu.org> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-Spam-Status: No, score=-10.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, FORGED_SPF_HELO, GIT_PATCH_0, JMQ_SPF_NEUTRAL, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_NEUTRAL, TXREP, URIBL_BLACK autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Hello, here is a fix for an ICE caused by dangling pointers to ISO_C_BINDING's C_PTR symbol in the global intrinsic symbol for C_LOC. I tried to fix it by making the intrinsic symbol use its own copy of C_PTR, but it regressed heavily. Instead, I propose this which is based on a patch I attached to the PR one year ago. It's sufficient to remove the access to freed memory. However, an underlying problem remains that successive use-associations of ISO_C_BINDING's symbols in different scopes cause the return type of the C_LOC global intrinsic symbol to be set to the C_PTR from each scope successively, with the last one "winning". Not very pretty. Anyway, there are two changed messages in the testsuite as a side-effect of the proposed change. I regard them as acceptable, albeit slightly worse. No regression otherwise on x86_64-pc-linux-gnu. Ok for 14 master? Mikael -- >8 -- This fixes an access to freed memory on the testcase from the PR. The problem comes from an invalid subroutine statement in an interface, which is ignored and causes the following statements forming the procedure body to be rejected. One of them use-associates the intrinsic ISO_C_BINDING module, which imports new symbols in a namespace that is freed at the time the statement is rejected. However, this creates dangling pointers as ISO_C_BINDING is special and its import creates a reference to the imported C_PTR symbol in the return type of the global intrinsic symbol for C_LOC (see the function create_intrinsic_function). This change saves and restores the list of use statements, so that rejected use statements are removed before they have a chance to be applied to the current namespace and create dangling pointers. PR fortran/107426 gcc/fortran/ChangeLog: * gfortran.h (gfc_save_module_list, gfc_restore_old_module_list): New declarations. * module.cc (old_module_list_tail): New global variable. (gfc_save_module_list, gfc_restore_old_module_list): New functions. (gfc_use_modules): Set module_list and old_module_list_tail. * parse.cc (next_statement): Save module_list before doing any work. (reject_statement): Restore module_list to its saved value. gcc/testsuite/ChangeLog: * gfortran.dg/pr89943_3.f90: Update error pattern. * gfortran.dg/pr89943_4.f90: Likewise. * gfortran.dg/use_31.f90: New test. --- gcc/fortran/gfortran.h | 2 ++ gcc/fortran/module.cc | 31 +++++++++++++++++++++++++ gcc/fortran/parse.cc | 4 ++++ gcc/testsuite/gfortran.dg/pr89943_3.f90 | 2 +- gcc/testsuite/gfortran.dg/pr89943_4.f90 | 2 +- gcc/testsuite/gfortran.dg/use_31.f90 | 25 ++++++++++++++++++++ 6 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/use_31.f90 diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index c7039730fad..fec7b53ff1a 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -3926,6 +3926,8 @@ void gfc_module_done_2 (void); void gfc_dump_module (const char *, int); bool gfc_check_symbol_access (gfc_symbol *); void gfc_free_use_stmts (gfc_use_list *); +void gfc_save_module_list (); +void gfc_restore_old_module_list (); const char *gfc_dt_lower_string (const char *); const char *gfc_dt_upper_string (const char *); diff --git a/gcc/fortran/module.cc b/gcc/fortran/module.cc index d1de53cbdb4..c565b84d61b 100644 --- a/gcc/fortran/module.cc +++ b/gcc/fortran/module.cc @@ -195,7 +195,12 @@ static const char *module_name; /* The name of the .smod file that the submodule will write to. */ static const char *submodule_name; +/* The list of use statements to apply to the current namespace + before parsing the non-use statements. */ static gfc_use_list *module_list; +/* The end of the MODULE_LIST list above at the time the recognition + of the current statement started. */ +static gfc_use_list **old_module_list_tail; /* If we're reading an intrinsic module, this is its ID. */ static intmod_id current_intmod; @@ -7561,6 +7566,8 @@ gfc_use_modules (void) gfc_use_module (module_list); free (module_list); } + module_list = NULL; + old_module_list_tail = &module_list; gfc_rename_list = NULL; } @@ -7584,6 +7591,30 @@ gfc_free_use_stmts (gfc_use_list *use_stmts) } +/* Remember the end of the MODULE_LIST list, so that the list can be restored + to its previous state if the current statement is erroneous. */ + +void +gfc_save_module_list () +{ + gfc_use_list **tail = &module_list; + while (*tail != NULL) + tail = &(*tail)->next; + old_module_list_tail = tail; +} + + +/* Restore the MODULE_LIST list to its previous value and free the use + statements that are no longer part of the list. */ + +void +gfc_restore_old_module_list () +{ + gfc_free_use_stmts (*old_module_list_tail); + *old_module_list_tail = NULL; +} + + void gfc_module_init_2 (void) { diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc index a2bf328f681..79c810c86ba 100644 --- a/gcc/fortran/parse.cc +++ b/gcc/fortran/parse.cc @@ -1800,6 +1800,7 @@ next_statement (void) locus old_locus; gfc_enforce_clean_symbol_state (); + gfc_save_module_list (); gfc_new_block = NULL; @@ -3104,6 +3105,9 @@ reject_statement (void) gfc_reject_data (gfc_current_ns); + /* Don't queue use-association of a module if we reject the use statement. */ + gfc_restore_old_module_list (); + gfc_new_block = NULL; gfc_undo_symbols (); gfc_clear_warning (); diff --git a/gcc/testsuite/gfortran.dg/pr89943_3.f90 b/gcc/testsuite/gfortran.dg/pr89943_3.f90 index 38b723e2458..84a9fb74741 100644 --- a/gcc/testsuite/gfortran.dg/pr89943_3.f90 +++ b/gcc/testsuite/gfortran.dg/pr89943_3.f90 @@ -22,7 +22,7 @@ submodule(Foo_mod) Foo_smod module subroutine runFoo4C(ndim) bind(C, name="runFu") ! { dg-error "Mismatch in BIND" } use, intrinsic :: iso_c_binding ! { dg-error "Unexpected USE statement" } implicit none ! { dg-error "Unexpected IMPLICIT NONE statement" } - integer(c_int32_t) , intent(in) :: ndim ! { dg-error "Unexpected data declaration" } + integer(c_int32_t) , intent(in) :: ndim ! { dg-error "Symbol 'c_int32_t' at .1. has no IMPLICIT type" } end subroutine runFoo4C ! { dg-error " Expecting END SUBMODULE" } end submodule Foo_smod diff --git a/gcc/testsuite/gfortran.dg/pr89943_4.f90 b/gcc/testsuite/gfortran.dg/pr89943_4.f90 index 8eba2eda171..cb955d01c88 100644 --- a/gcc/testsuite/gfortran.dg/pr89943_4.f90 +++ b/gcc/testsuite/gfortran.dg/pr89943_4.f90 @@ -23,7 +23,7 @@ submodule(Foo_mod) Foo_smod module function runFoo4C(ndim) bind(C, name="runFu") ! { dg-error "Mismatch in BIND" } use, intrinsic :: iso_c_binding ! { dg-error "Unexpected USE statement in" } implicit none ! { dg-error "Unexpected IMPLICIT NONE statement" } - integer(c_int32_t) , intent(in) :: ndim ! { dg-error "Unexpected data declaration" } + integer(c_int32_t) , intent(in) :: ndim ! { dg-error "Symbol 'c_int32_t' at .1. has no IMPLICIT type" } end function runFoo4C ! { dg-error "Expecting END SUBMODULE" } end submodule Foo_smod diff --git a/gcc/testsuite/gfortran.dg/use_31.f90 b/gcc/testsuite/gfortran.dg/use_31.f90 new file mode 100644 index 00000000000..818f2e30b09 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/use_31.f90 @@ -0,0 +1,25 @@ +! { dg-do compile } +! +! PR fortran/107426 +! This example used to generate an ICE, caused by the use stmt from the nested +! procedure declaration wrongly applying to the host procedure and overwriting +! the symbols there. +! +! Contributed by Gerhard Steinmetz + +module m +contains + subroutine p() bind(c) + use, intrinsic :: iso_c_binding + integer, target :: a = 1 + type(c_ptr) :: z + interface + subroutine s(x) bind(cc) ! { dg-error "Missing closing paren" } + use, intrinsic :: iso_c_binding ! { dg-error "Unexpected USE statement in INTERFACE block" } + integer(c_int), value :: x ! { dg-error "Parameter 'c_int' at .1. has not been declared" } + end ! { dg-error "END INTERFACE statement expected" } + end interface + z = c_loc(a) + call s(z) + end +end