From patchwork Mon Oct 4 08:47:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre-Marie de Rodat X-Patchwork-Id: 1536004 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.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=IdpuIYIW; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from 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 RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HNF8k0MyWz9t0k for ; Mon, 4 Oct 2021 20:02:14 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 89FF23858439 for ; Mon, 4 Oct 2021 09:02:11 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 89FF23858439 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1633338131; bh=qK8V5DHtZgqavlN2yNnTo7FR3uUfA6sPRQyspZM/mqU=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=IdpuIYIWIYBJ7p7fuRA+2iRAfhER01zxqVVgPIn0oi4bA+SRX8N8xpEUo4uLswhjg oUNqnzzJnE3ZYq44uzrEUwtSp5AxgrO340BrIlfN+IgOdntT1+L+GtjijDZelz1R6y g6/3OrFKelruSIYMIK3DvzVBA4Hz6vqV2QJMmRsY= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-lf1-x12b.google.com (mail-lf1-x12b.google.com [IPv6:2a00:1450:4864:20::12b]) by sourceware.org (Postfix) with ESMTPS id 1FA813858413 for ; Mon, 4 Oct 2021 08:48:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1FA813858413 Received: by mail-lf1-x12b.google.com with SMTP id y15so2667651lfk.7 for ; Mon, 04 Oct 2021 01:48:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition; bh=qK8V5DHtZgqavlN2yNnTo7FR3uUfA6sPRQyspZM/mqU=; b=y2xkHa1Xy7b96GN/Pacw6Kieb4AsFaoJN00dXfygJP4+831ccaPau5faW8S6S9xiNS atNCtKruy2Vy2iTsqnO16A2Pn7/RKFCNz/OYasyphSX/Kcz0AmboViEooT+BpVl/Buul wQxtoxuPpWeAiJNJuIcZ6vuV0cOQ5w1a4fjofdVxMLd0hi4UlkKoCLUR9AE00hhW+M2g RinjDvQCzXqqVAM/h3nFtrKIWY0iZnTgaQnORPwTSpHCcDZolGOJ2w61RzB56hkL/vxN pAkKF6Fe8enGQP5xdtTdoHzUzCAdTEe0ItUp3SbG9RPi+7dcGBFTsRYyZUoaZgg+fyCA IlqA== X-Gm-Message-State: AOAM530/meR8Mpkphy3HdSt/hrUW84C9EJsksZcIv7ddZk5xDUYmHeuE iqQrpCZP1jiaghWp4KVzXj8hJP1MbPFWlQ== X-Google-Smtp-Source: ABdhPJxDL+rPVlYq/AWgjO8KRiEvdZgfKNxgmnD4ZENvD2KjNXXT0oEjlmYT1zjiDWyMxJ1CUqEtXg== X-Received: by 2002:a19:6a16:: with SMTP id u22mr12713871lfu.254.1633337279025; Mon, 04 Oct 2021 01:47:59 -0700 (PDT) Received: from adacore.com ([2a02:2ab8:224:2ce:72b5:e8ff:feef:ee60]) by smtp.gmail.com with ESMTPSA id s11sm1550829ljc.80.2021.10.04.01.47.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Oct 2021 01:47:58 -0700 (PDT) Date: Mon, 4 Oct 2021 08:47:56 +0000 To: gcc-patches@gcc.gnu.org Subject: [Ada] Fix resolution of Declare_Expressions involving transient scopes Message-ID: <20211004084756.GA1536744@adacore.com> MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-13.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Pierre-Marie de Rodat via Gcc-patches From: Pierre-Marie de Rodat Reply-To: Pierre-Marie de Rodat Cc: Ed Schonberg Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" This patch modifies the resolution of Declare_Expressions to avoid the use of a fake scope to perform name capture in the expression, because such a scope (needed to analyze the declarations of the construct) conflicts with the transient scopes that may be generated by the presence of calls in the expression that may require finalization. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * sem_res.adb (Resolve_Declare_Expression): Use tree traversals to perform name capture of local entities in the expression of the construct. * exp_util.adb (Possible_Side_Effects_In_SPARK): Do not apply to the prefix of an attribute reference Reduce when that prefix is an aggregate, because it will be expanded into a loop, and has no identifiable type. diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb --- a/gcc/ada/exp_util.adb +++ b/gcc/ada/exp_util.adb @@ -11737,10 +11737,15 @@ package body Exp_Util is -- case and it is better not to make an additional one for the attribute -- itself, because the return type of many of them is universal integer, -- which is a very large type for a temporary. + -- The prefix of an attribute reference Reduce may be syntactically an + -- aggregate, but will be expanded into a loop, so no need to remove + -- side-effects. if Nkind (Exp) = N_Attribute_Reference and then Side_Effect_Free_Attribute (Attribute_Name (Exp)) and then Side_Effect_Free (Expressions (Exp), Name_Req, Variable_Ref) + and then (Attribute_Name (Exp) /= Name_Reduce + or else Nkind (Prefix (Exp)) /= N_Aggregate) and then not Is_Name_Reference (Prefix (Exp)) then Remove_Side_Effects (Prefix (Exp), Name_Req, Variable_Ref); diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb --- a/gcc/ada/sem_res.adb +++ b/gcc/ada/sem_res.adb @@ -7487,66 +7487,76 @@ package body Sem_Res is (N : Node_Id; Typ : Entity_Id) is - Decl : Node_Id; - Need_Transient_Scope : Boolean := False; - begin - -- Install the scope created for local declarations, if - -- any. The syntax allows a Declare_Expression with no - -- declarations, in analogy with block statements. - -- Note that that scope has no explicit declaration, but - -- appears as the scope of all entities declared therein. + Expr : constant Node_Id := Expression (N); - Decl := First (Actions (N)); - while Present (Decl) loop - exit when Nkind (Decl) - in N_Object_Declaration | N_Object_Renaming_Declaration; - Next (Decl); - end loop; + Decl : Node_Id; + Local : Entity_Id := Empty; - if Present (Decl) then + function Replace_Local (N : Node_Id) return Traverse_Result; + -- Use a tree traversal to replace each ocurrence of the name of + -- a local object declared in the construct, with the corresponding + -- entity. This replaces the usual way to perform name capture by + -- visibility, because it is not possible to place on the scope + -- stack the fake scope created for the analysis of the local + -- declarations; such a scope conflicts with the transient scopes + -- that may be generated if the expression includes function calls + -- requiring finalization. - -- Need to establish a transient scope in case Expression (N) - -- requires actions to be wrapped. + ------------------- + -- Replace_Local -- + ------------------- - declare - Node : Node_Id; - begin - Node := First (Actions (N)); - while Present (Node) loop - if Nkind (Node) = N_Object_Declaration - and then Requires_Transient_Scope - (Etype (Defining_Identifier (Node))) - then - Need_Transient_Scope := True; - exit; - end if; + function Replace_Local (N : Node_Id) return Traverse_Result is + begin + -- The identifier may be the prefix of a selected component, + -- but not a selector name, because the local entities do not + -- have a scope that can be named: a selected component whose + -- selector is a homonym of a local entity must denote some + -- global entity. + + if Nkind (N) = N_Identifier + and then Chars (N) = Chars (Local) + and then No (Entity (N)) + and then + (Nkind (Parent (N)) /= N_Selected_Component + or else N = Prefix (Parent (N))) + then + Set_Entity (N, Local); + Set_Etype (N, Etype (Local)); + end if; - Next (Node); - end loop; - end; + return OK; + end Replace_Local; - if Need_Transient_Scope then - Establish_Transient_Scope (Decl, Manage_Sec_Stack => True); - else - Push_Scope (Scope (Defining_Identifier (Decl))); + procedure Replace_Local_Ref is new Traverse_Proc (Replace_Local); + + -- Start of processing for Resolve_Declare_Expression + + begin + + Decl := First (Actions (N)); + + while Present (Decl) loop + if Nkind (Decl) in + N_Object_Declaration | N_Object_Renaming_Declaration + and then Comes_From_Source (Defining_Identifier (Decl)) + then + Local := Defining_Identifier (Decl); + Replace_Local_Ref (Expr); end if; - declare - E : Entity_Id := First_Entity (Current_Scope); - begin - while Present (E) loop - Set_Current_Entity (E); - Set_Is_Immediately_Visible (E); - Next_Entity (E); - end loop; - end; + Next (Decl); + end loop; - Resolve (Expression (N), Typ); - End_Scope; + -- The end of the declarative list is a freeze point for the + -- local declarations. - else - Resolve (Expression (N), Typ); + if Present (Local) then + Decl := Parent (Local); + Freeze_All (First_Entity (Scope (Local)), Decl); end if; + + Resolve (Expr, Typ); end Resolve_Declare_Expression; -----------------------------------------