This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Elaboration checks for dispatching calls


This patch introduces a new access-before-elaboration check which attempts to
detect an indirect call to a primitive of a tagged type through dispatching
where the body of the primitive has not been elaborated yet. The check uses a
flag which is set after the body of the primitive is elaborated and verified
within the body itself.

------------
-- Source --
------------

--  pack1.ads

package Pack1 is
   type Parent is abstract tagged null record;

   function Prim (Obj : Parent) return Boolean is abstract;

   function Call_Any_Prim (Obj : Parent'Class) return Boolean;
end Pack1;

--  pack1.adb

package body Pack1 is
   function Call_Any_Prim (Obj : Parent'Class) return Boolean is
   begin
      return Prim (Obj);
   end Call_Any_Prim;
end Pack1;

--  pack2.ads

with Pack1; use Pack1;

package Pack2 is
   Body_Elaborated : Boolean := False;

   type Child is new Parent with record
      Flag : Boolean;
   end record;

   overriding function Prim (Obj : Child) return Boolean;

   Obj : Child;

   ABE : constant Boolean := Call_Any_Prim (Obj);
end Pack2;

--  pack2.adb

with Ada.Text_IO; use Ada.Text_IO;

package body Pack2 is
   function Prim (Obj : Child) return Boolean is
   begin
      Put_Line ("Prim");

      if not Body_Elaborated then
         raise Program_Error with "Pack2 not elaborated";
      end if;

      return Obj.Flag;
   end Prim;

begin
   Body_Elaborated := True;
   Put_Line ("Pack2 elaborated");
end Pack2;

--  main.adb

with Pack2;

procedure Main is begin null; end Main;

----------------------------
-- Compilation and output --
----------------------------

$ gnatmake -q main.adb
$ ./main
raised PROGRAM_ERROR : pack2.adb:4 access before elaboration

Tested on x86_64-pc-linux-gnu, committed on trunk

2017-04-27  Hristian Kirtchev  <kirtchev@adacore.com>

	* checks.adb Add with and use clauses for Sem_Disp.
	(Install_Primitive_Elaboration_Check): New routine.
	* checks.ads (Install_Primitive_Elaboration_Check): New routine.
	* exp_attr.adb (Expand_N_Attribute_Reference): Clean up the
	processing of 'Elaborated.
	* exp_ch6.adb (Expand_N_Subprogram_Body): Install a primitive
	elaboration check.

Attachment: difs
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]