https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94419
Bug ID: 94419 Summary: accepting wrong programs because compiler error Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: ada Assignee: unassigned at gcc dot gnu.org Reporter: yyelle at rbx dot email Target Milestone: --- I'm currently studing Ada and using GCC and I found a number of bugs in compiler. It is about Ada 2012. Example buggy code is here: package A is type tp is private; -- tp here is considered constrained. Users of public part will see this only, they do not see unconstrained'ness of private defnition. type atp is access all tp; function ff1 return atp; function ff2 return atp; procedure pp1(p: atp); private type dd is range 1..10; type tarr is array(dd range <>) of Integer; type tp(x : dd := 10) is record -- tp here becomes considered unconstrained. a: tarr(1..x); end record; end A; package body A is xx : aliased tp; -- unconstrained yy : aliased tp(2); -- constrained zz : aliased tp(10); -- constrained. ax : aliased atp(10); -- access, constrained; function ff1 return atp is begin return yy'Access; -- Conversion from access to constrained to access unconstrained is errorneous because constrained partial view. Should be reported but does not by GNAT. end ff1; function ff2 return atp is begin return xx'Access; -- ok end ff2; procedure pp1(a : atp) is begin ax := a; -- conversion from unconstrained to constrained (and constraint match). Errorneous again. Should be reporrted, but GNAT doesn't report. a here will be xx. end; procedure pp2 is begin xx := ( x => 2, others => 0); ax.all := zz; -- No error by GNAT, but is errorneous. ax.all is xx. end; end A; -- User of A: with A; procedure Proc is begin A.ff1.all := A.ff2.all; -- No error reported, no error schould be reported, but it tries to change the discriminant of constrained variable (and alter the array size). Is bad. A.pp1(A.ff2); A.pp2; end; -- Ever more bad package B is type R is private; procedure pp; private type R(x: Integer := 1) is null record; end B; with Ada.Text_IO; use Ada.Text_IO; package body B is procedure pp is type A is access all R; type A1 is access all R(1); type A2 is access all R(2); xx : aliased R(1); yy : aliased R(2); zz : aliased R; aa1 : A1 := xx'Access; aa2 : A2 := yy'Access; begin Put_Line("xx.x = " & xx.x'Image); -- schould be 1 aa1.all := aa2.all; -- No error reported by GNAT. Put_Line("xx.x = " & xx.x'Image); -- 1 ? zz := xx; -- ok Put_Line("zz.x = " & zz.x'Image); -- 2. end pp; end B; -- The following is about accessibility with Ada.Text_IO; use Ada.Text_IO; procedure C is type R(ad : access Integer) is null record; a : access R; procedure inner is y: aliased integer := 0; begin a := new R'(ad => y'Access); end; -- y lifetime is ended. begin inner; Put_Line("a.ad = " & a.ad.all'Image); -- 0 Put_Line("a.ad = " & a.ad.all'Image); -- 32767 ? end; Please, note Ada is not C, Ada is about safety. A program should be checked for corectness and any errors must be reported almost always, at runtime also. There are also cases when checks would be too hard to implement, but those cases are relatively rare, they ever need more arguments, than implementation complexity. And there is no intent to go to what C language is, Ada is not C. Another bad thing in GNAT is implementation of "mutable" records, they always need maximum memory. It is from GNAT manual: type Rec (D : Positive := 15) is record Name : String (1..D); end record; Too_Large : Rec; is flagged by the compiler with a warning: an attempt to create `Too_Large' will raise `Storage_Error', because the required size includes `Positive'Last' bytes. It is bad. I think such records should be dynamically reallocatable. GNAT manual says that such way is improper, but it is not that, it is right. Name in example above may be allocated and reallocated "in free memory" and record itself contain address of Name. If, for example, Name are passed as an aliased parameter to a procedure, discriminant D schould not alter (while the parameter is in use), this stated by Ada rules (the result is ever "errorneous execution", which may be unpredictable). Also x.Name'Access will be error. Really I think there schould be some "representational aspect" to say using "max memory allocation" (as current implementation), or "dynamic realloc", and ever latter ("dynamic realloc") schould be default (in this example anyways). Rationale: above code does not work at all (because Storage_error) in current implementation, but it is one of Ada feautures.