From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED.Oh2LSLzxQ4+YU0Htrufc+A.user.gioia.aioe.org!not-for-mail From: Simon Wright Newsgroups: comp.lang.ada Subject: Containers, dangling references Date: Mon, 09 Mar 2020 16:43:55 +0000 Organization: Aioe.org NNTP Server Message-ID: NNTP-Posting-Host: Oh2LSLzxQ4+YU0Htrufc+A.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain X-Complaints-To: abuse@aioe.org User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (darwin) Cancel-Lock: sha1:hA4UROygzliUj21XCfRepSc3XD4= X-Notice: Filtered by postfilter v. 0.9.2 Xref: reader01.eternal-september.org comp.lang.ada:58181 Date: 2020-03-09T16:43:55+00:00 List-Id: I've been working on checking the upcoming FSF GCC 10 against existing projects. One case is a set of containers which include reference types (which, under the hood, support for example the "for all X of Y" iteration style). The original version of the code looked like type Reference_Type (Element : not null access Element_Type) is record Dummy : Integer := raise Program_Error with "uninitialized reference"; end record; (this is the full declaration; Dummy is there so that default initialization will raise PE, as required, e.g. ARM A.18.2(147.4)). function Reference (C :aliased in out Container; Position : in Cursor) return Reference_Type; with implementation function Reference (C : aliased in out Container; Position : in Cursor) return Reference_Type is pragma Unreferenced (C); begin return (Element => Position.The_Node.all.The_Element'Access, Dummy => 1); end Reference; which was fine with compilers up to FSF GCC 9, GNAT CE 2019. With GCC 10, we get references.adb:8:26: access discriminant in return aggregate would be a dangling reference I was a bit puzzled by the Position.The_Node.all.The_Element'Access - why the .all? It turns out that if you remove it, the compilers that were happy are no longer. Perhaps this was some circuitry in GNAT to suppress this error? How do the Ada.Containers manage this? It turns out that GNAT's version is more like return R : constant Reference_Type := (Element => Position.The_Node.The_Element'Access, Dummy => 1) do null; end return; and this is fine in GCC 10 (but if you put in the .all the error message returns). I found where the error message is raised[1], but it's hard to tell what the compiler is actually checking for. [1] https://github.com/gcc-mirror/gcc/blob/master/gcc/ada/sem_ch6.adb#L858