From patchwork Tue Jun 15 10:20:51 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: 1492097 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 ozlabs.org (Postfix) with ESMTPS id 4G44Br6r3Tz9sTD for ; Tue, 15 Jun 2021 20:22:44 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 93602398B852 for ; Tue, 15 Jun 2021 10:22:42 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from rock.gnat.com (rock.gnat.com [205.232.38.15]) by sourceware.org (Postfix) with ESMTPS id 211BC398B173 for ; Tue, 15 Jun 2021 10:20:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 211BC398B173 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=adacore.com Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id DAE50117AE3; Tue, 15 Jun 2021 06:20:51 -0400 (EDT) X-Virus-Scanned: Debian amavisd-new at gnat.com Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id P38qVJyKKA5G; Tue, 15 Jun 2021 06:20:51 -0400 (EDT) Received: from tron.gnat.com (tron.gnat.com [IPv6:2620:20:4000:0:46a8:42ff:fe0e:e294]) by rock.gnat.com (Postfix) with ESMTP id C5BA9117985; Tue, 15 Jun 2021 06:20:51 -0400 (EDT) Received: by tron.gnat.com (Postfix, from userid 4862) id C34D31CA; Tue, 15 Jun 2021 06:20:51 -0400 (EDT) Date: Tue, 15 Jun 2021 06:20:51 -0400 From: Pierre-Marie de Rodat To: gcc-patches@gcc.gnu.org Subject: [Ada] Robust switching from incomplete to access types Message-ID: <20210615102051.GA1967@adacore.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: , Cc: Piotr Trojanek Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" When processing an access type declaration that completes an incomplete type, we now cleanly switch to a proper access type before setting the designated type. This simplifies the previous ad-hoc machinery for error recovery, which actually didn't work when the completion as an access type referenced an unknown subtype name. After cleaning code with transition from incomplete to access type, the Directly_Designated_Type field is only needed for access type entities. An access type declaration must be analysed before mutating the kind of the type entity from incomplete to access type. The analysis happens either directly in Analyse (which executed before mutating the kind) or indirectly in Process_Subtype (which was executed after mutating the kind). Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * sem_ch3.adb (Access_Type_Declaration): Add comments to explain the ordering of Mutate_Kind and Set_Directly_Designated_Type; remove temporary setting of Ekind to E_Access_Type for building _master objects, since now the Ekind is already set to its final value. Move repeated code into Setup_Access_Type routine and use it so that Process_Subtype is executed before mutating the kind of the type entity. * gen_il-gen-gen_entities.adb (Gen_Entities): Remove Directly_Designated_Type from E_Void, E_Private_Record, E_Limited_Private_Type and Incomplete_Kind; now it only belongs to Access_Kind entities. * sem_util.adb: Minor reformatting. diff --git a/gcc/ada/gen_il-gen-gen_entities.adb b/gcc/ada/gen_il-gen-gen_entities.adb --- a/gcc/ada/gen_il-gen-gen_entities.adb +++ b/gcc/ada/gen_il-gen-gen_entities.adb @@ -259,7 +259,6 @@ begin -- Gen_IL.Gen.Gen_Entities Sm (Corresponding_Remote_Type, Node_Id), Sm (CR_Discriminant, Node_Id), Sm (Debug_Renaming_Link, Node_Id), - Sm (Directly_Designated_Type, Node_Id), Sm (Discriminal_Link, Node_Id), Sm (Discriminant_Default_Value, Node_Id), Sm (Discriminant_Number, Uint), @@ -824,10 +823,7 @@ begin -- Gen_IL.Gen.Gen_Entities (Sm (Direct_Primitive_Operations, Elist_Id, Pre => "Is_Tagged_Type (N)"), Sm (Scalar_Range, Node_Id), - Sm (Scope_Depth_Value, Uint), - Sm (Directly_Designated_Type, Node_Id))); - -- ????Directly_Designated_Type was allowed to be Set_, but not get. - -- Same for E_Limited_Private_Type. And incomplete. + Sm (Scope_Depth_Value, Uint))); Cc (E_Private_Subtype, Private_Kind, (Sm (Direct_Primitive_Operations, Elist_Id, @@ -836,8 +832,7 @@ begin -- Gen_IL.Gen.Gen_Entities Cc (E_Limited_Private_Type, Private_Kind, (Sm (Scalar_Range, Node_Id), - Sm (Scope_Depth_Value, Uint), - Sm (Directly_Designated_Type, Node_Id))); + Sm (Scope_Depth_Value, Uint))); Cc (E_Limited_Private_Subtype, Private_Kind, (Sm (Scope_Depth_Value, Uint))); @@ -845,8 +840,7 @@ begin -- Gen_IL.Gen.Gen_Entities Ab (Incomplete_Kind, Incomplete_Or_Private_Kind, (Sm (Direct_Primitive_Operations, Elist_Id, Pre => "Is_Tagged_Type (N)"), - Sm (Non_Limited_View, Node_Id), - Sm (Directly_Designated_Type, Node_Id))); + Sm (Non_Limited_View, Node_Id))); Cc (E_Incomplete_Type, Incomplete_Kind, (Sm (Scalar_Range, Node_Id))); diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -1326,36 +1326,48 @@ package body Sem_Ch3 is ---------------------------- procedure Access_Type_Declaration (T : Entity_Id; Def : Node_Id) is + + procedure Setup_Access_Type (Desig_Typ : Entity_Id); + -- After type declaration is analysed with T being an incomplete type, + -- this routine will mutate the kind of T to the appropriate access type + -- and set its directly designated type to Desig_Typ. + + ----------------------- + -- Setup_Access_Type -- + ----------------------- + + procedure Setup_Access_Type (Desig_Typ : Entity_Id) is + begin + if All_Present (Def) or else Constant_Present (Def) then + Mutate_Ekind (T, E_General_Access_Type); + else + Mutate_Ekind (T, E_Access_Type); + end if; + + Set_Directly_Designated_Type (T, Desig_Typ); + end Setup_Access_Type; + + -- Local variables + P : constant Node_Id := Parent (Def); S : constant Node_Id := Subtype_Indication (Def); Full_Desig : Entity_Id; + -- Start of processing for Access_Type_Declaration + begin -- Check for permissible use of incomplete type if Nkind (S) /= N_Subtype_Indication then + Analyze (S); if Nkind (S) in N_Has_Entity and then Present (Entity (S)) and then Ekind (Root_Type (Entity (S))) = E_Incomplete_Type then - -- The following "if" prevents us from blowing up if the access - -- type is illegally completing something else. - - if T in E_Void_Id - | Access_Kind_Id - | E_Private_Type_Id - | E_Limited_Private_Type_Id - | Incomplete_Kind_Id - then - Set_Directly_Designated_Type (T, Entity (S)); - - else - pragma Assert (Error_Posted (T)); - return; - end if; + Setup_Access_Type (Desig_Typ => Entity (S)); -- If the designated type is a limited view, we cannot tell if -- the full view contains tasks, and there is no way to handle @@ -1366,13 +1378,12 @@ package body Sem_Ch3 is if From_Limited_With (Entity (S)) and then not Is_Class_Wide_Type (Entity (S)) then - Mutate_Ekind (T, E_Access_Type); Build_Master_Entity (T); Build_Master_Renaming (T); end if; else - Set_Directly_Designated_Type (T, Process_Subtype (S, P, T, 'P')); + Setup_Access_Type (Desig_Typ => Process_Subtype (S, P, T, 'P')); end if; -- If the access definition is of the form: ACCESS NOT NULL .. @@ -1404,14 +1415,7 @@ package body Sem_Ch3 is end if; else - Set_Directly_Designated_Type (T, - Process_Subtype (S, P, T, 'P')); - end if; - - if All_Present (Def) or Constant_Present (Def) then - Mutate_Ekind (T, E_General_Access_Type); - else - Mutate_Ekind (T, E_Access_Type); + Setup_Access_Type (Desig_Typ => Process_Subtype (S, P, T, 'P')); end if; if not Error_Posted (T) then diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -24441,10 +24441,10 @@ package body Sem_Util is (Chars (Related_Id), Suffix, Suffix_Index, Prefix)); begin - Mutate_Ekind (N, Kind); - Set_Is_Internal (N, True); - Append_Entity (N, Scope_Id); - Set_Public_Status (N); + Mutate_Ekind (N, Kind); + Set_Is_Internal (N, True); + Append_Entity (N, Scope_Id); + Set_Public_Status (N); if Kind in Type_Kind then Init_Size_Align (N);