• Is this legal?

    From Simon Belmont@21:1/5 to All on Sat Oct 16 12:00:18 2021
    I'm trying to learn the 2012 changes to accessibility rules, e.g. aliased parameters, additional dynamics checks, and some eliminated unnecessary typecasts. But I am also aware of the....fluid nature of GNATs correctness of implementing them, and the
    following situation seems dubious. In particular, when 'current' is an anonymous access type, it compiles without issue, but not when it's a named access type (or when explicitly converted to one). Does anyone know off hand which is the correct
    behavior?

    Thanks
    -sb

    procedure Main is

    subtype str5 is string(1..5);
    type s5_ptr is access all str5;

    type T is
    record
    current : access str5;
    --current : s5_ptr; -- "aliased actual has wrong accessibility"
    foo : aliased str5;
    end record;

    function F (y : aliased in out str5) return access str5 is
    begin
    return y'Access;
    end F;


    procedure P (x : in out T) is
    begin
    x.current := F(x.foo);
    end P;

    o : T := (current => null, foo => "Hello");

    begin
    P(o);
    end Main;

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From AdaMagica@21:1/5 to All on Sun Oct 17 01:41:15 2021
    procedure Main is

    subtype str5 is string(1..5);
    type s5_ptr is access all str5;

    Ptr: s5_ptr;

    type T is
    record
    --current : access str5;
    current : s5_ptr; -- "aliased actual has wrong accessibility"
    foo : aliased str5;
    end record;

    The accessibility rules are far too complicated and unreadable (I'm not about trying to grock them), but the component current has a type that has a lifetime as long as Main. Your object o may be declared in an inner scope with less lifetime. Thus the
    assignment must be illegal.

    begin
    declare
    o : T := (Acurrent => null, --Ncurrent => null,
    foo => "Hello");
    begin
    P (o);
    --Ptr := o.Ncurrent; -- global point to disappearing object
    Ptr := o.Acurrent; -- global point to disappearing object
    end;
    put_line(Ptr.all); -- prints Hello
    end Main;

    But it occurs to me that GNAT CE 2021 has a problem here. (Comment out all occurrences of Ncurrent.)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gautier write-only address@21:1/5 to All on Sun Oct 17 01:35:22 2021
    For information, ObjectAda v.10.2 accepts both variants (in Ada 2012 mode).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Simon Belmont@21:1/5 to AdaMagica on Sun Oct 17 11:31:23 2021
    On Sunday, October 17, 2021 at 4:41:17 AM UTC-4, AdaMagica wrote:

    The accessibility rules are far too complicated and unreadable (I'm not about trying to grock them), but the component current has a type that has a lifetime as long as Main. Your object o may be declared in an inner scope with less lifetime. Thus the
    assignment must be illegal.

    I only ask because there are two rules, one that says the scope of the object must be *statically* deeper than the return type of the function to be legal, but then another similar one down the page that says a runtime check is made to ensure it (which
    begs the question of why the runtime check is needed if it must be done statically). Normally things like that are for edge cases with anonymous access types, so it's not immediately obvious (to me, at least) if GNAT is blowing the static check or the
    dynamic check (Or both? Or neither?)

    6.4.1~6.3/3
    In a function call, the accessibility level of the actual object for each explicitly aliased parameter shall not be statically deeper than the accessibility level of the master of the call (see 3.10.2).

    6.4.1~15.1/3
    In a function call, for each explicitly aliased parameter, a check is made that the accessibility level of the master of the actual object is not deeper than that of the master of the call (see 3.10.2).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From AdaMagica@21:1/5 to All on Mon Oct 18 03:50:27 2021
    may be the code is legal, but definitly dynamic accessibility checks should be present (which must fail in the last example)..

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Randy Brukardt@21:1/5 to All on Mon Oct 18 22:50:52 2021
    "Simon Belmont" <sbelmont700@gmail.com> wrote in message news:6c49980a-fe55-4cea-a356-d021b417d942n@googlegroups.com...
    I'm trying to learn the 2012 changes to accessibility rules, ...
    ...
    Does anyone know off hand which is the correct behavior?

    I can assure you that no one anywhere will *ever* know "off-hand" the
    correct behavior. :-) It takes quite a bit of looking to be sure.

    ...
    ...
    function F (y : aliased in out str5) return access str5 is
    begin
    return y'Access;
    end F;

    This is always legal (we hope :-). There should be a static (or dynamic)
    check on Y when F is called that Y has an appropriate lifetime for the
    result. (I can't grok "accessibility", either. I always think in terms of lifetimes, and then try to translate to the wording.)

    procedure P (x : in out T) is
    begin
    x.current := F(x.foo);
    end P;

    This should always be statically illegal. X here has the lifetime of P (as
    the actual lifetime is unknown). That's not long enough regardless of how
    you declare Current (since it's type is necessarily outside of P). There is
    no special accessibility rules for anonymous access components (unlike most other cases); they always have the accessibility (think lifetime) of the enclosing type.

    My understanding is that AdaCore has been actively working on
    re-implementing these rules correctly, and in a few cases we've changed the rules as it was obvious that a better rule was possible (so Ada 2022 changes this some more). But none of the Ada 2022 changes should change this
    example.

    Randy.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)