comp.lang.ada
 help / color / mirror / Atom feed
* Derived types, private parts, abstract subprograms
@ 2004-03-08 20:31 Adam Beneschan
  2004-03-08 21:28 ` Robert I. Eachus
  2004-03-15 22:43 ` Adam Beneschan
  0 siblings, 2 replies; 4+ messages in thread
From: Adam Beneschan @ 2004-03-08 20:31 UTC (permalink / raw)


We believe we have found an error in some Ada source code that is
publicly available on the Internet, that isn't supposed to compile but
that some compilers apparently let slip through.  However, I wanted to
ask to make sure my interpretation of the RM is correct.

package pak1 is
   type T1 is abstract tagged null record;
   procedure Operation (X : T1) is abstract;
end pak1;

with pak1;
package pak2 is
   type T2 is new pak1.T1 with null record;
private
   procedure Operation (X : T2);
end pak2;

package pak3 is
   procedure Foo;
end pak3;

with pak2;
package body pak3 is
   type T3 is new pak2.T2 with null record;

   procedure Foo is
       X : T3;
   begin
      Operation (X);      --legal?
   end Foo;

end pak3;


As I interpret the RM: When T2 is declared, Operaton is inherited, but
the inherited subprogram is still abstract.  3.9.3(6) says that
Operation must be overridden with a nonabstract procedure, but that
the overriding may be done in the private part, which is what's done
here.

When T3 is declared, T2's primitive subprograms are inherited.  As I
understand it, this includes primitive subprograms of T2 that are
overridden, since those would reemerge in places where the overriding
subprogram isn't visible.  Is this correct in general for derived
types?  Thus, it would seem that T3 would inherit both the abstract
and the nonabstract versions of Operation from T2; but by 7.3.1(6),
the nonabstract version is not visible in places where pak2's private
part is not visible.  In this instance, the nonabstract inherited
version of Operation that operates on T3 is, in the language of
7.3.1(6), "not declared at all" and thus "cannot be named in a call"
(but still could be called indirectly with a dispatching call).  This
would seem to mean that the call with the "--legal?" comment cannot
name the nonabstract inherited Operation; however, the *abstract*
inherited Operation is still visible (reemerges?), and thus Operation
in this statement names this subprogram, but this makes the call
illegal because it's a nondispatching call on an abstract subprogram
(3.9.3(7)).

Is this all correct?

Is this the intent of the language?  It seems like it should be,
because declaring pak2.Operation in the private part of pak2 should
mean that you can't call it directly when the private part of pak2
isn't visible, even via a derived type.  But I want to make sure there
isn't any subtlety I've missed before I make a bug report.

Thanks in advance for any help,

                                      -- Adam



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Derived types, private parts, abstract subprograms
  2004-03-08 20:31 Derived types, private parts, abstract subprograms Adam Beneschan
@ 2004-03-08 21:28 ` Robert I. Eachus
  2004-03-15 22:43 ` Adam Beneschan
  1 sibling, 0 replies; 4+ messages in thread
From: Robert I. Eachus @ 2004-03-08 21:28 UTC (permalink / raw)


Adam Beneschan wrote:

> We believe we have found an error in some Ada source code that is
> publicly available on the Internet, that isn't supposed to compile but
> that some compilers apparently let slip through.  However, I wanted to
> ask to make sure my interpretation of the RM is correct.

I would suggest you send a bug report to the authors of the code, plus 
report this to Ada Comment.

Incidently, I think the code as written is correct.  Type T2 is not 
abstract, so types derived from it are not abstract types.  But this is 
one of those "interesting corner cases" which should at least be 
documented...

-- 
                                           Robert I. Eachus

"The only thing necessary for the triumph of evil is for good men to do 
nothing." --Edmund Burke




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Derived types, private parts, abstract subprograms
@ 2004-03-09  6:53 christoph.grein
  0 siblings, 0 replies; 4+ messages in thread
From: christoph.grein @ 2004-03-09  6:53 UTC (permalink / raw)
  To: comp.lang.ada

I amended your example a bit.

> package pak1 is
>    type T1 is abstract tagged null record;
>    procedure Operation (X : T1) is abstract;
> end pak1;
> 
> with pak1;
> package pak2 is
>    type T2 is new pak1.T1 with null record;
> private
>    procedure Operation (X : T2);
> end pak2;

with pak1;
package pak2P is
  type T2 is private;
private
  type T2 is new pak1.T1 with null record;
  procedure Operation (X : T2);
end pak2P;

> package pak3 is
>    procedure Foo;
> end pak3;
> 
> with pak2, pak2P;
> package body pak3 is
>    type T3 is new pak2.T2 with null record;
> 
>    procedure Foo is
>        X : T3;
         Y : pak2P.T;
