comp.lang.ada
 help / color / mirror / Atom feed
From: Simon Wright <simon@pushface.org>
Subject: Re: Class wide preconditions: error in GNAT implementation?
Date: Sat, 16 Feb 2013 20:23:32 +0000
Date: 2013-02-16T20:23:32+00:00	[thread overview]
Message-ID: <lyhalcqa7v.fsf@pushface.org> (raw)
In-Reply-To: kfmlq1$puv$1@munin.nbi.dk

"Randy Brukardt" <randy@rrsoftware.com> writes:

> OTOH, I didn't realize that you had a dispatching call. In that case,
> the precondition is supposed to just be the Pre'Class for A, which is
> stronger that A or B which a direct call would use. Probably GNAT
> dispatched and then checked the precondition. Technically, that's
> wrong (although I would have a hard time caring, the reason for the
> stronger precondition on dispatching calls is to allow analysis
> without knowing the actual tag, it doesn't have anything to do with
> correctness).

I think that the rule that GNAT appears to be breaking is 6.6.1(38)[1]?

I've constructed an example where GNAT's behaviour results in caller
code that used to work (with checks enabled) no longer working,
depending on the actual type for a classwide (an access-to-classwide,
as might be used if say the application logger could be changed at run
time):

with Ada.Exceptions; use Ada.Exceptions;
with Ada.Text_IO; use Ada.Text_IO;

procedure Conditions is

   package A_Pack is
      type T is tagged null record;
      not overriding
      procedure P (This : T; Var : Integer) is null
        with Pre'Class => Var >= 1;
   end A_Pack;

   package B_Pack is
      type T is new A_Pack.T with null record;
      overriding
      procedure P (This : T; Var : Integer) is null
        with Pre'Class => Var >= 0;                -- widening
   end B_Pack;

   package C_Pack is
      type T is new A_Pack.T with null record;
      overriding
      procedure P (This : T; Var : Integer) is null;
   end C_Pack;

begin

   declare
      O : access A_Pack.T'Class;
   begin
      O := new B_Pack.T;
      Put_Line ("passing 0 to an actual B_Pack.T");
      O.P (0);
      Put_Line ("success.");
      O := new C_Pack.T;
      Put_Line ("passing 0 to an actual C_Pack.T");
      O.P (0);
      Put_Line ("success.");
   exception
      when E : others =>
         Put_Line (Exception_Information (E));
   end;

end Conditions;

and the output is

$ ./conditions 
passing 0 to an actual B_Pack.T
success.
passing 0 to an actual C_Pack.T
Exception name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed inherited precondition from conditions.adb:10


[1] http://www.ada-auth.org/standards/12aarm/html/AA-6-1-1.html#p38



  parent reply	other threads:[~2013-02-16 20:23 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-15  3:55 Class wide preconditions: error in GNAT implementation? ytomino
2013-02-15 10:15 ` Georg Bauhaus
2013-02-15 13:16   ` ytomino
2013-02-16  1:01 ` Randy Brukardt
2013-02-16  2:50   ` ytomino
2013-02-16  9:28     ` Dmitry A. Kazakov
2013-02-16 13:13       ` ytomino
2013-02-16 16:35         ` Dmitry A. Kazakov
2013-02-16 19:55           ` ytomino
2013-02-16 20:34             ` ytomino
2013-02-18  8:30             ` Dmitry A. Kazakov
2013-02-18  9:17               ` Simon Wright
2013-02-18 14:25                 ` Dmitry A. Kazakov
2013-02-18 18:04                   ` Simon Wright
2013-02-18 19:27                     ` Dmitry A. Kazakov
2013-02-18 20:42                       ` Simon Wright
2013-02-19  9:07                         ` Dmitry A. Kazakov
2013-02-18 19:02               ` ytomino
2013-02-18 19:44                 ` Dmitry A. Kazakov
2013-02-16 15:16       ` Georg Bauhaus
2013-02-16 20:23   ` Simon Wright [this message]
2013-02-17 15:12     ` ytomino
2013-02-18 17:49       ` Simon Wright
2013-02-18 18:45         ` ytomino
replies disabled

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