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,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 10.66.121.137 with SMTP id lk9mr20479557pab.11.1431367371666; Mon, 11 May 2015 11:02:51 -0700 (PDT) X-Received: by 10.182.165.70 with SMTP id yw6mr64209obb.17.1431367371585; Mon, 11 May 2015 11:02:51 -0700 (PDT) Path: buffer1.nntp.dca1.giganews.com!border1.nntp.dca1.giganews.com!nntp.giganews.com!m20no2036051iga.0!news-out.google.com!kd3ni14194igb.0!nntp.google.com!m20no10346710iga.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Mon, 11 May 2015 11:02:51 -0700 (PDT) Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=68.4.216.19; posting-account=JMw1jQoAAAA12VqnlnZDg7fuMc49R2Kv NNTP-Posting-Host: 68.4.216.19 User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <9ee472db-e51d-4e04-a5df-7bee793794a1@googlegroups.com> Subject: Interesting Array Initialization Code Gen [FSF GNAT 4.9.2] From: visaoni@gmail.com Injection-Date: Mon, 11 May 2015 18:02:51 +0000 Content-Type: text/plain; charset=ISO-8859-1 Xref: number.nntp.giganews.com comp.lang.ada:193121 Date: 2015-05-11T11:02:51-07:00 List-Id: Recently I was messing around with some large arrays and noticed something strange. Large arrays (allocated with new) cause a stack overflow when initialized with a function call. Another pair of eyes (thanks, Lucretia) was able to spot the issue. ----- procedure Main is function X( I : Integer ) return Integer is (I); type Arr is array (1..2**30) of Integer; type Arr_Ptr is access Arr; Q : Arr_Ptr := new Arr'(others => X(1)); begin null; end Main; ------ Interestingly this creates an array on the stack, initializes it, and then copies it into a newly allocated array. ----- procedure main is function main__x (i : integer) return integer; type main__arr is array (1 .. 16#4000_0000#) of integer; type main__arr_ptr is access main__arr; [type main__TarrB is array (1 .. 16#4000_0000# range <>) of integer] freeze main__TarrB [] [subtype main__T5b is main__TarrB (1 .. 16#4000_0000#)] A6b : main__T5b; for J7b in 1 .. 16#4000_0000# loop A6b (J7b) := main__x (1); end loop; q : main__arr_ptr := new main__arr'(A6b); function main__x (i : integer) return integer is begin return (i); end main__x; begin null; return; end main; ----- Furthermore, if you don't use a function, like so... ----- procedure Main is function X( I : Integer ) return Integer is (I); type Arr is array (1..2**30) of Integer; type Arr_Ptr is access Arr; Q : Arr_Ptr := new Arr'(others => 1); begin null; end Main; ----- You get something that seems more sensible, with no array on the stack and the allocated array initialized via pointer. ----- procedure main is function main__x (i : integer) return integer; type main__arr is array (1 .. 16#4000_0000#) of integer; type main__arr_ptr is access main__arr; [type main__TarrB is array (1 .. 16#4000_0000# range <>) of integer] freeze main__TarrB [] [subtype main__T5b is main__TarrB (1 .. 16#4000_0000#)] P6b : main__arr_ptr := new main__T5b; for J8b in 1 .. 16#4000_0000# loop main__T5b!(P6b.all) (J8b) := 1; end loop; q : main__arr_ptr := P6b; function main__x (i : integer) return integer is begin return (i); end main__x; begin null; return; end main; ----- Particularly in light of the second bit, the code gen for initialization by function seems incorrect. Or is this allowed somehow, even though it effectively means potentially large arrays can't be initialized by function? Also, GNAT GPL 2014 generates similar code but in both cases raises a storage error saying the object is too large.