https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124310

            Bug ID: 124310
           Summary: incorrect accessibility levels in expressions
           Product: gcc
           Version: 15.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: ada
          Assignee: unassigned at gcc dot gnu.org
          Reporter: liam at liampwll dot com
                CC: dkm at gcc dot gnu.org
  Target Milestone: ---

This was not discovered in a real program but was instead discovered when
reading the section of RM22 on accessibility levels (3.10.2) and then trying to
use GNAT to confirm my understanding. GNAT does not agree with my
understanding, however I believe this is a GNAT bug rather than a hole in my
understanding or a hole in the RM.

Take the below program:

    with Ada.Text_IO; use Ada.Text_IO;
    with Ada.Containers.Ordered_Maps;

    procedure Example is
       type R is record
          X : aliased Integer;
       end record;

       package R_Maps is new Ada.Containers.Ordered_Maps (Positive, R);
       M : R_Maps.Map := [1 => (X => 1)];

       type Integer_Access is access all Integer;
       A : Integer_Access := M (1).X'Access;
       --  An explicit `.Element` also triggers the bug.
    begin
       Put_Line (A.all'Image);
       M.Clear;
       Put_Line (A.all'Image);
       M.Insert (1, R'(X => 2));
       Put_Line (A.all'Image);
    end Example;

This will show a use-after-free when running with Valgrind. Notably this
program is accepted both when using No_Dynamic_Accessibility_Checks and when
not using it.

This program should not be accepted by a conforming Ada compiler for the
following reasons:

RM22 7.6.1(3/5) states that "... in the case of the execution of a master
construct: a body other than a package_body; a statement; or an expression ..."

The initialiser for A here is an expression.

RM22 3.10.2(18/5) states that "For a master construct that is statically nested
within another master construct, the accessibility level of the inner master
construct is statically deeper than that of the outer master construct."

This means that the accessibility level of initialiser for A is deeper than the
declarative region of Example.

RM22 3.10.2(12.5/3) states that "The accessibility level of the anonymous
access type of an access discriminant in any other context is that of the
enclosing object."

The enclosing object here is the temporary Reference_Type object created within
the initialiser of A, therefore the accessibility level of the temporary
Reference_Type object is that of the initialiser of A.

RM22 4.1.5(6/3) states that "A generalized_reference denotes a view equivalent
to that of a dereference of the reference discriminant of the reference
object."

RM22 3.10.2(28/3) states in regards to X'Access that "The accessibility level
of the view shall not be statically deeper than that of the access type A."

Therefore the assignment should be invalid.

Reply via email to