Hello,

Just spotted this function in Gnoga.Server.Connection:


       function Connection_Socket (ID : in Gnoga.Types.Connection_ID)
                                   return Socket_Type
       is
       begin
          return Socket_Map.Element (ID);
       exception
          when E : others =>
             Log ("Error connection_Socket - " & ID'Img);
             Log (Ada.Exceptions.Exception_Information (E));
             raise Connection_Error with
               "Connection ID" & ID'Img & " not found in connection map. " &
               "Connection most likely was previously closed.";
       end Connection_Socket;

It is legal Ada (relying on Constraint_Error for catching a missing key) 
but it won't work properly with GNAT GPL 2016 onwards when pragma 
Suppress(Container_Checks) is activated, for instance with the -gnatp 
switch. In that case, the Element function will raise a PROGRAM_ERROR : 
EXCEPTION_ACCESS_VIOLATION not caught by the exception handler. The 
reason is clear in the RTL code:

    function Element (Container : Map; Key : Key_Type) return 
Element_Type is
       Node : constant Node_Access := Key_Ops.Find (Container.Tree, Key);

    begin
       if Checks and then Node = null then
          raise Constraint_Error with "key not in map";
       end if;

       return Node.Element;
    end Element;

Full test procedure right here (see what happens when you comment out or 
not line 2):

--  GNAT GPL 2016 pragma, suppression included in -gnatp switch :
pragma Suppress(Container_Checks);

with Ada.Strings.Unbounded.Hash;             use Ada.Strings.Unbounded;
with Ada.Containers.Hashed_Maps;
with Ada.Text_IO; use Ada.Text_IO;

procedure Test_2016 is

   package T_Dic is new Ada.Containers.Hashed_Maps
     (Key_Type        => Ada.Strings.Unbounded.Unbounded_String,
      Element_Type    => Positive,
      Hash            => Ada.Strings.Unbounded.Hash,
      Equivalent_Keys => Ada.Strings.Unbounded."=");

   dic: T_Dic.Map;
   n: Positive:= 1;

   procedure P_KO(s: String) is
     i: Integer;
   begin
     i:= dic.Element(To_Unbounded_String(s));
     Put_Line("P_KO: Key " & s & " found, element=" & Integer'Image(i));
   exception
     when Constraint_Error =>  --  A.18.4, 69/2
       Put_Line("P_KO: Key " & s & " not found");
       dic.Insert(To_Unbounded_String(s), n);
       n:= n + 1;
   end P_KO;

   procedure P_OK(s: String) is
     i: Integer;
     use T_Dic;
     curs: Cursor;
   begin
     curs:= dic.Find(To_Unbounded_String(s));
     if curs = No_Element then
       Put_Line("P_OK: Key " & s & " not found");
       dic.Insert(To_Unbounded_String(s), n);
       n:= n + 1;
     else
       i:= Element(curs);
       Put_Line("P_OK: Key " & s & " found, element=" & Integer'Image(i));
     end if;
   end P_OK;

begin
   P_OK("A");
   P_OK("A");
   P_KO("B");
   P_KO("B");
end Test_2016;

There was a discussion about it in c.l.a :

https://groups.google.com/forum/#!searchin/comp.lang.ada/banana$20skin%7Csort:relevance/comp.lang.ada/HZsG7Czymto/kY4BjoD0BAAJ

Cheers
Gautier
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Gnoga-list mailing list
Gnoga-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gnoga-list

Reply via email to