>    begin
>       Operation (X);      --legal?  (yes, because T2 is visibly derived
                            -- from T1
        Operation (Y);      -- illegal (not visible, because T2 is not visibly
                            -- derived from T1
>    end Foo;
> 
> end pak3;

My interpretation is that it is irrelevant whether inherited primitives are 
overridden visibly or not if only the type is visibly derived.

It matters of course if the type is invisibly derived.

package P is
  type T is tagged ...
  procedure Prim (X: T; I: Integer := 5);
end P;
with P;
package P1 is
  type T1 is new P.T with ...
private
  procedure Prim (Y: T1; I: Integer := -5);
end P1;

In this example, Prim applied to a value of type T1 uses different default 
values for I depending on whether the overriding is visible or not. Also named 
association for the first parameter has to use different names.
And IMHO it's irrelevant whether the ancestor of Prim is abstract or not.

Thus:

with P1;
procedure M is  -- cannot see the private part
  Ob: P1.T1;
begin
  P1.Prim (X => Ob);  -- uses I => 5
end M;

procedure P1.M is  -- bodies of children see the private parts of parents
  Ob: P1.T1;
begin
  P1.Prim (Y => Ob);  -- uses I => -5
end P1.M;

Gnat 3.16a compiles this OK and uses the correct default, alas Apex 3.2.0b 
reports an error on parameter name Y and uses the wrong default.



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Derived types, private parts, abstract subprograms
  2004-03-08 20:31 Derived types, private parts, abstract subprograms Adam Beneschan
  2004-03-08 21:28 ` Robert I. Eachus
@ 2004-03-15 22:43 ` Adam Beneschan
  1 sibling, 0 replies; 4+ messages in thread
From: Adam Beneschan @ 2004-03-15 22:43 UTC (permalink / raw)


adam@irvine.com (Adam Beneschan) wrote in message news:<b4682ab7.0403081231.41281512@posting.google.com>...
> We believe we have found an error in some Ada source code that is
> publicly available on the Internet, that isn't supposed to compile but
> that some compilers apparently let slip through.  However, I wanted to
> ask to make sure my interpretation of the RM is correct.
> 
> package pak1 is
>    type T1 is abstract tagged null record;
>    procedure Operation (X : T1) is abstract;
> end pak1;
> 
> with pak1;
> package pak2 is
>    type T2 is new pak1.T1 with null record;
> private
>    procedure Operation (X : T2);
> end pak2;
> 
> package pak3 is
>    procedure Foo;
> end pak3;
> 
> with pak2;
> package body pak3 is
>    type T3 is new pak2.T2 with null record;
> 
>    procedure Foo is
>        X : T3;
>    begin
>       Operation (X);      --legal?
>    end Foo;
> 
> end pak3;
> 
> 
> As I interpret the RM: When T2 is declared, Operaton is inherited, but
> the inherited subprogram is still abstract.  3.9.3(6) says that
> Operation must be overridden with a nonabstract procedure, but that
> the overriding may be done in the private part, which is what's done
> here.
> 
> When T3 is declared, T2's primitive subprograms are inherited.  As I
> understand it, this includes primitive subprograms of T2 that are
> overridden, since those would reemerge in places where the overriding
> subprogram isn't visible.  Is this correct in general for derived
> types?  Thus, it would seem that T3 would inherit both the abstract
> and the nonabstract versions of Operation from T2; but by 7.3.1(6),
> the nonabstract version is not visible in places where pak2's private
> part is not visible.  In this instance, the nonabstract inherited
> version of Operation that operates on T3 is, in the language of
> 7.3.1(6), "not declared at all" and thus "cannot be named in a call"
> (but still could be called indirectly with a dispatching call).  This
> would seem to mean that the call with the "--legal?" comment cannot
> name the nonabstract inherited Operation; however, the *abstract*
> inherited Operation is still visible (reemerges?), and thus Operation
> in this statement names this subprogram, but this makes the call
> illegal because it's a nondispatching call on an abstract subprogram
> (3.9.3(7)).
> 
> Is this all correct?
> 
> Is this the intent of the language?  It seems like it should be,
> because declaring pak2.Operation in the private part of pak2 should
> mean that you can't call it directly when the private part of pak2
> isn't visible, even via a derived type.  But I want to make sure there
> isn't any subtlety I've missed before I make a bug report.

OK, I was wrong.  I forgot that there was a difference between tagged
and untagged types in regard to what happens when an inherited
primitive operation is overridden in the private part.  The biggest
mistake I made was that when I read 3.9.2(20), I mistakenly read "a
call on a dispatching operation" as "a dispatching call", which I
suppose is understandable but changes the meaning quite a bit.  Also,
Pascal Leroy pointed me to AI95-00228 which clarifies some issues
about what happens when an abstract subprogram is inherited.

The bottom line is that the call to Operation above *is* legal, and it
does execute the correct body even though the declaration for that
body appears in a place that is not visible.

                                  -- Adam



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2004-03-15 22:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-08 20:31 Derived types, private parts, abstract subprograms Adam Beneschan
2004-03-08 21:28 ` Robert I. Eachus
2004-03-15 22:43 ` Adam Beneschan
  -- strict thread matches above, loose matches on Subject: below --
2004-03-09  6:53 christoph.grein

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox