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=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,ee82e0a06c8bbead X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Received: by 10.68.227.230 with SMTP id sd6mr1606720pbc.8.1333806930190; Sat, 07 Apr 2012 06:55:30 -0700 (PDT) Path: r9ni29172pbh.0!nntp.google.com!news2.google.com!newsfeed2.dallas1.level3.net!newsfeed3.dallas1.level3.net!news.level3.com!bloom-beacon.mit.edu!newsswitch.lcs.mit.edu!nntp.TheWorld.com!.POSTED!not-for-mail From: Robert A Duff Newsgroups: comp.lang.ada Subject: Re: A Gnother Gnasty bug Date: Sat, 07 Apr 2012 09:55:29 -0400 Organization: The World Public Access UNIX, Brookline, MA Message-ID: References: <22193583.1528.1333759470339.JavaMail.geo-discussion-forums@vbdn7> <87mx6nvlwo.fsf@ludovic-brenta.org> NNTP-Posting-Host: shell01.theworld.com Mime-Version: 1.0 X-Trace: pcls6.std.com 1333806929 11665 192.74.137.71 (7 Apr 2012 13:55:29 GMT) X-Complaints-To: abuse@TheWorld.com NNTP-Posting-Date: Sat, 7 Apr 2012 13:55:29 +0000 (UTC) User-Agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.3 (irix) Cancel-Lock: sha1:6NvAAIesvVyLAslUR2P0y/hFqqI= Content-Type: text/plain; charset=us-ascii Date: 2012-04-07T09:55:29-04:00 List-Id: Ludovic Brenta writes: > sbelmont700@gmail.com writes: >> new I'class'(F(arg=> 42))))); > > I don't think that's legal. I didn't look at the original post, but I think it's legal. >...You can have a class-wide access value but > not an allocator for a class-wide type because the allocator doesn't > know how much memory to allocate: It knows how much to allocate from the initial value. It's UNinitialized allocators (and uninitialized object declarations) that are illegal when the type is indefinite. It also needs to know the alignment, which it can get from the 'Tag of the initial value. >> 4.8(4): An initialized allocator is an allocator with a >> qualified_expression. [...] > > Your allocator is initialized because it has a qualified_expression. Right, and that's why it's legal. > The type designatd by your qualified_expression is class-wide, it is > therefore impossible for the allocator to create the object. There are at least two ways to implement it: Call F(42), putting the result in a temp. Call Allocate with the size and alignment of that temp. Copy the temp into the newly-allocated object, with adjustment/finalization if controlled. Call F, passing it a hidden thunk, which does the allocation. At the point where F does "return", call the thunk, passing this size and alignment. Store the result of F at the address returned by the thunk. If the designated type is limited, the second way is necessary, because the first way won't work (it involves a copy, which won't work for limited types). In this example, the type is nonlimited, so either method works. GNAT currently uses the first, but might someday use the second for better efficiency (avoiding the copy, if it's big, and avoiding adjust/fin) in some cases. > with Ada.Finalization; > procedure T is > > type B is new Ada.Finalization.Controlled with record > D : Integer; > end record; > > type Access_B is access B'Class; > > > function F return B'Class is > begin > return B'(Ada.Finalization.Controlled with D => 42); > end F; > > J : Access_B := new B'Class'(Ada.Finalization.Controlled with D => 42); -- Line 16 This is illegal because the expected type for an aggregate cannot be class-wide. Otherwise, how would it know what 'Tag to use, and how would it know whether you've obeyed the full coverage rule? This is a property of aggregates, whether or not "new" is involved. If F said "return B'Class'(...)" instead of "return B'(...)", then that would be illegal, too. In general, for aggregates, the compiler does NOT determine the type (or the 'Tag) by looking inside the aggregate. It does NOT say, hmm, let's find a type derived from Controlled that happens to have a component D of some integer type. Instead, this information must come from the context. > K : Access_B := new B'Class'(F); -- Line 17: Not diagnosed Here, there's no aggregate. This is legal. > gnatmake -gnatwa t > gcc-4.6 -c -gnatwa t.adb > t.adb:16:32: expected type "B'Class" defined at line 4 > t.adb:16:32: found a composite type GNAT is correct here. - Bob