diff mbox

[Ada] Pragma Default_Initial_Condition and tagged types

Message ID 20170109120336.GA4674@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Jan. 9, 2017, 12:03 p.m. UTC
This patch reimplements pragma Default_Initial_Condition. When the pragma is
inherited from a parent tagged type, the assertion expression of the pragma is
subject to class-wide pre/postcondition-like semantics. This means that any
function calls to primitives of the parent type are replaced by calls to the
overriding primitives of the derived type.

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

--  dic_aspects.ads

package DIC_Aspects is

   ------------------------------------
   --  Derivation without overriding --
   ------------------------------------

   type Par_1 is tagged private
     with Default_Initial_Condition => A (Par_1);

   function A (Obj : Par_1) return Boolean;

   type Deriv_1 is new Par_1 with private;
   --  DIC calls: A (Par_1)

   --------------------------------
   -- Derivation with overriding --
   --------------------------------

   type Par_2 is tagged private
     with Default_Initial_Condition => B (Par_2);

   function B (Obj : Par_2) return Boolean;

   type Deriv_2 is new Par_2 with private;
   --  DIC calls: B (Deriv_2)

   function B (Obj : Deriv_2) return Boolean;

   ------------------------------------
   -- Derivation with DIC overriding --
   ------------------------------------

   type Par_3 is tagged private
     with Default_Initial_Condition => C (Par_3);

   function C (Obj : Par_3) return Boolean;

   type Deriv_3 is new Par_3 with private
     with Default_Initial_Condition => D (Deriv_3);
   --  DIC calls: D (Deriv_3)

   function D (Obj : Deriv_3) return Boolean;

   ------------------------------------------------
   -- Derivation with overriding, DIC overriding --
   ------------------------------------------------

   type Par_4 is tagged private
     with Default_Initial_Condition => E (Par_4);

   function E (Obj : Par_4) return Boolean;

   type Deriv_4 is new Par_4 with private
     with Default_Initial_Condition => E (Deriv_4);
   --  DIC calls: E (Deriv_4)

   function E (Obj : Deriv_4) return Boolean;

   ----------------------------------------
   -- Derivation with partial overriding --
   ----------------------------------------

   type Par_5 is tagged private
     with Default_Initial_Condition => F (Par_5) and G (Par_5);

   function F (Obj : Par_5) return Boolean;
   function G (Obj : Par_5) return Boolean;

   type Deriv_5 is new Par_5 with private;
   --  DIC calls: F (Deriv_5), G (Par_5)

   function F (Obj : Deriv_5) return Boolean;

   -------------------------------------------
   --  Hidden derivation without overriding --
   -------------------------------------------

   type Par_6 is tagged private
     with Default_Initial_Condition => H (Par_6);

   function H (Obj : Par_6) return Boolean;

   type Deriv_6 is tagged private;
   --  DIC calls: H (Par_6)

   ---------------------------------------
   -- Hidden derivation with overriding --
   ---------------------------------------

   type Par_7 is tagged private
     with Default_Initial_Condition => I (Par_7);

   function I (Obj : Par_7) return Boolean;

   type Deriv_7 is tagged private;
   --  DIC calls: I (Deriv_7)

   -----------------------------------------------
   -- Hidden derivation with partial overriding --
   -----------------------------------------------

   type Par_8 is tagged private
     with Default_Initial_Condition => J (Par_8) and K (Par_8) and L (Par_8);

   function J (Obj : Par_8) return Boolean;
   function K (Obj : Par_8) return Boolean;
   function L (Obj : Par_8) return Boolean;

   type Deriv_8 is tagged private;
   --  DIC calls: J (Deriv_8), K (Deriv_8), L (Par_8)

   function J (Obj : Deriv_8) return Boolean;

   -----------------------------------
   -- Long chain without overriding --
   -----------------------------------

   type Deriv_9 is new Deriv_1 with private;
   --  DIC calls: A (Par_1)

   --------------------------------
   -- Long chain with overriding --
   --------------------------------

   type Deriv_10 is new Deriv_2 with private;
   --  DIC calls: B (Deriv_2)

   -----------
   -- Mix 1 --
   -----------

   type Typ_1 is tagged private
     with Default_Initial_Condition =>
            M (Typ_1) and N (Typ_1) and O (Typ_1) and P (Typ_1) and Q (Typ_1);

   function M (Obj : Typ_1) return Boolean;
   function N (Obj : Typ_1) return Boolean;
   function O (Obj : Typ_1) return Boolean;
   function P (Obj : Typ_1) return Boolean;
   function Q (Obj : Typ_1) return Boolean;

   type Typ_2 is new Typ_1 with private;
   --  DIC calls: M (Typ_2), N (Typ_2), O (Typ_1), P (Typ_1), Q (Typ_1)

   function M (Obj : Typ_2) return Boolean;

   type Typ_3 is new Typ_2 with private;
   --  DIC calls: M (Typ_2), N (Typ_2), O (Typ_3), P (Typ_3), Q (Typ_1)

   function O (Obj : Typ_3) return Boolean;

private
   type Par_1 is tagged null record;
   type Par_2 is tagged null record;
   type Par_3 is tagged null record;
   type Par_4 is tagged null record;
   type Par_5 is tagged null record;
   type Par_6 is tagged null record;
   type Par_7 is tagged null record;
   type Par_8 is tagged null record;

   type Deriv_1 is new Par_1 with null record;
   type Deriv_2 is new Par_2 with null record;
   type Deriv_3 is new Par_3 with null record;
   type Deriv_4 is new Par_4 with null record;
   type Deriv_5 is new Par_5 with null record;

   type Deriv_6 is new Par_6 with null record;
   type Deriv_7 is new Par_7 with null record;

   function I (Obj : Deriv_7) return Boolean;

   type Deriv_8 is new Par_8 with null record;

   function K (Obj : Deriv_8) return Boolean;

   type Deriv_9 is new Deriv_1 with null record;
   type Deriv_10 is new Deriv_2 with null record;

   type Typ_1 is tagged null record;
   type Typ_2 is new Typ_1 with null record;

   function N (Obj : Typ_2) return Boolean;

   type Typ_3 is new Typ_2 with null record;

   function P (Obj : Typ_3) return Boolean;
end DIC_Aspects;

--  dic_aspects.adb

with Tester; use Tester;

package body DIC_Aspects is
   function A (Obj : Par_1) return Boolean is
   begin
      Mark (Par_1_Id);
      return True;
   end A;

   function B (Obj : Par_2) return Boolean is
   begin
      Mark (Par_2_Id);
      return True;
   end B;

   function B (Obj : Deriv_2) return Boolean is
   begin
      Mark (Deriv_2_Id);
      return True;
   end B;

   function C (Obj : Par_3) return Boolean is
   begin
      Mark (Par_3_Id);
      return True;
   end C;

   function D (Obj : Deriv_3) return Boolean is
   begin
      Mark (Deriv_3_Id);
      return True;
   end D;

   function E (Obj : Par_4) return Boolean is
   begin
      Mark (Par_4_Id);
      return True;
   end E;

   function E (Obj : Deriv_4) return Boolean is
   begin
      Mark (Deriv_4_Id);
      return True;
   end E;

   function F (Obj : Par_5) return Boolean is
   begin
      Mark (Par_5_Id);
      return True;
   end F;

   function F (Obj : Deriv_5) return Boolean is
   begin
      Mark (Deriv_5_Id);
      return True;
   end F;

   function G (Obj : Par_5) return Boolean is
   begin
      Mark (Par_5_Id);
      return True;
   end G;

   function H (Obj : Par_6) return Boolean is
   begin
      Mark (Par_6_Id);
      return True;
   end H;

   function I (Obj : Par_7) return Boolean is
   begin
      Mark (Par_7_Id);
      return True;
   end I;

   function I (Obj : Deriv_7) return Boolean is
   begin
      Mark (Deriv_7_Id);
      return True;
   end I;

   function J (Obj : Par_8) return Boolean is
   begin
      Mark (Par_8_Id);
      return True;
   end J;

   function J (Obj : Deriv_8) return Boolean is
   begin
      Mark (Deriv_8_Id);
      return True;
   end J;

   function K (Obj : Par_8) return Boolean is
   begin
      Mark (Par_8_Id);
      return True;
   end K;

   function K (Obj : Deriv_8) return Boolean is
   begin
      Mark (Deriv_8_Id);
      return True;
   end K;

   function L (Obj : Par_8) return Boolean is
   begin
      Mark (Par_8_Id);
      return True;
   end L;

   function M (Obj : Typ_1) return Boolean is
   begin
      Mark (Typ_1_Id);
      return True;
   end M;

   function M (Obj : Typ_2) return Boolean is
   begin
      Mark (Typ_2_Id);
      return True;
   end M;

   function N (Obj : Typ_1) return Boolean is
   begin
      Mark (Typ_1_Id);
      return True;
   end N;

   function N (Obj : Typ_2) return Boolean is
   begin
      Mark (Typ_2_Id);
      return True;
   end N;

   function O (Obj : Typ_1) return Boolean is
   begin
      Mark (Typ_1_Id);
      return True;
   end O;

   function O (Obj : Typ_3) return Boolean is
   begin
      Mark (Typ_3_Id);
      return True;
   end O;

   function P (Obj : Typ_1) return Boolean is
   begin
      Mark (Typ_1_Id);
      return True;
   end P;

   function P (Obj : Typ_3) return Boolean is
   begin
      Mark (Typ_3_Id);
      return True;
   end P;

   function Q (Obj : Typ_1) return Boolean is
   begin
      Mark (Typ_1_Id);
      return True;
   end Q;
end DIC_Aspects;

--  tester.ads

package Tester is
   type Type_Id is
     (Deriv_1_Id,
      Deriv_2_Id,
      Deriv_3_Id,
      Deriv_4_Id,
      Deriv_5_Id,
      Deriv_6_Id,
      Deriv_7_Id,
      Deriv_8_Id,
      Deriv_9_Id,
      Deriv_10_Id,
      Par_1_Id,
      Par_2_Id,
      Par_3_Id,
      Par_4_Id,
      Par_5_Id,
      Par_6_Id,
      Par_7_Id,
      Par_8_Id,
      Typ_1_Id,
      Typ_2_Id,
      Typ_3_Id);

   type Results is array (Type_Id) of Natural;

   procedure Mark (Typ : Type_Id);
   --  Mark the result for a particular type as verified

   procedure Reset_Results;
   --  Reset the internally kept result state

   procedure Test_Results (Test_Id : String; Exp : Results);
   --  Ensure that the internally kept result state agrees with expected
   --  results Exp. Emit an error if this is not the case.
end Tester;

--  tester.adb

with Ada.Text_IO; use Ada.Text_IO;

package body Tester is
   State : Results;

   ----------
   -- Mark --
   ----------

   procedure Mark (Typ : Type_Id) is
   begin
      State (Typ) := State (Typ) + 1;
   end Mark;

   -------------------
   -- Reset_Results --
   -------------------

   procedure Reset_Results is
   begin
      State := (others => 0);
   end Reset_Results;

   ------------------
   -- Test_Results --
   ------------------

   procedure Test_Results (Test_Id : String; Exp : Results) is
      Exp_Val   : Natural;
      Posted    : Boolean := False;
      State_Val : Natural;

   begin
      for Index in Results'Range loop
         Exp_Val   := Exp (Index);
         State_Val := State (Index);

         if State_Val /= Exp_Val then
            if not Posted then
               Posted := True;
               Put_Line (Test_Id & ": ERROR");
            end if;

            Put_Line ("  " & Index'Img);
            Put_Line ("    Expected:" & Exp_Val'Img);
            Put_Line ("    Got:     " & State_Val'Img);
         end if;
      end loop;

      if not Posted then
         Put_Line (Test_Id & ": OK");
      end if;
   end Test_Results;
end Tester;

--  dic_main.adb

with DIC_Aspects; use DIC_Aspects;
with Tester;      use Tester;

procedure DIC_Main is
begin
   Reset_Results;
   declare
      Obj : Deriv_1;
   begin
      Test_Results ("Deriv_1", (Par_1_Id => 1,
                                others   => 0));
   end;

   Reset_Results;
   declare
      Obj : Deriv_2;
   begin
      Test_Results ("Deriv_2", (Deriv_2_Id => 1,
                                others     => 0));
   end;

   Reset_Results;
   declare
      Obj : Deriv_3;
   begin
      Test_Results ("Deriv_3", (Deriv_3_Id => 1,
                                others     => 0));
   end;

   Reset_Results;
   declare
      Obj : Deriv_4;
   begin
      Test_Results ("Deriv_4", (Deriv_4_Id => 1,
                                others     => 0));
   end;

   Reset_Results;
   declare
      Obj : Deriv_5;
   begin
      Test_Results ("Deriv_5", (Deriv_5_Id => 1,
                                Par_5_Id   => 1,
                                others     => 0));
   end;

   Reset_Results;
   declare
      Obj : Deriv_6;
   begin
      Test_Results ("Deriv_6", (Par_6_Id => 1,
                                others   => 0));
   end;

   Reset_Results;
   declare
      Obj : Deriv_7;
   begin
      Test_Results ("Deriv_7", (Deriv_7_Id => 1,
                                others     => 0));
   end;

   Reset_Results;
   declare
      Obj : Deriv_8;
   begin
      Test_Results ("Deriv_8", (Deriv_8_Id => 2,
                                Par_8_Id   => 1,
                                others     => 0));
   end;

   Reset_Results;
   declare
      Obj : Deriv_9;
   begin
      Test_Results ("Deriv_9", (Par_1_Id => 1,
                                others   => 0));
   end;

   Reset_Results;
   declare
      Obj : Deriv_10;
   begin
      Test_Results ("Deriv_10", (Deriv_2_Id => 1,
                                 others     => 0));
   end;

   Reset_Results;
   declare
      Obj : Par_1;
   begin
      Test_Results ("Par_1", (Par_1_Id => 1,
                              others   => 0));
   end;

   Reset_Results;
   declare
      Obj : Par_2;
   begin
      Test_Results ("Par_2", (Par_2_Id => 1,
                              others   => 0));
   end;

   Reset_Results;
   declare
      Obj : Par_3;
   begin
      Test_Results ("Par_3", (Par_3_Id => 1,
                              others   => 0));
   end;

   Reset_Results;
   declare
      Obj : Par_4;
   begin
      Test_Results ("Par_4", (Par_4_Id => 1,
                              others   => 0));
   end;

   Reset_Results;
   declare
      Obj : Par_5;
   begin
      Test_Results ("Par_5", (Par_5_Id => 2,
                              others   => 0));
   end;

   Reset_Results;
   declare
      Obj : Par_6;
   begin
      Test_Results ("Par_6", (Par_6_Id => 1,
                              others   => 0));
   end;

   Reset_Results;
   declare
      Obj : Par_7;
   begin
      Test_Results ("Par_7", (Par_7_Id => 1,
                              others   => 0));
   end;

   Reset_Results;
   declare
      Obj : Par_8;
   begin
      Test_Results ("Par_8", (Par_8_Id => 3,
                              others   => 0));
   end;

   Reset_Results;
   declare
      Obj : Typ_1;
   begin
      Test_Results ("Typ_1", (Typ_1_Id => 5,
                              others   => 0));
   end;

   Reset_Results;
   declare
      Obj : Typ_2;
   begin
      Test_Results ("Typ_2", (Typ_1_Id => 3,
                              Typ_2_Id => 2,
                              others   => 0));
   end;

   Reset_Results;
   declare
      Obj : Typ_3;
   begin
      Test_Results ("Typ_3", (Typ_1_Id => 1,
                              Typ_2_Id => 2,
                              Typ_3_Id => 2,
                              others   => 0));
   end;
end DIC_Main;

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

$ gnatmake -q -gnata dic_main.adb
$ ./dic_main
Deriv_1: OK
Deriv_2: OK
Deriv_3: OK
Deriv_4: OK
Deriv_5: OK
Deriv_6: OK
Deriv_7: OK
Deriv_8: OK
Deriv_9: OK
Deriv_10: OK
Par_1: OK
Par_2: OK
Par_3: OK
Par_4: OK
Par_5: OK
Par_6: OK
Par_7: OK
Par_8: OK
Typ_1: OK
Typ_2: OK
Typ_3: OK

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

2017-01-09  Hristian Kirtchev  <kirtchev@adacore.com>

	* einfo.ads, einfo.adb: Remove uses of flags Has_Default_Init_Cond,
	Is_Default_Init_Cond_Procedure, and
	Has_Inherited_Default_Init_Cond.  Add uses of flags
	Has_Own_DIC, Is_DIC_Procedure, and Has_Inherited_DIC.
	(Default_Init_Cond_Procedure): Removed.
	(DIC_Procedure): New routine.
	(Has_Default_Init_Cond): Removed.
	(Has_DIC): New routine.
	(Has_Inheritable_Invariants): The attribute applies to the base type.
	(Has_Inherited_Default_Init_Cond): Removed.
	(Has_Inherited_DIC): New routine.
	(Has_Inherited_Invariants): The attribute applies to the base type.
	(Has_Own_DIC): New routine.
	(Has_Own_Invariants): The attribute applies to the base type.
	(Is_Default_Init_Cond_Procedure): Removed.
	(Is_DIC_Procedure): New routine.
	(Set_Default_Init_Cond_Procedure): Removed.
	(Set_DIC_Procedure): New routine.
	(Set_Has_Default_Init_Cond): Removed.
	(Set_Has_Inheritable_Invariants): The attribute applies
	to the base type.
	(Set_Has_Inherited_Default_Init_Cond): Removed.
	(Set_Has_Inherited_DIC): New routine.
	(Set_Has_Inherited_Invariants): The attribute applies to the base type.
	(Set_Has_Own_DIC): New routine.
	(Set_Has_Own_Invariants): The attribute applies to the base type.
	(Set_Is_Default_Init_Cond_Procedure): Removed.
	(Set_Is_DIC_Procedure): New routine.
	(Write_Entity_Flags): Update the output of all flags related to
	default initial condition.
	* exp_ch3.adb (Expand_N_Object_Declaration): Update the generation
	of the call to the DIC procedure.
	(Freeze_Type): Generate the body of the DIC procedure.
	* exp_ch7.adb (Build_Invariant_Procedure_Body): Replace
	all occurrences of Create_Append with Append_New_To. Do
	not generate an invariant procedure for a class-wide type.
	The generated body acts as a freeze action of the working type.
	(Build_Invariant_Procedure_Declaration): Do not generate an
	invariant procedure for a class-wide type.
	(Create_Append): Removed.
	* exp_util.adb: Add with and use clauses for Sem_Ch3, sem_ch6,
	sem_Ch12, Sem_Disp, and GNAT.HTable. Move the handling of
	class-wide pre/postcondition description and data structures from
	Sem_Prag.
	(Build_Class_Wide_Expression): Moved from Sem_Prag.
	(Build_DIC_Call): New routine.
	(Build_DIC_Procedure_Body): New routine.
	(Build_DIC_Procedure_Declaration): New routine.
	(Entity_Hash): Moved from Sem_Prag.
	(Find_DIC_Type): New routine.
	(Update_Primitives_Mapping): Reimplemented.
	(Update_Primitives_Mapping_Of_Types): New routine.
	* exp_util.ads (Build_Class_Wide_Expression): Moved from Sem_Prag.
	(Build_DIC_Call): New routine.
	(Build_DIC_Procedure_Body): New routine.
	(Build_DIC_Procedure_Declaration): New routine.
	(Update_Primitives_Mapping): Moved from Sem_Prag.
	(Update_Primitives_Mapping_Of_Types): New routine.
	* nlists.adb (Append_New): New routine.
	(Append_New_To): New routine.
	* nlists.ads (Append_New): New routine.
	(Append_New_To): New routine.
	* sem_ch3.adb (Analyze_Declarations): Do not generate the bodies
	of DIC procedures here. This is now done at the end of the
	visible declarations, private declarations, and at the freeze
	point of a type.
	(Analyze_Private_Extension_Declaration):
	A private extension inherits the DIC pragma of a parent type.
	(Analyze_Subtype_Declaration): No need to propagate invariant
	attributes to a subtype as those apply to the base type.
	(Build_Derived_Record_Type): No need to inherit invariants here
	as this is now done in Build_Derived_Type.
	(Build_Derived_Type): Inherit both the DIC pragma and invariants from
	a parent type.
	(Process_Full_View): Update the propagation of DIC attributes.
	(Propagate_Default_Init_Cond_Attributes): Removed.
	* sem_ch7.adb Add with and use clauses for Exp_Util.
	(Analyze_Package_Specification): Create the body of the DIC
	procedure at the end of the visible and private declarations.
	(Preserve_Full_Attributes): Propagate DIC attributes.
	* sem_ch9.adb (Analyze_Protected_Type_Declaration): Propagate
	DIC attributes.
	(Analyze_Task_Type_Declaration): Propagate DIC attributes.
	* sem_elab.adb (Check_A_Call): Update the call to
	Is_Nontrivial_Default_Init_Cond_Procedure.
	* sem_prag.adb Remove the with and use clauses for
	GNAT.HTable. Move the handling of class- wide pre/postcondition
	description and data structures to Exp_Util.
	(Analyze_Pragma): Create the declaration of the DIC procedure. There
	is no need to propagate invariant-related attributes at this point
	as this is done in Build_Invariant_Procedure_Declaration.
	(Build_Class_Wide_Expression): Moved to Exp_Util.
	(Entity_Hash): Moved to Exp_Util.
	(Update_Primitives_Mapping): Moved to Exp_Util.
	* sem_prag.ads (Build_Class_Wide_Expression): Moved to Exp_Util.
	(Update_Primitives_Mapping): Moved to Exp_Util.
	* sem_util.adb: Remove with and use clauses for Ghost
	and Sem_Ch13.
	(Build_Default_Init_Cond_Call): Removed.
	(Build_Default_Init_Cond_Procedure_Bodies): Removed.
	(Build_Default_Init_Cond_Procedure_Declaration): Removed.
	(Get_Views): Reimplemented.
	(Has_Full_Default_Initialization): Reimplement the section on DIC.
	(Inherit_Default_Init_Cond_Procedure): Removed.
	(Is_Nontrivial_Default_Init_Cond_Procedure): Removed.
	(Is_Nontrivial_DIC_Procedure): New routine.
	(Is_Verifiable_DIC_Pragma): New routine.
	(Propagate_DIC_Attributes): New routine.
	* sem_util.ads (Build_Default_Init_Cond_Call): Removed.
	(Build_Default_Init_Cond_Procedure_Bodies): Removed.
	(Build_Default_Init_Cond_Procedure_Declaration): Removed.
	(Inherit_Default_Init_Cond_Procedure): Removed.
	(Is_Nontrivial_Default_Init_Cond_Procedure): Removed.
	(Is_Nontrivial_DIC_Procedure): New routine.
	(Is_Verifiable_DIC_Pragma): New routine.
	(Propagate_DIC_Attributes): New routine.
	* sem_warn.adb (Is_OK_Fully_Initialized): Reimplement the section
	on DIC.
	* sinfo.ads, sinfo.adb: Add new attribute Expression_Copy along with
	usage in nodes.
	(Expression_Copy): New routine along with pragma Inline.
	(Set_Expression_Copy): New routine along with pragma Inline.
diff mbox

Patch

Index: sem_ch3.adb
===================================================================
--- sem_ch3.adb	(revision 244223)
+++ sem_ch3.adb	(working copy)
@@ -646,17 +646,6 @@ 
    --  present. If errors are found, error messages are posted, and the
    --  Real_Range_Specification of Def is reset to Empty.
 
-   procedure Propagate_Default_Init_Cond_Attributes
-     (From_Typ             : Entity_Id;
-      To_Typ               : Entity_Id;
-      Parent_To_Derivation : Boolean := False;
-      Private_To_Full_View : Boolean := False);
-   --  Subsidiary to routines Build_Derived_Type and Process_Full_View. Inherit
-   --  all attributes related to pragma Default_Initial_Condition from From_Typ
-   --  to To_Typ. Flag Parent_To_Derivation should be set when the context is
-   --  the creation of a derived type. Flag Private_To_Full_View should be set
-   --  when processing both views of a private type.
-
    procedure Record_Type_Declaration
      (T    : Entity_Id;
       N    : Node_Id;
@@ -2567,15 +2556,6 @@ 
             if L = Private_Declarations (Context) then
                Analyze_Package_Contract (Defining_Entity (Context));
 
-               --  Build the bodies of the default initial condition procedures
-               --  for all types subject to pragma Default_Initial_Condition.
-               --  From a purely Ada stand point, this is a freezing activity,
-               --  however freezing is not available under GNATprove_Mode. To
-               --  accomodate both scenarios, the bodies are build at the end
-               --  of private declaration analysis.
-
-               Build_Default_Init_Cond_Procedure_Bodies (L);
-
             --  Otherwise the contract is analyzed at the end of the visible
             --  declarations.
 
@@ -4639,12 +4619,21 @@ 
 
       Build_Derived_Record_Type (N, Parent_Type, T);
 
+      --  A private extension inherits the Default_Initial_Condition pragma
+      --  coming from any parent type within the derivation chain.
+
+      if Has_DIC (Parent_Type) then
+         Set_Has_Inherited_DIC (T);
+      end if;
+
       --  A private extension inherits any class-wide invariants coming from a
       --  parent type or an interface. Note that the invariant procedure of the
       --  parent type should not be inherited because the private extension may
       --  define invariants of its own.
 
-      if Has_Inheritable_Invariants (Parent_Type) then
+      if Has_Inherited_Invariants (Parent_Type)
+        or else Has_Inheritable_Invariants (Parent_Type)
+      then
          Set_Has_Inherited_Invariants (T);
 
       elsif Present (Interfaces (T)) then
@@ -5243,11 +5232,6 @@ 
          end if;
       end if;
 
-      --  Propagate invariant-related attributes from the base type to the
-      --  subtype.
-
-      Propagate_Invariant_Attributes (Id, From_Typ => Base_Type (T));
-
       --  Remaining processing depends on characteristics of base type
 
       T := Etype (Id);
@@ -8863,40 +8847,6 @@ 
                   end;
                end if;
 
-               --  A derived type inherits any class-wide invariants coming
-               --  from a parent type or an interface. Note that the invariant
-               --  procedure of the parent type should not be inherited because
-               --  the derived type may define invariants of its own.
-
-               if Ada_Version >= Ada_2012
-                 and then not Is_Interface (Derived_Type)
-               then
-                  if Has_Inherited_Invariants (Parent_Type)
-                    or else Has_Inheritable_Invariants (Parent_Type)
-                  then
-                     Set_Has_Inherited_Invariants (Derived_Type);
-
-                  elsif not Is_Empty_Elmt_List (Ifaces_List) then
-                     declare
-                        Iface      : Entity_Id;
-                        Iface_Elmt : Elmt_Id;
-
-                     begin
-                        Iface_Elmt := First_Elmt (Ifaces_List);
-                        while Present (Iface_Elmt) loop
-                           Iface := Node (Iface_Elmt);
-
-                           if Has_Inheritable_Invariants (Iface) then
-                              Set_Has_Inherited_Invariants (Derived_Type);
-                              exit;
-                           end if;
-
-                           Next_Elmt (Iface_Elmt);
-                        end loop;
-                     end;
-                  end if;
-               end if;
-
                --  A type extension is automatically Ghost when one of its
                --  progenitors is Ghost (SPARK RM 6.9(9)). This property is
                --  also inherited when the parent type is Ghost, but this is
@@ -9128,10 +9078,55 @@ 
          Set_Default_SSO (Derived_Type);
       end if;
 
-      --  Propagate invariant information. The new type has invariants if
-      --  they are inherited from the parent type, and these invariants can
-      --  be further inherited, so both flags are set.
+      --  A derived type inherits the Default_Initial_Condition pragma coming
+      --  from any parent type within the derivation chain.
 
+      if Has_DIC (Parent_Type) then
+         Set_Has_Inherited_DIC (Derived_Type);
+      end if;
+
+      --  A derived type inherits any class-wide invariants coming from a
+      --  parent type or an interface. Note that the invariant procedure of
+      --  the parent type should not be inherited because the derived type may
+      --  define invariants of its own.
+
+      if not Is_Interface (Derived_Type) then
+         if Has_Inherited_Invariants (Parent_Type)
+           or else Has_Inheritable_Invariants (Parent_Type)
+         then
+            Set_Has_Inherited_Invariants (Derived_Type);
+
+         elsif Is_Concurrent_Type (Derived_Type)
+           or else Is_Tagged_Type (Derived_Type)
+         then
+            declare
+               Iface      : Entity_Id;
+               Ifaces     : Elist_Id;
+               Iface_Elmt : Elmt_Id;
+
+            begin
+               Collect_Interfaces
+                 (T               => Derived_Type,
+                  Ifaces_List     => Ifaces,
+                  Exclude_Parents => True);
+
+               if Present (Ifaces) then
+                  Iface_Elmt := First_Elmt (Ifaces);
+                  while Present (Iface_Elmt) loop
+                     Iface := Node (Iface_Elmt);
+
+                     if Has_Inheritable_Invariants (Iface) then
+                        Set_Has_Inherited_Invariants (Derived_Type);
+                        exit;
+                     end if;
+
+                     Next_Elmt (Iface_Elmt);
+                  end loop;
+               end if;
+            end;
+         end if;
+      end if;
+
       --  We similarly inherit predicates
 
       if Has_Predicates (Parent_Type) then
@@ -9142,18 +9137,6 @@ 
 
       Inherit_Rep_Item_Chain (Derived_Type, Parent_Type);
 
-      --  Propagate the attributes related to pragma Default_Initial_Condition
-      --  from the parent type to the private extension. A derived type always
-      --  inherits the default initial condition flag from the parent type. If
-      --  the derived type carries its own Default_Initial_Condition pragma,
-      --  the flag is later reset in Analyze_Pragma. Note that both flags are
-      --  mutually exclusive.
-
-      Propagate_Default_Init_Cond_Attributes
-        (From_Typ             => Parent_Type,
-         To_Typ               => Derived_Type,
-         Parent_To_Derivation => True);
-
       --  If the parent type has delayed rep aspects, then mark the derived
       --  type as possibly inheriting a delayed rep aspect.
 
@@ -15161,6 +15144,10 @@ 
       --  Actual_Subp is the actual subprogram corresponding with the generic
       --  subprogram Subp.
 
+      ------------------------
+      -- Check_Derived_Type --
+      ------------------------
+
       function Check_Derived_Type return Boolean is
          E        : Entity_Id;
          Elmt     : Elmt_Id;
@@ -15171,7 +15158,7 @@ 
 
       begin
          --  Traverse list of entities in the current scope searching for
-         --  an incomplete type whose full-view is derived type
+         --  an incomplete type whose full-view is derived type.
 
          E := First_Entity (Scope (Derived_Type));
          while Present (E) and then E /= Derived_Type loop
@@ -20195,46 +20182,6 @@ 
          Set_Has_Specified_Stream_Output (Full_T);
       end if;
 
-      --  Propagate the attributes related to pragma Default_Initial_Condition
-      --  from the private to the full view. Note that both flags are mutually
-      --  exclusive.
-
-      if Has_Default_Init_Cond (Priv_T)
-        or else Has_Inherited_Default_Init_Cond (Priv_T)
-      then
-         Propagate_Default_Init_Cond_Attributes
-           (From_Typ             => Priv_T,
-            To_Typ               => Full_T,
-            Private_To_Full_View => True);
-
-      --  In the case where the full view is derived from another private type,
-      --  the attributes related to pragma Default_Initial_Condition must be
-      --  propagated from the full to the private view to maintain consistency
-      --  of views.
-
-      --    package Pack is
-      --       type Parent_Typ is private
-      --         with Default_Initial_Condition ...;
-      --    private
-      --       type Parent_Typ is ...;
-      --    end Pack;
-
-      --    with Pack; use Pack;
-      --    package Pack_2 is
-      --       type Deriv_Typ is private;         --  must inherit
-      --    private
-      --       type Deriv_Typ is new Parent_Typ;  --  must inherit
-      --    end Pack_2;
-
-      elsif Has_Default_Init_Cond (Full_T)
-        or else Has_Inherited_Default_Init_Cond (Full_T)
-      then
-         Propagate_Default_Init_Cond_Attributes
-           (From_Typ             => Full_T,
-            To_Typ               => Priv_T,
-            Private_To_Full_View => True);
-      end if;
-
       if Is_Ghost_Entity (Priv_T) then
 
          --  The Ghost policy in effect at the point of declaration and at the
@@ -20248,7 +20195,13 @@ 
          Mark_Full_View_As_Ghost (Priv_T, Full_T);
       end if;
 
-      --  Propagate invariant-related attributes from the private view to the
+      --  Propagate Default_Initial_Condition-related attributes from the
+      --  partial view to the full view and its base type.
+
+      Propagate_DIC_Attributes (Full_T, From_Typ => Priv_T);
+      Propagate_DIC_Attributes (Base_Type (Full_T), From_Typ => Priv_T);
+
+      --  Propagate invariant-related attributes from the partial view to the
       --  full view and its base type.
 
       Propagate_Invariant_Attributes (Full_T, From_Typ => Priv_T);
@@ -21085,121 +21038,6 @@ 
       end if;
    end Process_Subtype;
 
-   --------------------------------------------
-   -- Propagate_Default_Init_Cond_Attributes --
-   --------------------------------------------
-
-   procedure Propagate_Default_Init_Cond_Attributes
-     (From_Typ             : Entity_Id;
-      To_Typ               : Entity_Id;
-      Parent_To_Derivation : Boolean := False;
-      Private_To_Full_View : Boolean := False)
-   is
-      procedure Remove_Default_Init_Cond_Procedure (Typ : Entity_Id);
-      --  Remove the default initial condition procedure (if any) from the
-      --  Subprograms_For_Type chain of type Typ.
-
-      ----------------------------------------
-      -- Remove_Default_Init_Cond_Procedure --
-      ----------------------------------------
-
-      procedure Remove_Default_Init_Cond_Procedure (Typ : Entity_Id) is
-         Subps     : constant Elist_Id := Subprograms_For_Type (Typ);
-         Subp_Elmt : Elmt_Id;
-         Subp_Id   : Entity_Id;
-
-      begin
-         if Present (Subps) then
-            Subp_Elmt := First_Elmt (Subps);
-            while Present (Subp_Elmt) loop
-               Subp_Id := Node (Subp_Elmt);
-
-               if Is_Default_Init_Cond_Procedure (Subp_Id) then
-                  Remove_Elmt (Subps, Subp_Elmt);
-                  exit;
-               end if;
-
-               Next_Elmt (Subp_Elmt);
-            end loop;
-         end if;
-      end Remove_Default_Init_Cond_Procedure;
-
-      --  Local variables
-
-      Inherit_Procedure : Boolean := False;
-
-   --  Start of processing for Propagate_Default_Init_Cond_Attributes
-
-   begin
-      if Has_Default_Init_Cond (From_Typ) then
-
-         --  A derived type inherits the attributes from its parent type
-
-         if Parent_To_Derivation then
-            Set_Has_Inherited_Default_Init_Cond (To_Typ);
-
-         --  A full view shares the attributes with its private view
-
-         else
-            Set_Has_Default_Init_Cond (To_Typ);
-         end if;
-
-         Inherit_Procedure := True;
-
-         --  Due to the order of expansion, a derived private type is processed
-         --  by two routines which both attempt to set the attributes related
-         --  to pragma Default_Initial_Condition - Build_Derived_Type and then
-         --  Process_Full_View.
-
-         --    package Pack is
-         --       type Parent_Typ is private
-         --         with Default_Initial_Condition ...;
-         --    private
-         --       type Parent_Typ is ...;
-         --    end Pack;
-
-         --    with Pack; use Pack;
-         --    package Pack_2 is
-         --       type Deriv_Typ is private
-         --         with Default_Initial_Condition ...;
-         --    private
-         --       type Deriv_Typ is new Parent_Typ;
-         --    end Pack_2;
-
-         --  When Build_Derived_Type operates, it sets the attributes on the
-         --  full view without taking into account that the private view may
-         --  define its own default initial condition procedure. This becomes
-         --  apparent in Process_Full_View which must undo some of the work by
-         --  Build_Derived_Type and propagate the attributes from the private
-         --  to the full view.
-
-         if Private_To_Full_View then
-            Set_Has_Inherited_Default_Init_Cond (To_Typ, False);
-            Remove_Default_Init_Cond_Procedure (To_Typ);
-         end if;
-
-      --  A type must inherit the default initial condition procedure from a
-      --  parent type when the parent itself is inheriting the procedure or
-      --  when it is defining one. This circuitry is also used when dealing
-      --  with the private / full view of a type.
-
-      elsif Has_Inherited_Default_Init_Cond (From_Typ)
-        or (Parent_To_Derivation
-              and Present (Get_Pragma
-                    (From_Typ, Pragma_Default_Initial_Condition)))
-      then
-         Set_Has_Inherited_Default_Init_Cond (To_Typ);
-         Inherit_Procedure := True;
-      end if;
-
-      if Inherit_Procedure
-        and then No (Default_Init_Cond_Procedure (To_Typ))
-      then
-         Set_Default_Init_Cond_Procedure
-           (To_Typ, Default_Init_Cond_Procedure (From_Typ));
-      end if;
-   end Propagate_Default_Init_Cond_Attributes;
-
    -----------------------------
    -- Record_Type_Declaration --
    -----------------------------
Index: exp_ch7.adb
===================================================================
--- exp_ch7.adb	(revision 244223)
+++ exp_ch7.adb	(working copy)
@@ -3525,9 +3525,6 @@ 
       --  inherited class-wide invariants. Priv_Item denotes the first rep
       --  item of the private type.
 
-      procedure Create_Append (L : in out List_Id; N : Node_Id);
-      --  Append arbitrary node N to list L. If there is no list, create one.
-
       function Is_Untagged_Private_Derivation
         (Priv_Typ : Entity_Id;
          Full_Typ : Entity_Id) return Boolean;
@@ -3589,7 +3586,7 @@ 
                --  effect.
 
                if not Has_Null_Body (Proc_Id) then
-                  Create_Append (Comp_Checks,
+                  Append_New_To (Comp_Checks,
                     Make_Procedure_Call_Statement (Loc,
                       Name                   =>
                         New_Occurrence_Of (Proc_Id, Loc),
@@ -3628,7 +3625,7 @@ 
                --  effect.
 
                if not Has_Null_Body (Proc_Id) then
-                  Create_Append (Comp_Checks,
+                  Append_New_To (Comp_Checks,
                     Make_If_Statement (Loc,
                       Condition       =>
                         Make_Op_Ne (Loc,
@@ -3703,7 +3700,7 @@ 
                --  effect.
 
                if Present (Comp_Checks) then
-                  Create_Append (Dim_Checks,
+                  Append_New_To (Dim_Checks,
                     Make_Implicit_Loop_Statement (T,
                       Identifier       => Empty,
                       Iteration_Scheme =>
@@ -3906,7 +3903,7 @@ 
                      Var_Stmts := New_List (Make_Null_Statement (Loc));
                   end if;
 
-                  Create_Append (Var_Alts,
+                  Append_New_To (Var_Alts,
                     Make_Case_Statement_Alternative (Loc,
                       Discrete_Choices =>
                         New_Copy_List (Discrete_Choices (Var)),
@@ -3920,7 +3917,7 @@ 
                --  values only when there is at least one real invariant check.
 
                if Produced_Variant_Check then
-                  Create_Append (CL_Checks,
+                  Append_New_To (CL_Checks,
                     Make_Case_Statement (Loc,
                       Expression   =>
                         Make_Selected_Component (Loc,
@@ -3980,7 +3977,7 @@ 
                --  effect.
 
                if not Has_Null_Body (Proc_Id) then
-                  Create_Append (Comp_Checks,
+                  Append_New_To (Comp_Checks,
                     Make_Procedure_Call_Statement (Loc,
                       Name                   =>
                         New_Occurrence_Of (Proc_Id, Loc),
@@ -4023,7 +4020,7 @@ 
                --  effect.
 
                if not Has_Null_Body (Proc_Id) then
-                  Create_Append (Comp_Checks,
+                  Append_New_To (Comp_Checks,
                     Make_If_Statement (Loc,
                       Condition       =>
                         Make_Op_Ne (Loc,
@@ -4356,7 +4353,7 @@ 
                --  Generate:
                --    pragma Check (<Nam>, <Expr>, <Str>);
 
-               Create_Append (Checks,
+               Append_New_To (Checks,
                  Make_Pragma (Ploc,
                    Chars                        => Name_Check,
                    Pragma_Argument_Associations => Assoc));
@@ -4443,19 +4440,6 @@ 
          end if;
       end Add_Type_Invariants;
 
-      -------------------
-      -- Create_Append --
-      -------------------
-
-      procedure Create_Append (L : in out List_Id; N : Node_Id) is
-      begin
-         if No (L) then
-            L := New_List;
-         end if;
-
-         Append_To (L, N);
-      end Create_Append;
-
       ------------------------------------
       -- Is_Untagged_Private_Derivation --
       ------------------------------------
@@ -4494,11 +4478,6 @@ 
       Full_Typ : Entity_Id;
       --  The full view of the working type
 
-      Freeze_Typ : Entity_Id;
-      --  The freeze type whose freeze node carries the invariant procedure
-      --  body. This is either the partial or the full view of the working
-      --  type.
-
       Obj_Id : Entity_Id;
       --  The _object formal parameter of the invariant procedure
 
@@ -4539,10 +4518,15 @@ 
 
       pragma Assert (Has_Invariants (Work_Typ));
 
+      --  ??? invariants of class-wide types are not properly implemented
+
+      if Is_Class_Wide_Type (Work_Typ) then
+         return;
+
       --  Nothing to do for interface types as their class-wide invariants are
       --  inherited by implementing types.
 
-      if Is_Interface (Work_Typ) then
+      elsif Is_Interface (Work_Typ) then
          return;
       end if;
 
@@ -4633,7 +4617,6 @@ 
 
       if Partial_Invariant then
          pragma Assert (Present (Priv_Typ));
-         Freeze_Typ := Priv_Typ;
 
          Add_Type_Invariants
            (Priv_Typ => Priv_Typ,
@@ -4650,7 +4633,6 @@ 
 
       else
          pragma Assert (Present (Full_Typ));
-         Freeze_Typ := Full_Typ;
 
          --  Check the invariants of the partial view by calling the "partial"
          --  invariant procedure. Generate:
@@ -4658,7 +4640,7 @@ 
          --    <Work_Typ>Partial_Invariant (_object);
 
          if Present (Part_Proc) then
-            Create_Append (Stmts,
+            Append_New_To (Stmts,
               Make_Procedure_Call_Statement (Loc,
                 Name                   => New_Occurrence_Of (Part_Proc, Loc),
                 Parameter_Associations => New_List (
@@ -4793,7 +4775,7 @@ 
       --  Otherwise the body is part of the freezing actions of the type
 
       else
-         Append_Freeze_Action (Freeze_Typ, Proc_Body);
+         Append_Freeze_Action (Work_Typ, Proc_Body);
       end if;
 
       Ghost_Mode := Save_Ghost_Mode;
@@ -4860,10 +4842,15 @@ 
 
       pragma Assert (Has_Invariants (Work_Typ));
 
+      --  ??? invariants of class-wide types are not properly implemented
+
+      if Is_Class_Wide_Type (Work_Typ) then
+         return;
+
       --  Nothing to do for interface types as their class-wide invariants are
       --  inherited by implementing types.
 
-      if Is_Interface (Work_Typ) then
+      elsif Is_Interface (Work_Typ) then
          return;
 
       --  Nothing to do if the type already has a "partial" invariant procedure
Index: exp_util.adb
===================================================================
--- exp_util.adb	(revision 244223)
+++ exp_util.adb	(working copy)
@@ -46,8 +46,12 @@ 
 with Rident;   use Rident;
 with Sem;      use Sem;
 with Sem_Aux;  use Sem_Aux;
+with Sem_Ch3;  use Sem_Ch3;
+with Sem_Ch6;  use Sem_Ch6;
 with Sem_Ch8;  use Sem_Ch8;
+with Sem_Ch12; use Sem_Ch12;
 with Sem_Ch13; use Sem_Ch13;
+with Sem_Disp; use Sem_Disp;
 with Sem_Eval; use Sem_Eval;
 with Sem_Res;  use Sem_Res;
 with Sem_Type; use Sem_Type;
@@ -61,8 +65,46 @@ 
 with Urealp;   use Urealp;
 with Validsw;  use Validsw;
 
+with GNAT.HTable; use GNAT.HTable;
+
 package body Exp_Util is
 
+   ---------------------------------------------------------
+   -- Handling of inherited class-wide pre/postconditions --
+   ---------------------------------------------------------
+
+   --  Following AI12-0113, the expression for a class-wide condition is
+   --  transformed for a subprogram that inherits it, by replacing calls
+   --  to primitive operations of the original controlling type into the
+   --  corresponding overriding operations of the derived type. The following
+   --  hash table manages this mapping, and is expanded on demand whenever
+   --  such inherited expression needs to be constructed.
+
+   --  The mapping is also used to check whether an inherited operation has
+   --  a condition that depends on overridden operations. For such an
+   --  operation we must create a wrapper that is then treated as a normal
+   --  overriding. In SPARK mode such operations are illegal.
+
+   --  For a given root type there may be several type extensions with their
+   --  own overriding operations, so at various times a given operation of
+   --  the root will be mapped into different overridings. The root type is
+   --  also mapped into the current type extension to indicate that its
+   --  operations are mapped into the overriding operations of that current
+   --  type extension.
+
+   Primitives_Mapping_Size : constant := 511;
+
+   subtype Num_Primitives is Integer range 0 .. Primitives_Mapping_Size - 1;
+   function Entity_Hash (E : Entity_Id) return Num_Primitives;
+
+   package Primitives_Mapping is new GNAT.HTable.Simple_HTable
+     (Header_Num => Num_Primitives,
+      Key        => Entity_Id,
+      Element    => Entity_Id,
+      No_element => Empty,
+      Hash       => Entity_Hash,
+      Equal      => "=");
+
    -----------------------
    -- Local Subprograms --
    -----------------------
@@ -113,6 +155,11 @@ 
    --  Force evaluation of bounds of a slice, which may be given by a range
    --  or by a subtype indication with or without a constraint.
 
+   function Find_DIC_Type (Typ : Entity_Id) return Entity_Id;
+   --  Subsidiary to all Build_DIC_Procedure_xxx routines. Find the type which
+   --  defines the Default_Initial_Condition pragma of type Typ. This is either
+   --  Typ itself or a parent type when the pragma is inherited.
+
    function Make_CW_Equivalent_Type
      (T : Entity_Id;
       E : Node_Id) return Entity_Id;
@@ -984,6 +1031,1074 @@ 
       return Blk;
    end Build_Abort_Undefer_Block;
 
+   ---------------------------------
+   -- Build_Class_Wide_Expression --
+   ---------------------------------
+
+   procedure Build_Class_Wide_Expression
+     (Prag        : Node_Id;
+      Subp        : Entity_Id;
+      Par_Subp    : Entity_Id;
+      Adjust_Sloc : Boolean)
+   is
+      function Replace_Entity (N : Node_Id) return Traverse_Result;
+      --  Replace reference to formal of inherited operation or to primitive
+      --  operation of root type, with corresponding entity for derived type,
+      --  when constructing the class-wide condition of an overriding
+      --  subprogram.
+
+      --------------------
+      -- Replace_Entity --
+      --------------------
+
+      function Replace_Entity (N : Node_Id) return Traverse_Result is
+         New_E : Entity_Id;
+
+      begin
+         if Adjust_Sloc then
+            Adjust_Inherited_Pragma_Sloc (N);
+         end if;
+
+         if Nkind (N) = N_Identifier
+           and then Present (Entity (N))
+           and then
+             (Is_Formal (Entity (N)) or else Is_Subprogram (Entity (N)))
+           and then
+             (Nkind (Parent (N)) /= N_Attribute_Reference
+               or else Attribute_Name (Parent (N)) /= Name_Class)
+         then
+            --  The replacement does not apply to dispatching calls within the
+            --  condition, but only to calls whose static tag is that of the
+            --  parent type.
+
+            if Is_Subprogram (Entity (N))
+              and then Nkind (Parent (N)) = N_Function_Call
+              and then Present (Controlling_Argument (Parent (N)))
+            then
+               return OK;
+            end if;
+
+            --  Determine whether entity has a renaming
+
+            New_E := Primitives_Mapping.Get (Entity (N));
+
+            if Present (New_E) then
+               Rewrite (N, New_Occurrence_Of (New_E, Sloc (N)));
+            end if;
+
+            --  Check that there are no calls left to abstract operations if
+            --  the current subprogram is not abstract.
+
+            if Nkind (Parent (N)) = N_Function_Call
+              and then N = Name (Parent (N))
+            then
+               if not Is_Abstract_Subprogram (Subp)
+                 and then Is_Abstract_Subprogram (Entity (N))
+               then
+                  Error_Msg_Sloc := Sloc (Current_Scope);
+                  Error_Msg_NE
+                    ("cannot call abstract subprogram in inherited condition "
+                      & "for&#", N, Current_Scope);
+
+               --  In SPARK mode, reject an inherited condition for an
+               --  inherited operation if it contains a call to an overriding
+               --  operation, because this implies that the pre/postcondition
+               --  of the inherited operation have changed silently.
+
+               elsif SPARK_Mode = On
+                 and then Warn_On_Suspicious_Contract
+                 and then Present (Alias (Subp))
+                 and then Present (New_E)
+                 and then Comes_From_Source (New_E)
+               then
+                  Error_Msg_N
+                    ("cannot modify inherited condition (SPARK RM 6.1.1(1))",
+                     Parent (Subp));
+                  Error_Msg_Sloc   := Sloc (New_E);
+                  Error_Msg_Node_2 := Subp;
+                  Error_Msg_NE
+                    ("\overriding of&# forces overriding of&",
+                     Parent (Subp), New_E);
+               end if;
+            end if;
+
+            --  Update type of function call node, which should be the same as
+            --  the function's return type.
+
+            if Is_Subprogram (Entity (N))
+              and then Nkind (Parent (N)) = N_Function_Call
+            then
+               Set_Etype (Parent (N), Etype (Entity (N)));
+            end if;
+
+         --  The whole expression will be reanalyzed
+
+         elsif Nkind (N) in N_Has_Etype then
+            Set_Analyzed (N, False);
+         end if;
+
+         return OK;
+      end Replace_Entity;
+
+      procedure Replace_Condition_Entities is
+        new Traverse_Proc (Replace_Entity);
+
+      --  Local variables
+
+      Par_Formal  : Entity_Id;
+      Subp_Formal : Entity_Id;
+
+   --  Start of processing for Build_Class_Wide_Expression
+
+   begin
+      --  Add mapping from old formals to new formals
+
+      Par_Formal  := First_Formal (Par_Subp);
+      Subp_Formal := First_Formal (Subp);
+
+      while Present (Par_Formal) and then Present (Subp_Formal) loop
+         Primitives_Mapping.Set (Par_Formal, Subp_Formal);
+         Next_Formal (Par_Formal);
+         Next_Formal (Subp_Formal);
+      end loop;
+
+      Replace_Condition_Entities (Prag);
+   end Build_Class_Wide_Expression;
+
+   --------------------
+   -- Build_DIC_Call --
+   --------------------
+
+   function Build_DIC_Call
+     (Loc    : Source_Ptr;
+      Obj_Id : Entity_Id;
+      Typ    : Entity_Id) return Node_Id
+   is
+      Proc_Id    : constant Entity_Id := DIC_Procedure (Typ);
+      Formal_Typ : constant Entity_Id := Etype (First_Formal (Proc_Id));
+
+   begin
+      return
+        Make_Procedure_Call_Statement (Loc,
+          Name                   => New_Occurrence_Of (Proc_Id, Loc),
+          Parameter_Associations => New_List (
+            Make_Unchecked_Type_Conversion (Loc,
+              Subtype_Mark => New_Occurrence_Of (Formal_Typ, Loc),
+              Expression   => New_Occurrence_Of (Obj_Id, Loc))));
+   end Build_DIC_Call;
+
+   ------------------------------
+   -- Build_DIC_Procedure_Body --
+   ------------------------------
+
+   procedure Build_DIC_Procedure_Body (Typ : Entity_Id) is
+      procedure Add_DIC_Check
+        (DIC_Prag : Node_Id;
+         DIC_Expr : Node_Id;
+         Stmts    : in out List_Id);
+      --  Subsidiary to all Add_xxx_DIC routines. Add a runtime check to verify
+      --  assertion expression DIC_Expr of pragma DIC_Prag. All generated code
+      --  is added to list Stmts.
+
+      procedure Add_Inherited_DIC
+        (DIC_Prag  : Node_Id;
+         Par_Typ   : Entity_Id;
+         Deriv_Typ : Entity_Id;
+         Stmts     : in out List_Id);
+      --  Add a runtime check to verify the assertion expression of inherited
+      --  pragma DIC_Prag. Par_Typ is parent type which is also the owner of
+      --  the DIC pragma. Deriv_Typ is the derived type inheriting the DIC
+      --  pragma. All generated code is added to list Stmts.
+
+      procedure Add_Inherited_Tagged_DIC
+        (DIC_Prag  : Node_Id;
+         Par_Typ   : Entity_Id;
+         Deriv_Typ : Entity_Id;
+         Stmts     : in out List_Id);
+      --  Add a runtime check to verify assertion expression DIC_Expr of
+      --  inherited pragma DIC_Prag. This routine applies class-wide pre- and
+      --  postcondition-like runtime semantics to the check. Par_Typ is the
+      --  parent type whose DIC pragma is being inherited. Deriv_Typ is the
+      --  derived type inheriting the DIC pragma. All generated code is added
+      --  to list Stmts.
+
+      procedure Add_Own_DIC
+        (DIC_Prag : Node_Id;
+         DIC_Typ  : Entity_Id;
+         Stmts    : in out List_Id);
+      --  Add a runtime check to verify the assertion expression of pragma
+      --  DIC_Prag. DIC_Typ is the owner of the DIC pragma. All generated code
+      --  is added to list Stmts.
+
+      procedure Replace_Object_And_Primitive_References
+        (Expr      : Node_Id;
+         Par_Typ   : Entity_Id;
+         Deriv_Typ : Entity_Id);
+      --  Expr denotes an arbitrary expression. Par_Typ is a parent type in a
+      --  type hierarchy. Deriv_Typ is a type derived from Par_Typ. Perform the
+      --  following substitutions:
+      --
+      --    * Replace a reference to the _object parameter of the parent type's
+      --      DIC procedure with a reference to the _object parameter of the
+      --      derived type's DIC procedure.
+      --
+      --    * Replace a call to an overridden parent primitive with a call to
+      --      the overriding derived type primitive.
+      --
+      --    * Replace a call to an inherited parent primitive with a call to
+      --      the internally-generated inherited derived type primitive.
+
+      procedure Replace_Type_References
+        (Expr   : Node_Id;
+         Typ    : Entity_Id;
+         Obj_Id : Entity_Id);
+      --  Substitute all references of the current instance of type Typ with
+      --  references to formal parameter Obj_Id within expression Expr.
+
+      -------------------
+      -- Add_DIC_Check --
+      -------------------
+
+      procedure Add_DIC_Check
+        (DIC_Prag : Node_Id;
+         DIC_Expr : Node_Id;
+         Stmts    : in out List_Id)
+      is
+         Loc : constant Source_Ptr := Sloc (DIC_Prag);
+         Nam : constant Name_Id    := Original_Aspect_Pragma_Name (DIC_Prag);
+
+      begin
+         --  The DIC pragma is ignored, nothing left to do
+
+         if Is_Ignored (DIC_Prag) then
+            null;
+
+         --  Otherwise the DIC expression must be checked at runtime. Generate:
+
+         --    pragma Check (<Nam>, <DIC_Expr>);
+
+         else
+            Append_New_To (Stmts,
+              Make_Pragma (Loc,
+                Pragma_Identifier            =>
+                  Make_Identifier (Loc, Name_Check),
+
+                Pragma_Argument_Associations => New_List (
+                  Make_Pragma_Argument_Association (Loc,
+                    Expression => Make_Identifier (Loc, Nam)),
+
+                  Make_Pragma_Argument_Association (Loc,
+                    Expression => DIC_Expr))));
+         end if;
+      end Add_DIC_Check;
+
+      -----------------------
+      -- Add_Inherited_DIC --
+      -----------------------
+
+      procedure Add_Inherited_DIC
+        (DIC_Prag  : Node_Id;
+         Par_Typ   : Entity_Id;
+         Deriv_Typ : Entity_Id;
+         Stmts     : in out List_Id)
+      is
+         Deriv_Proc : constant Entity_Id  := DIC_Procedure (Deriv_Typ);
+         Deriv_Obj  : constant Entity_Id  := First_Entity  (Deriv_Proc);
+         Par_Proc   : constant Entity_Id  := DIC_Procedure (Par_Typ);
+         Par_Obj    : constant Entity_Id  := First_Entity  (Par_Proc);
+         Loc        : constant Source_Ptr := Sloc (DIC_Prag);
+
+      begin
+         pragma Assert (Present (Deriv_Proc) and then Present (Par_Proc));
+
+         --  Verify the inherited DIC assertion expression by calling the DIC
+         --  procedure of the parent type.
+
+         --  Generate:
+         --    <Par_Typ>DIC (Par_Typ (_object));
+
+         Append_New_To (Stmts,
+           Make_Procedure_Call_Statement (Loc,
+             Name                   => New_Occurrence_Of (Par_Proc, Loc),
+             Parameter_Associations => New_List (
+               Convert_To
+                 (Typ  => Etype (Par_Obj),
+                  Expr => New_Occurrence_Of (Deriv_Obj, Loc)))));
+      end Add_Inherited_DIC;
+
+      ------------------------------
+      -- Add_Inherited_Tagged_DIC --
+      ------------------------------
+
+      procedure Add_Inherited_Tagged_DIC
+        (DIC_Prag  : Node_Id;
+         Par_Typ   : Entity_Id;
+         Deriv_Typ : Entity_Id;
+         Stmts     : in out List_Id)
+      is
+         DIC_Args : constant List_Id :=
+                      Pragma_Argument_Associations (DIC_Prag);
+         DIC_Arg  : constant Node_Id := First (DIC_Args);
+         DIC_Expr : constant Node_Id := Expression_Copy (DIC_Arg);
+         Typ_Decl : constant Node_Id := Declaration_Node (Deriv_Typ);
+
+         Expr : Node_Id;
+
+      begin
+         --  The processing of an inherited DIC assertion expression starts off
+         --  with a copy of the original parent expression where all references
+         --  to the parent type have already been replaced with references to
+         --  the _object formal parameter of the parent type's DIC procedure.
+
+         pragma Assert (Present (DIC_Expr));
+         Expr := New_Copy_Tree (DIC_Expr);
+
+         --  Perform the following substitutions:
+
+         --    * Replace a reference to the _object parameter of the parent
+         --      type's DIC procedure with a reference to the _object parameter
+         --      of the derived types' DIC procedure.
+
+         --    * Replace a call to an overridden parent primitive with a call
+         --      to the overriding derived type primitive.
+
+         --    * Replace a call to an inherited parent primitive with a call to
+         --      the internally-generated inherited derived type primitive.
+
+         --  Note that primitives defined in the private part are automatically
+         --  handled by the overriding/inheritance mechanism and do not require
+         --  an extra replacement pass.
+
+         Replace_Object_And_Primitive_References
+           (Expr      => Expr,
+            Par_Typ   => Par_Typ,
+            Deriv_Typ => Deriv_Typ);
+
+         --  Preanalyze the DIC expression to detect errors and at the same
+         --  time capture the visibility of the proper package part.
+
+         Set_Parent (Expr, Typ_Decl);
+         Preanalyze_Assert_Expression (Expr, Any_Boolean);
+
+         --  Once the DIC assertion expression is fully processed, add a check
+         --  to the statements of the DIC procedure.
+
+         Add_DIC_Check
+           (DIC_Prag => DIC_Prag,
+            DIC_Expr => Expr,
+            Stmts    => Stmts);
+      end Add_Inherited_Tagged_DIC;
+
+      -----------------
+      -- Add_Own_DIC --
+      -----------------
+
+      procedure Add_Own_DIC
+        (DIC_Prag : Node_Id;
+         DIC_Typ  : Entity_Id;
+         Stmts    : in out List_Id)
+      is
+         DIC_Args : constant List_Id   :=
+                      Pragma_Argument_Associations (DIC_Prag);
+         DIC_Arg  : constant Node_Id   := First (DIC_Args);
+         DIC_Asp  : constant Node_Id   := Corresponding_Aspect (DIC_Prag);
+         DIC_Expr : constant Node_Id   := Get_Pragma_Arg (DIC_Arg);
+         DIC_Proc : constant Entity_Id := DIC_Procedure (DIC_Typ);
+         Obj_Id   : constant Entity_Id := First_Formal (DIC_Proc);
+
+         procedure Preanalyze_Own_DIC_For_ASIS;
+         --  Preanalyze the original DIC expression of an aspect or a source
+         --  pragma for ASIS.
+
+         ---------------------------------
+         -- Preanalyze_Own_DIC_For_ASIS --
+         ---------------------------------
+
+         procedure Preanalyze_Own_DIC_For_ASIS is
+            Expr : Node_Id := Empty;
+
+         begin
+            --  The DIC pragma is a source construct, preanalyze the original
+            --  expression of the pragma.
+
+            if Comes_From_Source (DIC_Prag) then
+               Expr := DIC_Expr;
+
+            --  Otherwise preanalyze the expression of the corresponding aspect
+
+            elsif Present (DIC_Asp) then
+               Expr := Expression (DIC_Asp);
+            end if;
+
+            --  The expression must be subjected to the same substitutions as
+            --  the copy used in the generation of the runtime check.
+
+            if Present (Expr) then
+               Replace_Type_References
+                 (Expr   => Expr,
+                  Typ    => DIC_Typ,
+                  Obj_Id => Obj_Id);
+
+               Preanalyze_Assert_Expression (Expr, Any_Boolean);
+            end if;
+         end Preanalyze_Own_DIC_For_ASIS;
+
+         --  Local variables
+
+         Typ_Decl : constant Node_Id := Declaration_Node (DIC_Typ);
+
+         Expr : Node_Id;
+
+      --  Start of processing for Add_Own_DIC
+
+      begin
+         Expr := New_Copy_Tree (DIC_Expr);
+
+         --  Perform the following substituion:
+
+         --    * Replace the current instance of DIC_Typ with a reference to
+         --    the _object formal parameter of the DIC procedure.
+
+         Replace_Type_References
+           (Expr   => Expr,
+            Typ    => DIC_Typ,
+            Obj_Id => Obj_Id);
+
+         --  Preanalyze the DIC expression to detect errors and at the same
+         --  time capture the visibility of the proper package part.
+
+         Set_Parent (Expr, Typ_Decl);
+         Preanalyze_Assert_Expression (Expr, Any_Boolean);
+
+         --  Save a copy of the expression with all replacements and analysis
+         --  already taken place in case a derived type inherits the pragma.
+         --  The copy will be used as the foundation of the derived type's own
+         --  version of the DIC assertion expression.
+
+         if Is_Tagged_Type (DIC_Typ) then
+            Set_Expression_Copy (DIC_Arg, New_Copy_Tree (Expr));
+         end if;
+
+         --  If the pragma comes from an aspect specification, replace the
+         --  saved expression because all type references must be substituted
+         --  for the call to Preanalyze_Spec_Expression in Check_Aspect_At_xxx
+         --  routines.
+
+         if Present (DIC_Asp) then
+            Set_Entity (Identifier (DIC_Asp), New_Copy_Tree (Expr));
+         end if;
+
+         --  Preanalyze the original DIC expression for ASIS
+
+         if ASIS_Mode then
+            Preanalyze_Own_DIC_For_ASIS;
+         end if;
+
+         --  Once the DIC assertion expression is fully processed, add a check
+         --  to the statements of the DIC procedure.
+
+         Add_DIC_Check
+           (DIC_Prag => DIC_Prag,
+            DIC_Expr => Expr,
+            Stmts    => Stmts);
+      end Add_Own_DIC;
+
+      ---------------------------------------------
+      -- Replace_Object_And_Primitive_References --
+      ---------------------------------------------
+
+      procedure Replace_Object_And_Primitive_References
+        (Expr      : Node_Id;
+         Par_Typ   : Entity_Id;
+         Deriv_Typ : Entity_Id)
+      is
+         Deriv_Obj : Entity_Id;
+         --  The _object parameter of the derived type's DIC procedure
+
+         Par_Obj : Entity_Id;
+         --  The _object parameter of the parent type's DIC procedure
+
+         function Replace_Ref (Ref : Node_Id) return Traverse_Result;
+         --  Substitute a reference to an entity with a reference to the
+         --  corresponding entity stored in in table Primitives_Mapping.
+
+         -----------------
+         -- Replace_Ref --
+         -----------------
+
+         function Replace_Ref (Ref : Node_Id) return Traverse_Result is
+            Context : constant Node_Id    := Parent (Ref);
+            Loc     : constant Source_Ptr := Sloc (Ref);
+            New_Id  : Entity_Id;
+            New_Ref : Node_Id;
+            Ref_Id  : Entity_Id;
+            Result  : Traverse_Result;
+
+         begin
+            Result := OK;
+
+            --  The current node denotes a reference
+
+            if Nkind (Ref) in N_Has_Entity and then Present (Entity (Ref)) then
+               Ref_Id := Entity (Ref);
+               New_Id := Primitives_Mapping.Get (Ref_Id);
+
+               --  The reference mentions a parent type primitive which has a
+               --  corresponding derived type primitive.
+
+               if Present (New_Id) then
+                  New_Ref := New_Occurrence_Of (New_Id, Loc);
+
+               --  The reference mentions the _object parameter of the parent
+               --  type's DIC procedure.
+
+               elsif Ref_Id = Par_Obj then
+                  New_Ref := New_Occurrence_Of (Deriv_Obj, Loc);
+
+                  --  The reference to _object acts as an actual parameter in a
+                  --  subprogram call which may be invoking a primitive of the
+                  --  parent type:
+
+                  --    Primitive (... _object ...);
+
+                  --  The parent type primitive may not be overridden nor
+                  --  inherited when it is declared after the derived type
+                  --  definition:
+
+                  --    type Parent is tagged private;
+                  --    type Child is new Parent with private;
+                  --    procedure Primitive (Obj : Parent);
+
+                  --  In this scenario the _object parameter is converted to
+                  --  the parent type.
+
+                  if Nkind_In (Context, N_Function_Call,
+                                        N_Procedure_Call_Statement)
+                    and then
+                      No (Primitives_Mapping.Get (Entity (Name (Context))))
+                  then
+                     New_Ref := Convert_To (Par_Typ, New_Ref);
+
+                     --  Do not process the generated type conversion because
+                     --  both the parent type and the derived type are in the
+                     --  Primitives_Mapping table. This will clobber the type
+                     --  conversion by resetting its subtype mark.
+
+                     Result := Skip;
+                  end if;
+
+               --  Otherwise there is nothing to replace
+
+               else
+                  New_Ref := Empty;
+               end if;
+
+               if Present (New_Ref) then
+                  Rewrite (Ref, New_Ref);
+
+                  --  Update the return type when the context of the reference
+                  --  acts as the name of a function call. Note that the update
+                  --  should not be performed when the reference appears as an
+                  --  actual in the call.
+
+                  if Nkind (Context) = N_Function_Call
+                    and then Name (Context) = Ref
+                  then
+                     Set_Etype (Context, Etype (New_Id));
+                  end if;
+               end if;
+            end if;
+
+            --  Reanalyze the reference due to potential replacements
+
+            if Nkind (Ref) in N_Has_Etype then
+               Set_Analyzed (Ref, False);
+            end if;
+
+            return Result;
+         end Replace_Ref;
+
+         procedure Replace_Refs is new Traverse_Proc (Replace_Ref);
+
+         --  Local variables
+
+         Deriv_Proc : constant Entity_Id := DIC_Procedure (Deriv_Typ);
+         Par_Proc   : constant Entity_Id := DIC_Procedure (Par_Typ);
+
+      --  Start of processing for Replace_Object_And_Primitive_References
+
+      begin
+         pragma Assert (Present (Deriv_Proc) and then Present (Par_Proc));
+
+         Deriv_Obj := First_Entity (Deriv_Proc);
+         Par_Obj   := First_Entity (Par_Proc);
+
+         --  Map each primitive operation of the parent type to the proper
+         --  primitive of the derived type.
+
+         Update_Primitives_Mapping_Of_Types
+           (Par_Typ   => Par_Typ,
+            Deriv_Typ => Deriv_Typ);
+
+         --  Inspect the input expression and perform substitutions where
+         --  necessary.
+
+         Replace_Refs (Expr);
+      end Replace_Object_And_Primitive_References;
+
+      -----------------------------
+      -- Replace_Type_References --
+      -----------------------------
+
+      procedure Replace_Type_References
+        (Expr   : Node_Id;
+         Typ    : Entity_Id;
+         Obj_Id : Entity_Id)
+      is
+         procedure Replace_Type_Ref (N : Node_Id);
+         --  Substitute a single reference of the current instance of type Typ
+         --  with a reference to Obj_Id.
+
+         ----------------------
+         -- Replace_Type_Ref --
+         ----------------------
+
+         procedure Replace_Type_Ref (N : Node_Id) is
+            Ref : Node_Id;
+
+         begin
+            --  Decorate the reference to Typ even though it may be rewritten
+            --  further down. This is done for two reasons:
+
+            --    1) ASIS has all necessary semantic information in the
+            --    original tree.
+
+            --    2) Routines which examine properties of the Original_Node
+            --    have some semantic information.
+
+            if Nkind (N) = N_Identifier then
+               Set_Entity (N, Typ);
+               Set_Etype  (N, Typ);
+
+            elsif Nkind (N) = N_Selected_Component then
+               Analyze (Prefix (N));
+               Set_Entity (Selector_Name (N), Typ);
+               Set_Etype  (Selector_Name (N), Typ);
+            end if;
+
+            --  Perform the following substitution:
+
+            --    Typ  -->  _object
+
+            Ref := Make_Identifier (Sloc (N), Chars (Obj_Id));
+            Set_Entity (Ref, Obj_Id);
+            Set_Etype  (Ref, Typ);
+
+            Rewrite (N, Ref);
+
+            Set_Comes_From_Source (N, True);
+         end Replace_Type_Ref;
+
+         procedure Replace_Type_Refs is
+           new Replace_Type_References_Generic (Replace_Type_Ref);
+
+      --  Start of processing for Replace_Type_References
+
+      begin
+         Replace_Type_Refs (Expr, Typ);
+      end Replace_Type_References;
+
+      --  Local variables
+
+      Loc : constant Source_Ptr := Sloc (Typ);
+
+      Save_Ghost_Mode : constant Ghost_Mode_Type := Ghost_Mode;
+
+      DIC_Prag     : Node_Id;
+      DIC_Typ      : Entity_Id;
+      Dummy_1      : Entity_Id;
+      Dummy_2      : Entity_Id;
+      Proc_Body    : Node_Id;
+      Proc_Body_Id : Entity_Id;
+      Proc_Decl    : Node_Id;
+      Proc_Id      : Entity_Id;
+      Stmts        : List_Id := No_List;
+
+      Work_Typ : Entity_Id;
+      --  The working type
+
+   --  Start of processing for Build_DIC_Procedure_Body
+
+   begin
+      Work_Typ := Typ;
+
+      --  The input type denotes the implementation base type of a constrained
+      --  array type. Work with the first subtype as the DIC pragma is on its
+      --  rep item chain.
+
+      if Ekind (Work_Typ) = E_Array_Type and then Is_Itype (Work_Typ) then
+         Work_Typ := First_Subtype (Work_Typ);
+
+      --  The input denotes the corresponding record type of a protected or a
+      --  task type. Work with the concurrent type because the corresponding
+      --  record type may not be visible to clients of the type.
+
+      elsif Ekind (Work_Typ) = E_Record_Type
+        and then Is_Concurrent_Record_Type (Work_Typ)
+      then
+         Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
+      end if;
+
+      --  The working type must be either define a DIC pragma of its own or
+      --  inherit one from a parent type.
+
+      pragma Assert (Has_DIC (Work_Typ));
+
+      --  Recover the type which defines the DIC pragma. This is either the
+      --  working type itself or a parent type when the pragma is inherited.
+
+      DIC_Typ := Find_DIC_Type (Work_Typ);
+      pragma Assert (Present (DIC_Typ));
+
+      DIC_Prag := Get_Pragma (DIC_Typ, Pragma_Default_Initial_Condition);
+      pragma Assert (Present (DIC_Prag));
+
+      --  Nothing to do if pragma DIC appears without an argument or its sole
+      --  argument is "null".
+
+      if not Is_Verifiable_DIC_Pragma (DIC_Prag) then
+         return;
+      end if;
+
+      --  The working type may lack a DIC procedure declaration. This may be
+      --  due to several reasons:
+
+      --    * The working type's own DIC pragma does not contain a verifiable
+      --      assertion expression. In this case there is no need to build a
+      --      DIC procedure because there is nothing to check.
+
+      --    * The working type derives from a parent type. In this case a DIC
+      --      procedure should be built only when the inherited DIC pragma has
+      --      a verifiable assertion expression.
+
+      Proc_Id := DIC_Procedure (Work_Typ);
+
+      --  Build a DIC procedure declaration when the working type derives from
+      --  a parent type.
+
+      if No (Proc_Id) then
+         Build_DIC_Procedure_Declaration (Work_Typ);
+         Proc_Id := DIC_Procedure (Work_Typ);
+      end if;
+
+      --  At this point there should be a DIC procedure declaration
+
+      pragma Assert (Present (Proc_Id));
+      Proc_Decl := Unit_Declaration_Node (Proc_Id);
+
+      --  Nothing to do if the DIC procedure already has a body
+
+      if Present (Corresponding_Body (Proc_Decl)) then
+         return;
+      end if;
+
+      --  The working type may be subject to pragma Ghost. Set the mode now to
+      --  ensure that the DIC procedure is properly marked as Ghost.
+
+      Set_Ghost_Mode_From_Entity (Work_Typ);
+
+      --  Emulate the environment of the DIC procedure by installing its scope
+      --  and formal parameters.
+
+      Push_Scope (Proc_Id);
+      Install_Formals (Proc_Id);
+
+      --  The working type defines its own DIC pragma. Replace the current
+      --  instance of the working type with the formal of the DIC procedure.
+      --  Note that there is no need to consider inherited DIC pragmas from
+      --  parent types because the working type's DIC pragma "hides" all
+      --  inherited DIC pragmas.
+
+      if Has_Own_DIC (Work_Typ) then
+         pragma Assert (DIC_Typ = Work_Typ);
+
+         Add_Own_DIC
+           (DIC_Prag => DIC_Prag,
+            DIC_Typ  => DIC_Typ,
+            Stmts    => Stmts);
+
+      --  Otherwise the working type inherits a DIC pragma from a parent type
+
+      else
+         pragma Assert (Has_Inherited_DIC (Work_Typ));
+         pragma Assert (DIC_Typ /= Work_Typ);
+
+         --  The working type is tagged. The verification of the assertion
+         --  expression is subject to the same semantics as class-wide pre-
+         --  and postconditions.
+
+         if Is_Tagged_Type (Work_Typ) then
+            Add_Inherited_Tagged_DIC
+              (DIC_Prag  => DIC_Prag,
+               Par_Typ   => DIC_Typ,
+               Deriv_Typ => Work_Typ,
+               Stmts     => Stmts);
+
+         --  Otherwise the working type is not tagged. Verify the assertion
+         --  expression of the inherited DIC pragma by directly calling the
+         --  DIC procedure of the parent type.
+
+         else
+            Add_Inherited_DIC
+              (DIC_Prag  => DIC_Prag,
+               Par_Typ   => DIC_Typ,
+               Deriv_Typ => Work_Typ,
+               Stmts     => Stmts);
+         end if;
+      end if;
+
+      End_Scope;
+
+      --  Produce an empty completing body in the following cases:
+      --    * Assertions are disabled
+      --    * The DIC Assertion_Policy is Ignore
+      --    * Pragma DIC appears without an argument
+      --    * Pragma DIC appears with argument "null"
+
+      if No (Stmts) then
+         Stmts := New_List (Make_Null_Statement (Loc));
+      end if;
+
+      --  Generate:
+      --    procedure <Work_Typ>DIC (_object : <Work_Typ>) is
+      --    begin
+      --       <Stmts>
+      --    end <Work_Typ>DIC;
+
+      Proc_Body :=
+        Make_Subprogram_Body (Loc,
+          Specification                =>
+            Copy_Subprogram_Spec (Parent (Proc_Id)),
+          Declarations                 => Empty_List,
+            Handled_Statement_Sequence =>
+              Make_Handled_Sequence_Of_Statements (Loc,
+                Statements => Stmts));
+      Proc_Body_Id := Defining_Entity (Proc_Body);
+
+      --  Perform minor decoration in case the body is not analyzed
+
+      Set_Ekind (Proc_Body_Id, E_Subprogram_Body);
+      Set_Etype (Proc_Body_Id, Standard_Void_Type);
+      Set_Scope (Proc_Body_Id, Current_Scope);
+
+      --  Link both spec and body to avoid generating duplicates
+
+      Set_Corresponding_Body (Proc_Decl, Proc_Body_Id);
+      Set_Corresponding_Spec (Proc_Body, Proc_Id);
+
+      --  The body should not be inserted into the tree when the context is
+      --  ASIS, GNATprove or a generic unit because it is not part of the
+      --  template. Note that the body must still be generated in order to
+      --  resolve the DIC assertion expression.
+
+      if ASIS_Mode or GNATprove_Mode or Inside_A_Generic then
+         null;
+
+      --  Otherwise the body is part of the freezing actions of the working
+      --  type.
+
+      else
+         Append_Freeze_Action (Work_Typ, Proc_Body);
+      end if;
+
+      Ghost_Mode := Save_Ghost_Mode;
+   end Build_DIC_Procedure_Body;
+
+   -------------------------------------
+   -- Build_DIC_Procedure_Declaration --
+   -------------------------------------
+
+   procedure Build_DIC_Procedure_Declaration (Typ : Entity_Id) is
+      Loc : constant Source_Ptr := Sloc (Typ);
+
+      Save_Ghost_Mode : constant Ghost_Mode_Type := Ghost_Mode;
+
+      DIC_Prag  : Node_Id;
+      DIC_Typ   : Entity_Id;
+      Proc_Decl : Node_Id;
+      Proc_Id   : Entity_Id;
+      Typ_Decl  : Node_Id;
+
+      CRec_Typ : Entity_Id;
+      --  The corresponding record type of Full_Typ
+
+      Full_Base : Entity_Id;
+      --  The base type of Full_Typ
+
+      Full_Typ : Entity_Id;
+      --  The full view of working type
+
+      Obj_Id : Entity_Id;
+      --  The _object formal parameter of the DIC procedure
+
+      Priv_Typ : Entity_Id;
+      --  The partial view of working type
+
+      Work_Typ : Entity_Id;
+      --  The working type
+
+   begin
+      Work_Typ := Typ;
+
+      --  The input type denotes the implementation base type of a constrained
+      --  array type. Work with the first subtype as the DIC pragma is on its
+      --  rep item chain.
+
+      if Ekind (Work_Typ) = E_Array_Type and then Is_Itype (Work_Typ) then
+         Work_Typ := First_Subtype (Work_Typ);
+
+      --  The input denotes the corresponding record type of a protected or a
+      --  task type. Work with the concurrent type because the corresponding
+      --  record type may not be visible to clients of the type.
+
+      elsif Ekind (Work_Typ) = E_Record_Type
+        and then Is_Concurrent_Record_Type (Work_Typ)
+      then
+         Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
+      end if;
+
+      --  The type must be either subject to a DIC pragma or inherit one from a
+      --  parent type.
+
+      pragma Assert (Has_DIC (Work_Typ));
+
+      --  Recover the type which defines the DIC pragma. This is either the
+      --  working type itself or a parent type when the pragma is inherited.
+
+      DIC_Typ := Find_DIC_Type (Work_Typ);
+      pragma Assert (Present (DIC_Typ));
+
+      DIC_Prag := Get_Pragma (DIC_Typ, Pragma_Default_Initial_Condition);
+      pragma Assert (Present (DIC_Prag));
+
+      --  Nothing to do if pragma DIC appears without an argument or its sole
+      --  argument is "null".
+
+      if not Is_Verifiable_DIC_Pragma (DIC_Prag) then
+         return;
+
+      --  Nothing to do if the type already has a DIC procedure
+
+      elsif Present (DIC_Procedure (Work_Typ)) then
+         return;
+      end if;
+
+      --  The working type may be subject to pragma Ghost. Set the mode now to
+      --  ensure that the DIC procedure is properly marked as Ghost.
+
+      Set_Ghost_Mode_From_Entity (Work_Typ);
+
+      Proc_Id :=
+        Make_Defining_Identifier (Loc,
+          Chars =>
+            New_External_Name (Chars (Work_Typ), "Default_Initial_Condition"));
+
+      --  Perform minor decoration in case the declaration is not analyzed
+
+      Set_Ekind (Proc_Id, E_Procedure);
+      Set_Etype (Proc_Id, Standard_Void_Type);
+      Set_Scope (Proc_Id, Current_Scope);
+
+      Set_Is_DIC_Procedure (Proc_Id);
+      Set_DIC_Procedure (Work_Typ, Proc_Id);
+
+      --  The DIC procedure requires debug info when the assertion expression
+      --  is subject to Source Coverage Obligations.
+
+      if Opt.Generate_SCO then
+         Set_Needs_Debug_Info (Proc_Id);
+      end if;
+
+      --  Mark the DIC procedure explicitly as Ghost because it does not come
+      --  from source.
+
+      if Ghost_Mode > None then
+         Set_Is_Ghost_Entity (Proc_Id);
+      end if;
+
+      --  Obtain all views of the input type
+
+      Get_Views (Work_Typ, Priv_Typ, Full_Typ, Full_Base, CRec_Typ);
+
+      --  Associate the DIC procedure and various relevant flags with all views
+
+      Propagate_DIC_Attributes (Priv_Typ,  From_Typ => Work_Typ);
+      Propagate_DIC_Attributes (Full_Typ,  From_Typ => Work_Typ);
+      Propagate_DIC_Attributes (Full_Base, From_Typ => Work_Typ);
+      Propagate_DIC_Attributes (CRec_Typ,  From_Typ => Work_Typ);
+
+      --  The declaration of the DIC procedure must be inserted after the
+      --  declaration of the partial view as this allows for proper external
+      --  visibility.
+
+      if Present (Priv_Typ) then
+         Typ_Decl := Declaration_Node (Priv_Typ);
+
+      --  Derived types with the full view as parent do not have a partial
+      --  view. Insert the DIC procedure after the derived type.
+
+      else
+         Typ_Decl := Declaration_Node (Full_Typ);
+      end if;
+
+      --  The type should have a declarative node
+
+      pragma Assert (Present (Typ_Decl));
+
+      --  Create the formal parameter which emulates the variable-like behavior
+      --  of the current type instance.
+
+      Obj_Id := Make_Defining_Identifier (Loc, Chars => Name_uObject);
+
+      --  Perform minor decoration in case the declaration is not analyzed
+
+      Set_Ekind (Obj_Id, E_In_Parameter);
+      Set_Etype (Obj_Id, Work_Typ);
+      Set_Scope (Obj_Id, Proc_Id);
+
+      Set_First_Entity (Proc_Id, Obj_Id);
+
+      --  Generate:
+      --    procedure <Work_Typ>DIC (_object : <Work_Typ>);
+
+      Proc_Decl :=
+        Make_Subprogram_Declaration (Loc,
+          Specification =>
+            Make_Procedure_Specification (Loc,
+              Defining_Unit_Name       => Proc_Id,
+              Parameter_Specifications => New_List (
+                Make_Parameter_Specification (Loc,
+                  Defining_Identifier => Obj_Id,
+                  Parameter_Type      =>
+                    New_Occurrence_Of (Work_Typ, Loc)))));
+
+      --  The declaration should not be inserted into the tree when the context
+      --  is ASIS, GNATprove or a generic unit because it is not part of the
+      --  template.
+
+      if ASIS_Mode or GNATprove_Mode or Inside_A_Generic then
+         null;
+
+      --  Otherwise insert the declaration
+
+      else
+         pragma Assert (Present (Typ_Decl));
+         Insert_After_And_Analyze (Typ_Decl, Proc_Decl);
+      end if;
+
+      Ghost_Mode := Save_Ghost_Mode;
+   end Build_DIC_Procedure_Declaration;
+
    --------------------------
    -- Build_Procedure_Form --
    --------------------------
@@ -2224,6 +3339,15 @@ 
       end if;
    end Ensure_Defined;
 
+   -----------------
+   -- Entity_Hash --
+   -----------------
+
+   function Entity_Hash (E : Entity_Id) return Num_Primitives is
+   begin
+      return Num_Primitives (E mod Primitives_Mapping_Size);
+   end Entity_Hash;
+
    --------------------
    -- Entry_Names_OK --
    --------------------
@@ -2764,6 +3888,56 @@ 
       return TSS (Utyp, TSS_Finalize_Address);
    end Finalize_Address;
 
+   -------------------
+   -- Find_DIC_Type --
+   -------------------
+
+   function Find_DIC_Type (Typ : Entity_Id) return Entity_Id is
+      Curr_Typ : Entity_Id;
+      DIC_Typ  : Entity_Id;
+
+   begin
+      --  The input type defines its own DIC pragma, therefore it is the owner
+
+      if Has_Own_DIC (Typ) then
+         DIC_Typ := Typ;
+
+      --  Otherwise the DIC pragma is inherited from a parent type
+
+      else
+         pragma Assert (Has_Inherited_DIC (Typ));
+
+         --  Climb the parent chain
+
+         Curr_Typ := Typ;
+         loop
+            --  Inspect the parent type. Do not consider subtypes as they
+            --  inherit the DIC attributes from their base types.
+
+            DIC_Typ := Base_Type (Etype (Curr_Typ));
+
+            --  Look at the full view of a private type because the type may
+            --  have a hidden parent introduced in the full view.
+
+            if Is_Private_Type (DIC_Typ)
+              and then Present (Full_View (DIC_Typ))
+            then
+               DIC_Typ := Full_View (DIC_Typ);
+            end if;
+
+            --  Stop the climb once the nearest parent type which defines a DIC
+            --  pragma of its own is encountered or when the root of the parent
+            --  chain is reached.
+
+            exit when Has_Own_DIC (DIC_Typ) or else Curr_Typ = DIC_Typ;
+
+            Curr_Typ := DIC_Typ;
+         end loop;
+      end if;
+
+      return DIC_Typ;
+   end Find_DIC_Type;
+
    ------------------------
    -- Find_Interface_ADT --
    ------------------------
@@ -9830,6 +11004,172 @@ 
       end if;
    end Type_May_Have_Bit_Aligned_Components;
 
+   -------------------------------
+   -- Update_Primitives_Mapping --
+   -------------------------------
+
+   procedure Update_Primitives_Mapping
+     (Inher_Id : Entity_Id;
+      Subp_Id  : Entity_Id)
+   is
+   begin
+      Update_Primitives_Mapping_Of_Types
+        (Par_Typ   => Find_Dispatching_Type (Inher_Id),
+         Deriv_Typ => Find_Dispatching_Type (Subp_Id));
+   end Update_Primitives_Mapping;
+
+   ----------------------------------------
+   -- Update_Primitives_Mapping_Of_Types --
+   ----------------------------------------
+
+   procedure Update_Primitives_Mapping_Of_Types
+     (Par_Typ   : Entity_Id;
+      Deriv_Typ : Entity_Id)
+   is
+      procedure Add_Primitive (Prim : Entity_Id);
+      --  Find a primitive in the inheritance/overriding chain starting from
+      --  Prim whose dispatching type is parent type Par_Typ and add a mapping
+      --  between the result and primitive Prim.
+
+      -------------------
+      -- Add_Primitive --
+      -------------------
+
+      procedure Add_Primitive (Prim : Entity_Id) is
+         function Ancestor_Primitive (Subp : Entity_Id) return Entity_Id;
+         --  Return the next ancestor primitive in the inheritance/overriding
+         --  chain of subprogram Subp. Return Empty if no such primitive is
+         --  available.
+
+         ------------------------
+         -- Ancestor_Primitive --
+         ------------------------
+
+         function Ancestor_Primitive (Subp : Entity_Id) return Entity_Id is
+            Inher_Prim : constant Entity_Id := Alias (Subp);
+            Over_Prim  : constant Entity_Id := Overridden_Operation (Subp);
+
+         begin
+            --  The current subprogram overrides an ancestor primitive
+
+            if Present (Over_Prim) then
+               return Over_Prim;
+
+            --  The current subprogram is an internally generated alias of an
+            --  inherited ancestor primitive.
+
+            elsif Present (Inher_Prim) then
+               return Inher_Prim;
+
+            --  Otherwise the current subprogram is the root of the inheritance
+            --  or overriding chain.
+
+            else
+               return Empty;
+            end if;
+         end Ancestor_Primitive;
+
+         --  Local variables
+
+         Par_Prim : Entity_Id;
+
+      --  Start of processing for Add_Primitive
+
+      begin
+         --  Inspect both the inheritance chain through the Alias attribute and
+         --  the overriding chain through the Overridden_Operation looking for
+         --  an ancestor primitive with the appropriate dispatching type.
+
+         Par_Prim := Prim;
+         while Present (Par_Prim) loop
+            exit when Find_Dispatching_Type (Par_Prim) = Par_Typ;
+            Par_Prim := Ancestor_Primitive (Par_Prim);
+         end loop;
+
+         --  Create a mapping of the form:
+
+         --    Parent type primitive -> derived type primitive
+
+         if Present (Par_Prim) then
+            Primitives_Mapping.Set (Par_Prim, Prim);
+         end if;
+      end Add_Primitive;
+
+      --  Local variables
+
+      Deriv_Prim : Entity_Id;
+      Par_Prim   : Entity_Id;
+      Par_Prims  : Elist_Id;
+      Prim_Elmt  : Elmt_Id;
+
+   --  Start of processing for Update_Primitives_Mapping_Of_Types
+
+   begin
+      --  Nothing to do if there are no types to work with
+
+      if No (Par_Typ) or else No (Deriv_Typ) then
+         return;
+
+      --  Nothing to do if the mapping already exists
+
+      elsif Primitives_Mapping.Get (Par_Typ) = Deriv_Typ then
+         return;
+      end if;
+
+      --  Create a mapping of the form:
+
+      --    Parent type -> Derived type
+
+      --  to prevent any subsequent attempts to produce the same relations.
+
+      Primitives_Mapping.Set (Par_Typ, Deriv_Typ);
+
+      --  Inspect the primitives of the derived type and determine whether they
+      --  relate to the primitives of the parent type. If there is a meaningful
+      --  relation, create a mapping of the form:
+
+      --    Parent type primitive -> Derived type primitive
+
+      if Present (Direct_Primitive_Operations (Deriv_Typ)) then
+         Prim_Elmt := First_Elmt (Direct_Primitive_Operations (Deriv_Typ));
+         while Present (Prim_Elmt) loop
+            Deriv_Prim := Node (Prim_Elmt);
+
+            if Is_Subprogram (Deriv_Prim)
+              and then Find_Dispatching_Type (Deriv_Prim) = Deriv_Typ
+            then
+               Add_Primitive (Deriv_Prim);
+            end if;
+
+            Next_Elmt (Prim_Elmt);
+         end loop;
+      end if;
+
+      --  If the parent operation is an interface operation, the overriding
+      --  indicator is not present. Instead, we get from the interface
+      --  operation the primitive of the current type that implements it.
+
+      if Is_Interface (Par_Typ) then
+         Par_Prims := Collect_Primitive_Operations (Par_Typ);
+
+         if Present (Par_Prims) then
+            Prim_Elmt := First_Elmt (Par_Prims);
+
+            while Present (Prim_Elmt) loop
+               Par_Prim   := Node (Prim_Elmt);
+               Deriv_Prim :=
+                 Find_Primitive_Covering_Interface (Deriv_Typ, Par_Prim);
+
+               if Present (Deriv_Prim) then
+                  Primitives_Mapping.Set (Par_Prim, Deriv_Prim);
+               end if;
+
+               Next_Elmt (Prim_Elmt);
+            end loop;
+         end if;
+      end if;
+   end Update_Primitives_Mapping_Of_Types;
+
    ----------------------------------
    -- Within_Case_Or_If_Expression --
    ----------------------------------
Index: exp_util.ads
===================================================================
--- exp_util.ads	(revision 244223)
+++ exp_util.ads	(working copy)
@@ -247,6 +247,39 @@ 
    --  inlining of the abort undefer routine. Note that this routine does
    --  not install a call to Abort_Defer.
 
+   procedure Build_Class_Wide_Expression
+     (Prag        : Node_Id;
+      Subp        : Entity_Id;
+      Par_Subp    : Entity_Id;
+      Adjust_Sloc : Boolean);
+   --  Build the expression for an inherited class-wide condition. Prag is
+   --  the pragma constructed from the corresponding aspect of the parent
+   --  subprogram, and Subp is the overriding operation and Par_Subp is
+   --  the overridden operation that has the condition. Adjust_Sloc is True
+   --  when the sloc of nodes traversed should be adjusted for the inherited
+   --  pragma. The routine is also called to check whether an inherited
+   --  operation that is not overridden but has inherited conditions need
+   --  a wrapper, because the inherited condition includes calls to other
+   --  primitives that have been overridden. In that case the first argument
+   --  is the expression of the original class-wide aspect. In SPARK_Mode, such
+   --  operation which are just inherited but have modified pre/postconditions
+   --  are illegal.
+
+   function Build_DIC_Call
+     (Loc    : Source_Ptr;
+      Obj_Id : Entity_Id;
+      Typ    : Entity_Id) return Node_Id;
+   --  Build a call to the DIC procedure of type Typ with Obj_Id as the actual
+   --  parameter.
+
+   procedure Build_DIC_Procedure_Body (Typ : Entity_Id);
+   --  Create the body of the procedure which verifies the assertion expression
+   --  of pragma Default_Initial_Condition at runtime.
+
+   procedure Build_DIC_Procedure_Declaration (Typ : Entity_Id);
+   --  Create the declaration of the procedure which verifies the assertion
+   --  expression of pragma Default_Initial_Condition at runtime.
+
    procedure Build_Procedure_Form (N : Node_Id);
    --  Create a procedure declaration which emulates the behavior of a function
    --  that returns an array type, for C-compatible generation.
@@ -1055,6 +1088,21 @@ 
    --  is conservative, in that a result of False is decisive. A result of True
    --  means that such a component may or may not be present.
 
+   procedure Update_Primitives_Mapping
+     (Inher_Id : Entity_Id;
+      Subp_Id  : Entity_Id);
+   --  Map primitive operations of the parent type to the corresponding
+   --  operations of the descendant. Note that the descendant type may not be
+   --  frozen yet, so we cannot use the dispatch table directly. This is called
+   --  when elaborating a contract for a subprogram, and when freezing a type
+   --  extension to verify legality rules on inherited conditions.
+
+   procedure Update_Primitives_Mapping_Of_Types
+     (Par_Typ   : Entity_Id;
+      Deriv_Typ : Entity_Id);
+   --  Map the primitive operations of parent type Par_Typ to the corresponding
+   --  primitives of derived type Deriv_Typ.
+
    function Within_Case_Or_If_Expression (N : Node_Id) return Boolean;
    --  Determine whether arbitrary node N is within a case or an if expression
 
Index: nlists.adb
===================================================================
--- nlists.adb	(revision 244223)
+++ nlists.adb	(working copy)
@@ -203,7 +203,6 @@ 
    -----------------
 
    procedure Append_List (List : List_Id; To : List_Id) is
-
       procedure Append_List_Debug;
       pragma Inline (Append_List_Debug);
       --  Output debug information if Debug_Flag_N set
@@ -269,6 +268,28 @@ 
       Append_List (List, To);
    end Append_List_To;
 
+   ----------------
+   -- Append_New --
+   ----------------
+
+   procedure Append_New (Node : Node_Or_Entity_Id; To : in out List_Id) is
+   begin
+      if No (To) then
+         To := New_List;
+      end if;
+
+      Append (Node, To);
+   end Append_New;
+
+   -------------------
+   -- Append_New_To --
+   -------------------
+
+   procedure Append_New_To (To : in out List_Id; Node : Node_Or_Entity_Id) is
+   begin
+      Append_New (Node, To);
+   end Append_New_To;
+
    ---------------
    -- Append_To --
    ---------------
Index: nlists.ads
===================================================================
--- nlists.ads	(revision 244223)
+++ nlists.ads	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1992-2014, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2016, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -229,6 +229,16 @@ 
    --  An attempt to append an error node is ignored without complaint and the
    --  list is unchanged.
 
+   procedure Append_New (Node : Node_Or_Entity_Id; To : in out List_Id);
+   pragma Inline (Append_New);
+   --  Appends Node at the end of node list To. If To is non-existent list, a
+   --  list is created. Node must be a non-empty node that is not already a
+   --  member of a node list, and To must be a node list.
+
+   procedure Append_New_To (To : in out List_Id; Node : Node_Or_Entity_Id);
+   pragma Inline (Append_New_To);
+   --  Like Append_New, but the arguments are in reverse order
+
    procedure Append_To (To : List_Id; Node : Node_Or_Entity_Id);
    pragma Inline (Append_To);
    --  Like Append, but arguments are the other way round
Index: sinfo.adb
===================================================================
--- sinfo.adb	(revision 244223)
+++ sinfo.adb	(working copy)
@@ -1284,6 +1284,14 @@ 
       return Node3 (N);
    end Expression;
 
+   function Expression_Copy
+      (N : Node_Id) return Node_Id is
+   begin
+      pragma Assert (False
+        or else NT (N).Nkind = N_Pragma_Argument_Association);
+      return Node2 (N);
+   end Expression_Copy;
+
    function Expressions
       (N : Node_Id) return List_Id is
    begin
@@ -4555,6 +4563,14 @@ 
       Set_Node3_With_Parent (N, Val);
    end Set_Expression;
 
+   procedure Set_Expression_Copy
+      (N : Node_Id; Val : Node_Id) is
+   begin
+      pragma Assert (False
+        or else NT (N).Nkind = N_Pragma_Argument_Association);
+      Set_Node2 (N, Val);  -- semantic field, no parent set
+   end Set_Expression_Copy;
+
    procedure Set_Expressions
       (N : Node_Id; Val : List_Id) is
    begin
Index: sinfo.ads
===================================================================
--- sinfo.ads	(revision 244223)
+++ sinfo.ads	(working copy)
@@ -1281,6 +1281,12 @@ 
    --    target of the assignment or initialization is used to generate the
    --    left-hand side of individual assignment to each sub-component.
 
+   --  Expression_Copy (Node2-Sem)
+   --    Present in N_Pragma_Argument_Association nodes. Contains a copy of the
+   --    original expression. This field is best used to store pragma-dependent
+   --    modifications performed on the original expression such as replacement
+   --    of the current type instance or substitutions of primitives.
+
    --  First_Inlined_Subprogram (Node3-Sem)
    --    Present in the N_Compilation_Unit node for the main program. Points
    --    to a chain of entities for subprograms that are to be inlined. The
@@ -2571,6 +2577,7 @@ 
       --  N_Pragma_Argument_Association
       --  Sloc points to first token in association
       --  Chars (Name1) (set to No_Name if no pragma argument identifier)
+      --  Expression_Copy (Node2-Sem)
       --  Expression (Node3)
 
       ------------------------
@@ -9181,6 +9188,9 @@ 
    function Expression
      (N : Node_Id) return Node_Id;    -- Node3
 
+   function Expression_Copy
+     (N : Node_Id) return Node_Id;    -- Node2
+
    function Expressions
      (N : Node_Id) return List_Id;    -- List1
 
@@ -10227,6 +10237,9 @@ 
    procedure Set_Expression
      (N : Node_Id; Val : Node_Id);            -- Node3
 
+   procedure Set_Expression_Copy
+     (N : Node_Id; Val : Node_Id);            -- Node2
+
    procedure Set_Expressions
      (N : Node_Id; Val : List_Id);            -- List1
 
@@ -11082,7 +11095,7 @@ 
 
      N_Pragma_Argument_Association =>
        (1 => True,    --  Chars (Name1)
-        2 => False,   --  unused
+        2 => False,   --  Expression_Copy (Node2-Sem)
         3 => True,    --  Expression (Node3)
         4 => False,   --  unused
         5 => False),  --  unused
@@ -12544,14 +12557,14 @@ 
         5 => False),  --  unused
 
      N_Push_Program_Error_Label =>
-       (1 => False,   --  Exception_Label
+       (1 => False,   --  unused
         2 => False,   --  unused
         3 => False,   --  unused
         4 => False,   --  unused
         5 => False),  --  Exception_Label
 
      N_Push_Storage_Error_Label =>
-       (1 => False,   --  Exception_Label
+       (1 => False,   --  unused
         2 => False,   --  unused
         3 => False,   --  unused
         4 => False,   --  unused
@@ -12790,6 +12803,7 @@ 
    pragma Inline (Explicit_Actual_Parameter);
    pragma Inline (Explicit_Generic_Actual_Parameter);
    pragma Inline (Expression);
+   pragma Inline (Expression_Copy);
    pragma Inline (Expressions);
    pragma Inline (First_Bit);
    pragma Inline (First_Inlined_Subprogram);
@@ -13136,6 +13150,7 @@ 
    pragma Inline (Set_Explicit_Actual_Parameter);
    pragma Inline (Set_Explicit_Generic_Actual_Parameter);
    pragma Inline (Set_Expression);
+   pragma Inline (Set_Expression_Copy);
    pragma Inline (Set_Expressions);
    pragma Inline (Set_First_Bit);
    pragma Inline (Set_First_Inlined_Subprogram);
Index: sem_ch7.adb
===================================================================
--- sem_ch7.adb	(revision 244223)
+++ sem_ch7.adb	(working copy)
@@ -39,6 +39,7 @@ 
 with Exp_Disp;  use Exp_Disp;
 with Exp_Dist;  use Exp_Dist;
 with Exp_Dbug;  use Exp_Dbug;
+with Exp_Util;  use Exp_Util;
 with Freeze;    use Freeze;
 with Ghost;     use Ghost;
 with Lib;       use Lib;
@@ -1453,19 +1454,12 @@ 
 
          if Is_Type (E) then
 
-            --  Each private type subject to pragma Default_Initial_Condition
-            --  declares a specialized procedure which verifies the assumption
-            --  of the pragma. The declaration appears in the visible part of
-            --  the package to allow for being called from the outside.
+            --  Preanalyze and resolve the Default_Initial_Condition assertion
+            --  expression at the end of the visible declarations to catch any
+            --  errors.
 
-            if Has_Default_Init_Cond (E) then
-               Build_Default_Init_Cond_Procedure_Declaration (E);
-
-            --  A private extension inherits the default initial condition
-            --  procedure from its parent type.
-
-            elsif Has_Inherited_Default_Init_Cond (E) then
-               Inherit_Default_Init_Cond_Procedure (E);
+            if Has_DIC (E) then
+               Build_DIC_Procedure_Body (E);
             end if;
 
             --  Preanalyze and resolve the invariants of a private type at the
@@ -1661,18 +1655,28 @@ 
               ("full view of & does not have preelaborable initialization", E);
          end if;
 
-         --  Preanalyze and resolve the invariants of a private type's full
-         --  view at the end of the private declarations in case freezing did
-         --  not take place either due to errors or because the context is a
-         --  generic unit.
+         if Is_Type (E) and then Serious_Errors_Detected > 0 then
 
-         if Is_Type (E)
-           and then not Is_Private_Type (E)
-           and then Has_Private_Declaration (E)
-           and then Has_Invariants (E)
-           and then Serious_Errors_Detected > 0
-         then
-            Build_Invariant_Procedure_Body (E);
+            --  Preanalyze and resolve the Default_Initial_Condition assertion
+            --  expression at the end of the private declarations when freezing
+            --  did not take place due to errors or because the context is a
+            --  generic unit.
+
+            if Has_DIC (E) then
+               Build_DIC_Procedure_Body (E);
+            end if;
+
+            --  Preanalyze and resolve the invariants of a private type's full
+            --  view at the end of the private declarations in case freezing
+            --  did not take place either due to errors or because the context
+            --  is a generic unit.
+
+            if not Is_Private_Type (E)
+              and then Has_Private_Declaration (E)
+              and then Has_Invariants (E)
+            then
+               Build_Invariant_Procedure_Body (E);
+            end if;
          end if;
 
          Next_Entity (E);
@@ -2630,6 +2634,16 @@ 
 
          Set_Freeze_Node (Priv, Freeze_Node (Full));
 
+         --  Propagate Default_Initial_Condition-related attributes from the
+         --  base type of the full view to the full view and vice versa. This
+         --  may seem strange, but is necessary depending on which type
+         --  triggered the generation of the DIC procedure body. As a result,
+         --  both the full view and its base type carry the same DIC-related
+         --  information.
+
+         Propagate_DIC_Attributes (Full, From_Typ => Full_Base);
+         Propagate_DIC_Attributes (Full_Base, From_Typ => Full);
+
          --  Propagate invariant-related attributes from the base type of the
          --  full view to the full view and vice versa. This may seem strange,
          --  but is necessary depending on which type triggered the generation
Index: sem_ch9.adb
===================================================================
--- sem_ch9.adb	(revision 244223)
+++ sem_ch9.adb	(working copy)
@@ -2212,6 +2212,11 @@ 
             Set_Must_Have_Preelab_Init (T);
          end if;
 
+         --  Propagate Default_Initial_Condition-related attributes from the
+         --  private type to the protected type.
+
+         Propagate_DIC_Attributes (T, From_Typ => Def_Id);
+
          --  Propagate invariant-related attributes from the private type to
          --  the protected type.
 
@@ -3146,6 +3151,11 @@ 
             Set_Must_Have_Preelab_Init (T);
          end if;
 
+         --  Propagate Default_Initial_Condition-related attributes from the
+         --  private type to the task type.
+
+         Propagate_DIC_Attributes (T, From_Typ => Def_Id);
+
          --  Propagate invariant-related attributes from the private type to
          --  task type.
 
Index: einfo.adb
===================================================================
--- einfo.adb	(revision 244223)
+++ einfo.adb	(working copy)
@@ -290,7 +290,7 @@ 
 
    --    Is_Inlined_Always               Flag1
    --    Is_Hidden_Non_Overridden_Subpgm Flag2
-   --    Has_Default_Init_Cond           Flag3
+   --    Has_Own_DIC                     Flag3
    --    Is_Frozen                       Flag4
    --    Has_Discriminants               Flag5
    --    Is_Dispatching_Operation        Flag6
@@ -432,8 +432,8 @@ 
    --    Is_Generic_Instance             Flag130
 
    --    No_Pool_Assigned                Flag131
-   --    Is_Default_Init_Cond_Procedure  Flag132
-   --    Has_Inherited_Default_Init_Cond Flag133
+   --    Is_DIC_Procedure                Flag132
+   --    Has_Inherited_DIC               Flag133
    --    Has_Aliased_Components          Flag135
    --    No_Strict_Aliasing              Flag136
    --    Is_Machine_Code_Subprogram      Flag137
@@ -1527,12 +1527,6 @@ 
       return Flag39 (Base_Type (Id));
    end Has_Default_Aspect;
 
-   function Has_Default_Init_Cond (Id : E) return B is
-   begin
-      pragma Assert (Is_Type (Id));
-      return Flag3 (Base_Type (Id));
-   end Has_Default_Init_Cond;
-
    function Has_Delayed_Aspects (Id : E) return B is
    begin
       pragma Assert (Nkind (Id) in N_Entity);
@@ -1619,19 +1613,19 @@ 
    function Has_Inheritable_Invariants (Id : E) return B is
    begin
       pragma Assert (Is_Type (Id));
-      return Flag248 (Id);
+      return Flag248 (Base_Type (Id));
    end Has_Inheritable_Invariants;
 
-   function Has_Inherited_Default_Init_Cond (Id : E) return B is
+   function Has_Inherited_DIC (Id : E) return B is
    begin
       pragma Assert (Is_Type (Id));
       return Flag133 (Base_Type (Id));
-   end Has_Inherited_Default_Init_Cond;
+   end Has_Inherited_DIC;
 
    function Has_Inherited_Invariants (Id : E) return B is
    begin
       pragma Assert (Is_Type (Id));
-      return Flag291 (Id);
+      return Flag291 (Base_Type (Id));
    end Has_Inherited_Invariants;
 
    function Has_Initial_Value (Id : E) return B is
@@ -1693,10 +1687,16 @@ 
       return Flag110 (Id);
    end Has_Out_Or_In_Out_Parameter;
 
+   function Has_Own_DIC (Id : E) return B is
+   begin
+      pragma Assert (Is_Type (Id));
+      return Flag3 (Base_Type (Id));
+   end Has_Own_DIC;
+
    function Has_Own_Invariants (Id : E) return B is
    begin
       pragma Assert (Is_Type (Id));
-      return Flag232 (Id);
+      return Flag232 (Base_Type (Id));
    end Has_Own_Invariants;
 
    function Has_Partial_Visible_Refinement (Id : E) return B is
@@ -2155,11 +2155,11 @@ 
       return Flag74 (Id);
    end Is_CPP_Class;
 
-   function Is_Default_Init_Cond_Procedure (Id : E) return B is
+   function Is_DIC_Procedure (Id : E) return B is
    begin
       pragma Assert (Ekind_In (Id, E_Function, E_Procedure));
       return Flag132 (Id);
-   end Is_Default_Init_Cond_Procedure;
+   end Is_DIC_Procedure;
 
    function Is_Descendant_Of_Address (Id : E) return B is
    begin
@@ -4563,12 +4563,6 @@ 
       Set_Flag39 (Id, V);
    end Set_Has_Default_Aspect;
 
-   procedure Set_Has_Default_Init_Cond (Id : E; V : B := True) is
-   begin
-      pragma Assert (Is_Type (Id));
-      Set_Flag3 (Base_Type (Id), V);
-   end Set_Has_Default_Init_Cond;
-
    procedure Set_Has_Delayed_Aspects (Id : E; V : B := True) is
    begin
       pragma Assert (Nkind (Id) in N_Entity);
@@ -4660,19 +4654,19 @@ 
    procedure Set_Has_Inheritable_Invariants (Id : E; V : B := True) is
    begin
       pragma Assert (Is_Type (Id));
-      Set_Flag248 (Id, V);
+      Set_Flag248 (Base_Type (Id), V);
    end Set_Has_Inheritable_Invariants;
 
-   procedure Set_Has_Inherited_Default_Init_Cond (Id : E; V : B := True) is
+   procedure Set_Has_Inherited_DIC (Id : E; V : B := True) is
    begin
       pragma Assert (Is_Type (Id));
       Set_Flag133 (Base_Type (Id), V);
-   end Set_Has_Inherited_Default_Init_Cond;
+   end Set_Has_Inherited_DIC;
 
    procedure Set_Has_Inherited_Invariants (Id : E; V : B := True) is
    begin
       pragma Assert (Is_Type (Id));
-      Set_Flag291 (Id, V);
+      Set_Flag291 (Base_Type (Id), V);
    end Set_Has_Inherited_Invariants;
 
    procedure Set_Has_Initial_Value (Id : E; V : B := True) is
@@ -4735,10 +4729,16 @@ 
       Set_Flag110 (Id, V);
    end Set_Has_Out_Or_In_Out_Parameter;
 
+   procedure Set_Has_Own_DIC (Id : E; V : B := True) is
+   begin
+      pragma Assert (Is_Type (Id));
+      Set_Flag3 (Base_Type (Id), V);
+   end Set_Has_Own_DIC;
+
    procedure Set_Has_Own_Invariants (Id : E; V : B := True) is
    begin
       pragma Assert (Is_Type (Id));
-      Set_Flag232 (Id, V);
+      Set_Flag232 (Base_Type (Id), V);
    end Set_Has_Own_Invariants;
 
    procedure Set_Has_Partial_Visible_Refinement (Id : E; V : B := True) is
@@ -5243,11 +5243,11 @@ 
       Set_Flag74 (Id, V);
    end Set_Is_CPP_Class;
 
-   procedure Set_Is_Default_Init_Cond_Procedure (Id : E; V : B := True) is
+   procedure Set_Is_DIC_Procedure (Id : E; V : B := True) is
    begin
       pragma Assert (Ekind (Id) = E_Procedure);
       Set_Flag132 (Id, V);
-   end Set_Is_Default_Init_Cond_Procedure;
+   end Set_Is_DIC_Procedure;
 
    procedure Set_Is_Descendant_Of_Address (Id : E; V : B := True) is
    begin
@@ -7053,39 +7053,6 @@ 
       end loop;
    end Declaration_Node;
 
-   ---------------------------------
-   -- Default_Init_Cond_Procedure --
-   ---------------------------------
-
-   function Default_Init_Cond_Procedure (Id : E) return E is
-      Subp_Elmt : Elmt_Id;
-      Subp_Id   : Entity_Id;
-      Subps     : Elist_Id;
-
-   begin
-      pragma Assert
-        (Is_Type (Id)
-          and then (Has_Default_Init_Cond (Id)
-                     or else Has_Inherited_Default_Init_Cond (Id)));
-
-      Subps := Subprograms_For_Type (Base_Type (Id));
-
-      if Present (Subps) then
-         Subp_Elmt := First_Elmt (Subps);
-         while Present (Subp_Elmt) loop
-            Subp_Id := Node (Subp_Elmt);
-
-            if Is_Default_Init_Cond_Procedure (Subp_Id) then
-               return Subp_Id;
-            end if;
-
-            Next_Elmt (Subp_Elmt);
-         end loop;
-      end if;
-
-      return Empty;
-   end Default_Init_Cond_Procedure;
-
    ---------------------
    -- Designated_Type --
    ---------------------
@@ -7113,6 +7080,36 @@ 
       end if;
    end Designated_Type;
 
+   -------------------
+   -- DIC_Procedure --
+   -------------------
+
+   function DIC_Procedure (Id : E) return E is
+      Subp_Elmt : Elmt_Id;
+      Subp_Id   : Entity_Id;
+      Subps     : Elist_Id;
+
+   begin
+      pragma Assert (Is_Type (Id));
+
+      Subps := Subprograms_For_Type (Base_Type (Id));
+
+      if Present (Subps) then
+         Subp_Elmt := First_Elmt (Subps);
+         while Present (Subp_Elmt) loop
+            Subp_Id := Node (Subp_Elmt);
+
+            if Is_DIC_Procedure (Subp_Id) then
+               return Subp_Id;
+            end if;
+
+            Next_Elmt (Subp_Elmt);
+         end loop;
+      end if;
+
+      return Empty;
+   end DIC_Procedure;
+
    ----------------------
    -- Entry_Index_Type --
    ----------------------
@@ -7430,6 +7427,15 @@ 
       return False;
    end Has_Attach_Handler;
 
+   -------------
+   -- Has_DIC --
+   -------------
+
+   function Has_DIC (Id : E) return B is
+   begin
+      return Has_Own_DIC (Id) or else Has_Inherited_DIC (Id);
+   end Has_DIC;
+
    -----------------
    -- Has_Entries --
    -----------------
@@ -7671,7 +7677,7 @@ 
    begin
       pragma Assert (Is_Type (Id));
 
-      Subps := Subprograms_For_Type (Id);
+      Subps := Subprograms_For_Type (Base_Type (Id));
 
       if Present (Subps) then
          Subp_Elmt := First_Elmt (Subps);
@@ -8407,7 +8413,7 @@ 
    begin
       pragma Assert (Is_Type (Id));
 
-      Subps := Subprograms_For_Type (Id);
+      Subps := Subprograms_For_Type (Base_Type (Id));
 
       if Present (Subps) then
          Subp_Elmt := First_Elmt (Subps);
@@ -8820,29 +8826,19 @@ 
       end case;
    end Set_Component_Alignment;
 
-   -------------------------------------
-   -- Set_Default_Init_Cond_Procedure --
-   -------------------------------------
+   -----------------------
+   -- Set_DIC_Procedure --
+   -----------------------
 
-   procedure Set_Default_Init_Cond_Procedure (Id : E; V : E) is
+   procedure Set_DIC_Procedure (Id : E; V : E) is
       Base_Typ  : Entity_Id;
       Subp_Elmt : Elmt_Id;
       Subp_Id   : Entity_Id;
       Subps     : Elist_Id;
 
    begin
-      --  Once set, this attribute cannot be reset
+      pragma Assert (Is_Type (Id));
 
-      if No (V) then
-         pragma Assert (No (Default_Init_Cond_Procedure (Id)));
-         return;
-      end if;
-
-      pragma Assert
-        (Is_Type (Id)
-          and then (Has_Default_Init_Cond (Id)
-                     or else Has_Inherited_Default_Init_Cond (Id)));
-
       Base_Typ := Base_Type (Id);
       Subps    := Subprograms_For_Type (Base_Typ);
 
@@ -8859,19 +8855,20 @@ 
       while Present (Subp_Elmt) loop
          Subp_Id := Node (Subp_Elmt);
 
-         if Is_Default_Init_Cond_Procedure (Subp_Id) then
+         if Is_DIC_Procedure (Subp_Id) then
             raise Program_Error;
          end if;
 
          Next_Elmt (Subp_Elmt);
       end loop;
-   end Set_Default_Init_Cond_Procedure;
+   end Set_DIC_Procedure;
 
    -----------------------------
    -- Set_Invariant_Procedure --
    -----------------------------
 
    procedure Set_Invariant_Procedure (Id : E; V : E) is
+      Base_Typ  : Entity_Id;
       Subp_Elmt : Elmt_Id;
       Subp_Id   : Entity_Id;
       Subps     : Elist_Id;
@@ -8879,11 +8876,12 @@ 
    begin
       pragma Assert (Is_Type (Id));
 
-      Subps := Subprograms_For_Type (Id);
+      Base_Typ := Base_Type (Id);
+      Subps    := Subprograms_For_Type (Base_Typ);
 
       if No (Subps) then
          Subps := New_Elmt_List;
-         Set_Subprograms_For_Type (Id, Subps);
+         Set_Subprograms_For_Type (Base_Typ, Subps);
       end if;
 
       Subp_Elmt := First_Elmt (Subps);
@@ -8907,6 +8905,7 @@ 
    -------------------------------------
 
    procedure Set_Partial_Invariant_Procedure (Id : E; V : E) is
+      Base_Typ  : Entity_Id;
       Subp_Elmt : Elmt_Id;
       Subp_Id   : Entity_Id;
       Subps     : Elist_Id;
@@ -8914,11 +8913,12 @@ 
    begin
       pragma Assert (Is_Type (Id));
 
-      Subps := Subprograms_For_Type (Id);
+      Base_Typ := Base_Type (Id);
+      Subps    := Subprograms_For_Type (Base_Typ);
 
       if No (Subps) then
          Subps := New_Elmt_List;
-         Set_Subprograms_For_Type (Id, Subps);
+         Set_Subprograms_For_Type (Base_Typ, Subps);
       end if;
 
       Subp_Elmt := First_Elmt (Subps);
@@ -9277,7 +9277,6 @@ 
       W ("Has_Controlling_Result",          Flag98  (Id));
       W ("Has_Convention_Pragma",           Flag119 (Id));
       W ("Has_Default_Aspect",              Flag39  (Id));
-      W ("Has_Default_Init_Cond",           Flag3   (Id));
       W ("Has_Delayed_Aspects",             Flag200 (Id));
       W ("Has_Delayed_Freeze",              Flag18  (Id));
       W ("Has_Delayed_Rep_Aspects",         Flag261 (Id));
@@ -9294,7 +9293,7 @@ 
       W ("Has_Implicit_Dereference",        Flag251 (Id));
       W ("Has_Independent_Components",      Flag34  (Id));
       W ("Has_Inheritable_Invariants",      Flag248 (Id));
-      W ("Has_Inherited_Default_Init_Cond", Flag133 (Id));
+      W ("Has_Inherited_DIC",               Flag133 (Id));
       W ("Has_Inherited_Invariants",        Flag291 (Id));
       W ("Has_Initial_Value",               Flag219 (Id));
       W ("Has_Loop_Entry_Attributes",       Flag260 (Id));
@@ -9306,6 +9305,7 @@ 
       W ("Has_Non_Standard_Rep",            Flag75  (Id));
       W ("Has_Out_Or_In_Out_Parameter",     Flag110 (Id));
       W ("Has_Object_Size_Clause",          Flag172 (Id));
+      W ("Has_Own_DIC",                     Flag3   (Id));
       W ("Has_Own_Invariants",              Flag232 (Id));
       W ("Has_Per_Object_Constraint",       Flag154 (Id));
       W ("Has_Pragma_Controlled",           Flag27  (Id));
@@ -9381,8 +9381,8 @@ 
       W ("Is_Constructor",                  Flag76  (Id));
       W ("Is_Controlled",                   Flag42  (Id));
       W ("Is_Controlling_Formal",           Flag97  (Id));
-      W ("Is_Default_Init_Cond_Procedure",  Flag132 (Id));
       W ("Is_Descendant_Of_Address",        Flag223 (Id));
+      W ("Is_DIC_Procedure",                Flag132 (Id));
       W ("Is_Discrim_SO_Function",          Flag176 (Id));
       W ("Is_Discriminant_Check_Function",  Flag264 (Id));
       W ("Is_Dispatch_Table_Entity",        Flag234 (Id));
Index: einfo.ads
===================================================================
--- einfo.ads	(revision 244223)
+++ einfo.ads	(working copy)
@@ -848,16 +848,6 @@ 
 --       default expressions (see Freeze.Process_Default_Expressions), which
 --       would not only waste time, but also generate false error messages.
 
---    Default_Init_Cond_Procedure (synthesized)
---       Defined in all types. Set for private [sub]types subject to pragma
---       Default_Initial_Condition, their corresponding full views and derived
---       types with at least one parent subject to the pragma. Contains the
---       entity of the procedure which takes a single argument of the given
---       type and verifies the assumption of the pragma.
---
---       Note: the reason this is marked as a synthesized attribute is that the
---       way this is stored is as an element of the Subprograms_For_Type field.
-
 --    Default_Value (Node20)
 --       Defined in formal parameters. Points to the node representing the
 --       expression for the default value for the parameter. Empty if the
@@ -932,6 +922,16 @@ 
 --       incomplete type, and the full type is available, then this full type
 --       is returned instead of the incomplete type.
 
+--    DIC_Procedure (synthesized)
+--       Defined in all type entities. Set for a private type and its full view
+--       when the type is subject to pragma Default_Initial_Condition (DIC), or
+--       when the type inherits a DIC pragma from a parent type. Points to the
+--       entity of a procedure which takes a single argument of the given type
+--       and verifies the assertion expression of the DIC pragma at runtime.
+
+--       Note: the reason this is marked as a synthesized attribute is that the
+--       way this is stored is as an element of the Subprograms_For_Type field.
+
 --    Digits_Value (Uint17)
 --       Defined in floating point types and subtypes and decimal types and
 --       subtypes. Contains the Digits value specified in the declaration.
@@ -1574,11 +1574,6 @@ 
 --       value is set, but it may be overridden by an aspect declaration on
 --       type derivation.
 
---    Has_Default_Init_Cond (Flag3) [base type only]
---       Defined in all type entities. Set if pragma Default_Initial_Condition
---       applies to a private type and by extension to its full view. This flag
---       is mutually exclusive with flag Has_Inherited_Default_Init_Cond.
-
 --    Has_Delayed_Aspects (Flag200)
 --      Defined in all entities. Set if the Rep_Item chain for the entity has
 --      one or more N_Aspect_Definition nodes chained which are not to be
@@ -1600,6 +1595,11 @@ 
 --       set, signalling that Freeze.Inherit_Delayed_Rep_Aspects must be called
 --       at the freeze point of the derived type.
 
+--    Has_DIC (syntherized)
+--       Defined in all type entities. Set for a private type and its full view
+--       when the type is subject to pragma Default_Initial_Condition (DIC), or
+--       when the type inherits a DIC pragma from a parent type.
+
 --    Has_Discriminants (Flag5)
 --       Defined in all types and subtypes. For types that are allowed to have
 --       discriminants (record types and subtypes, task types and subtypes,
@@ -1706,18 +1706,17 @@ 
 --       will be chained to the rep item chain of the first subtype in the
 --       usual manner.
 
---    Has_Inheritable_Invariants (Flag248)
+--    Has_Inheritable_Invariants (Flag248) [base type only]
 --       Defined in all type entities. Set on private types and interface types
 --       which define at least one class-wide invariant. Such invariants must
 --       be inherited by derived types. The flag is also set on the full view
 --       of a private type for completeness.
 
---    Has_Inherited_Default_Init_Cond (Flag133) [base type only]
---       Defined in all type entities. Set when a derived type inherits pragma
---       Default_Initial_Condition from its parent type. This flag is mutually
---       exclusive with flag Has_Default_Init_Cond.
+--    Has_Inherited_DIC (Flag133) [base type only]
+--       Defined in all type entities. Set for a derived type which inherits
+--       pragma Default_Initial_Condition from a parent type.
 
---    Has_Inherited_Invariants (Flag291)
+--    Has_Inherited_Invariants (Flag291) [base type only]
 --       Defined in all type entities. Set on private extensions and derived
 --       types which inherit at least on class-wide invariant from a parent or
 --       an interface type. The flag is also set on the full view of a private
@@ -1816,10 +1815,14 @@ 
 --       families. Set if they have at least one OUT or IN OUT parameter
 --       (allowed for functions only in Ada 2012).
 
---    Has_Own_Invariants (Flag232)
+--    Has_Own_DIC (Flag3) [base type only]
+--       Defined in all type entities. Set for a private type and its full view
+--       when the type is subject to pragma Default_Initial_Condition.
+
+--    Has_Own_Invariants (Flag232) [base type only]
 --       Defined in all type entities. Set on any type which defines at least
 --       one invariant of its own. The flag is also set on the full view of a
---       private extension or a private type for completeness.
+--       private type for completeness.
 
 --    Has_Partial_Visible_Refinement (Flag296)
 --       Defined in E_Abstract_State entities. Set when a state has at least
@@ -2422,14 +2425,15 @@ 
 --       Applies to all type entities, true for decimal fixed point
 --       types and subtypes.
 
---    Is_Default_Init_Cond_Procedure (Flag132)
---       Defined in functions and procedures. Set for a generated procedure
---       which verifies the assumption of pragma Default_Initial_Condition.
-
 --    Is_Descendant_Of_Address (Flag223)
 --       Defined in all entities. True if the entity is type System.Address,
 --       or (recursively) a subtype or derived type of System.Address.
 
+--    Is_DIC_Procedure (Flag132)
+--       Defined in functions and procedures. Set for a generated procedure
+--       which verifies the assumption of pragma Default_Initial_Condition at
+--       runtime.
+
 --    Is_Discrete_Or_Fixed_Point_Type (synthesized)
 --       Applies to all entities, true for all discrete types and subtypes
 --       and all fixed-point types and subtypes.
@@ -5558,16 +5562,16 @@ 
    --    Has_Constrained_Partial_View        (Flag187)
    --    Has_Controlled_Component            (Flag43)   (base type only)
    --    Has_Default_Aspect                  (Flag39)   (base type only)
-   --    Has_Default_Init_Cond               (Flag3)    (base type only)
    --    Has_Delayed_Rep_Aspects             (Flag261)
    --    Has_Discriminants                   (Flag5)
    --    Has_Dynamic_Predicate_Aspect        (Flag258)
    --    Has_Independent_Components          (Flag34)   (base type only)
    --    Has_Inheritable_Invariants          (Flag248)  (base type only)
-   --    Has_Inherited_Default_Init_Cond     (Flag133)  (base type only)
+   --    Has_Inherited_DIC                   (Flag133)  (base type only)
    --    Has_Inherited_Invariants            (Flag291)  (base type only)
    --    Has_Non_Standard_Rep                (Flag75)   (base type only)
    --    Has_Object_Size_Clause              (Flag172)
+   --    Has_Own_DIC                         (Flag3)    (base type only)
    --    Has_Own_Invariants                  (Flag232)  (base type only)
    --    Has_Pragma_Preelab_Init             (Flag221)
    --    Has_Pragma_Unreferenced_Objects     (Flag212)
@@ -5621,7 +5625,8 @@ 
 
    --    Alignment_Clause                    (synth)
    --    Base_Type                           (synth)
-   --    Default_Init_Cond_Procedure         (synth)
+   --    DIC_Procedure                       (synth)
+   --    Has_DIC                             (synth)
    --    Has_Invariants                      (synth)
    --    Implementation_Base_Type            (synth)
    --    Invariant_Procedure                 (synth)
@@ -6026,7 +6031,7 @@ 
    --    Is_Abstract_Subprogram              (Flag19)   (non-generic case only)
    --    Is_Called                           (Flag102)  (non-generic case only)
    --    Is_Constructor                      (Flag76)
-   --    Is_Default_Init_Cond_Procedure      (Flag132)  (non-generic case only)
+   --    Is_DIC_Procedure                    (Flag132)  (non-generic case only)
    --    Is_Discrim_SO_Function              (Flag176)
    --    Is_Discriminant_Check_Function      (Flag264)
    --    Is_Eliminated                       (Flag124)
@@ -6337,7 +6342,7 @@ 
    --    Is_Asynchronous                     (Flag81)
    --    Is_Called                           (Flag102)  (non-generic case only)
    --    Is_Constructor                      (Flag76)
-   --    Is_Default_Init_Cond_Procedure      (Flag132)  (non-generic case only)
+   --    Is_DIC_Procedure                    (Flag132)  (non-generic case only)
    --    Is_Eliminated                       (Flag124)
    --    Is_Generic_Actual_Subprogram        (Flag274)  (non-generic case only)
    --    Is_Hidden_Non_Overridden_Subpgm     (Flag2)    (non-generic case only)
@@ -6982,10 +6987,10 @@ 
    function Has_Controlling_Result              (Id : E) return B;
    function Has_Convention_Pragma               (Id : E) return B;
    function Has_Default_Aspect                  (Id : E) return B;
-   function Has_Default_Init_Cond               (Id : E) return B;
    function Has_Delayed_Aspects                 (Id : E) return B;
    function Has_Delayed_Freeze                  (Id : E) return B;
    function Has_Delayed_Rep_Aspects             (Id : E) return B;
+   function Has_DIC                             (Id : E) return B;
    function Has_Discriminants                   (Id : E) return B;
    function Has_Dispatch_Table                  (Id : E) return B;
    function Has_Dynamic_Predicate_Aspect        (Id : E) return B;
@@ -6999,7 +7004,7 @@ 
    function Has_Implicit_Dereference            (Id : E) return B;
    function Has_Independent_Components          (Id : E) return B;
    function Has_Inheritable_Invariants          (Id : E) return B;
-   function Has_Inherited_Default_Init_Cond     (Id : E) return B;
+   function Has_Inherited_DIC                   (Id : E) return B;
    function Has_Inherited_Invariants            (Id : E) return B;
    function Has_Initial_Value                   (Id : E) return B;
    function Has_Interrupt_Handler               (Id : E) return B;
@@ -7013,6 +7018,7 @@ 
    function Has_Non_Standard_Rep                (Id : E) return B;
    function Has_Object_Size_Clause              (Id : E) return B;
    function Has_Out_Or_In_Out_Parameter         (Id : E) return B;
+   function Has_Own_DIC                         (Id : E) return B;
    function Has_Own_Invariants                  (Id : E) return B;
    function Has_Partial_Visible_Refinement      (Id : E) return B;
    function Has_Per_Object_Constraint           (Id : E) return B;
@@ -7098,8 +7104,8 @@ 
    function Is_Controlled                       (Id : E) return B;
    function Is_Controlling_Formal               (Id : E) return B;
    function Is_CPP_Class                        (Id : E) return B;
-   function Is_Default_Init_Cond_Procedure      (Id : E) return B;
    function Is_Descendant_Of_Address            (Id : E) return B;
+   function Is_DIC_Procedure                    (Id : E) return B;
    function Is_Discrim_SO_Function              (Id : E) return B;
    function Is_Discriminant_Check_Function      (Id : E) return B;
    function Is_Dispatch_Table_Entity            (Id : E) return B;
@@ -7664,7 +7670,6 @@ 
    procedure Set_Has_Controlling_Result          (Id : E; V : B := True);
    procedure Set_Has_Convention_Pragma           (Id : E; V : B := True);
    procedure Set_Has_Default_Aspect              (Id : E; V : B := True);
-   procedure Set_Has_Default_Init_Cond           (Id : E; V : B := True);
    procedure Set_Has_Delayed_Aspects             (Id : E; V : B := True);
    procedure Set_Has_Delayed_Freeze              (Id : E; V : B := True);
    procedure Set_Has_Delayed_Rep_Aspects         (Id : E; V : B := True);
@@ -7681,7 +7686,7 @@ 
    procedure Set_Has_Implicit_Dereference        (Id : E; V : B := True);
    procedure Set_Has_Independent_Components      (Id : E; V : B := True);
    procedure Set_Has_Inheritable_Invariants      (Id : E; V : B := True);
-   procedure Set_Has_Inherited_Default_Init_Cond (Id : E; V : B := True);
+   procedure Set_Has_Inherited_DIC               (Id : E; V : B := True);
    procedure Set_Has_Inherited_Invariants        (Id : E; V : B := True);
    procedure Set_Has_Initial_Value               (Id : E; V : B := True);
    procedure Set_Has_Loop_Entry_Attributes       (Id : E; V : B := True);
@@ -7693,6 +7698,7 @@ 
    procedure Set_Has_Non_Standard_Rep            (Id : E; V : B := True);
    procedure Set_Has_Object_Size_Clause          (Id : E; V : B := True);
    procedure Set_Has_Out_Or_In_Out_Parameter     (Id : E; V : B := True);
+   procedure Set_Has_Own_DIC                     (Id : E; V : B := True);
    procedure Set_Has_Own_Invariants              (Id : E; V : B := True);
    procedure Set_Has_Partial_Visible_Refinement  (Id : E; V : B := True);
    procedure Set_Has_Per_Object_Constraint       (Id : E; V : B := True);
@@ -7778,8 +7784,8 @@ 
    procedure Set_Is_Controlled                   (Id : E; V : B := True);
    procedure Set_Is_Controlling_Formal           (Id : E; V : B := True);
    procedure Set_Is_CPP_Class                    (Id : E; V : B := True);
-   procedure Set_Is_Default_Init_Cond_Procedure  (Id : E; V : B := True);
    procedure Set_Is_Descendant_Of_Address        (Id : E; V : B := True);
+   procedure Set_Is_DIC_Procedure                (Id : E; V : B := True);
    procedure Set_Is_Discrim_SO_Function          (Id : E; V : B := True);
    procedure Set_Is_Discriminant_Check_Function  (Id : E; V : B := True);
    procedure Set_Is_Dispatch_Table_Entity        (Id : E; V : B := True);
@@ -8009,17 +8015,17 @@ 
    -- Access to Subprograms in Subprograms_For_Type --
    ---------------------------------------------------
 
-   function Default_Init_Cond_Procedure         (Id : E) return E;
-   function Invariant_Procedure                 (Id : E) return E;
-   function Partial_Invariant_Procedure         (Id : E) return E;
-   function Predicate_Function                  (Id : E) return E;
-   function Predicate_Function_M                (Id : E) return E;
+   function DIC_Procedure                        (Id : E) return E;
+   function Invariant_Procedure                  (Id : E) return E;
+   function Partial_Invariant_Procedure          (Id : E) return E;
+   function Predicate_Function                   (Id : E) return E;
+   function Predicate_Function_M                 (Id : E) return E;
 
-   procedure Set_Default_Init_Cond_Procedure    (Id : E; V : E);
-   procedure Set_Invariant_Procedure            (Id : E; V : E);
-   procedure Set_Partial_Invariant_Procedure    (Id : E; V : E);
-   procedure Set_Predicate_Function             (Id : E; V : E);
-   procedure Set_Predicate_Function_M           (Id : E; V : E);
+   procedure Set_DIC_Procedure                   (Id : E; V : E);
+   procedure Set_Invariant_Procedure             (Id : E; V : E);
+   procedure Set_Partial_Invariant_Procedure     (Id : E; V : E);
+   procedure Set_Predicate_Function              (Id : E; V : E);
+   procedure Set_Predicate_Function_M            (Id : E; V : E);
 
    -----------------------------------
    -- Field Initialization Routines --
@@ -8459,7 +8465,6 @@ 
    pragma Inline (Has_Controlling_Result);
    pragma Inline (Has_Convention_Pragma);
    pragma Inline (Has_Default_Aspect);
-   pragma Inline (Has_Default_Init_Cond);
    pragma Inline (Has_Delayed_Aspects);
    pragma Inline (Has_Delayed_Freeze);
    pragma Inline (Has_Delayed_Rep_Aspects);
@@ -8476,7 +8481,7 @@ 
    pragma Inline (Has_Implicit_Dereference);
    pragma Inline (Has_Independent_Components);
    pragma Inline (Has_Inheritable_Invariants);
-   pragma Inline (Has_Inherited_Default_Init_Cond);
+   pragma Inline (Has_Inherited_DIC);
    pragma Inline (Has_Inherited_Invariants);
    pragma Inline (Has_Initial_Value);
    pragma Inline (Has_Loop_Entry_Attributes);
@@ -8488,6 +8493,7 @@ 
    pragma Inline (Has_Non_Standard_Rep);
    pragma Inline (Has_Object_Size_Clause);
    pragma Inline (Has_Out_Or_In_Out_Parameter);
+   pragma Inline (Has_Own_DIC);
    pragma Inline (Has_Own_Invariants);
    pragma Inline (Has_Partial_Visible_Refinement);
    pragma Inline (Has_Per_Object_Constraint);
@@ -8584,8 +8590,8 @@ 
    pragma Inline (Is_Controlling_Formal);
    pragma Inline (Is_CPP_Class);
    pragma Inline (Is_Decimal_Fixed_Point_Type);
-   pragma Inline (Is_Default_Init_Cond_Procedure);
    pragma Inline (Is_Descendant_Of_Address);
+   pragma Inline (Is_DIC_Procedure);
    pragma Inline (Is_Digits_Type);
    pragma Inline (Is_Discrete_Or_Fixed_Point_Type);
    pragma Inline (Is_Discrete_Type);
@@ -8978,7 +8984,6 @@ 
    pragma Inline (Set_Has_Controlling_Result);
    pragma Inline (Set_Has_Convention_Pragma);
    pragma Inline (Set_Has_Default_Aspect);
-   pragma Inline (Set_Has_Default_Init_Cond);
    pragma Inline (Set_Has_Delayed_Aspects);
    pragma Inline (Set_Has_Delayed_Freeze);
    pragma Inline (Set_Has_Delayed_Rep_Aspects);
@@ -8995,7 +9000,7 @@ 
    pragma Inline (Set_Has_Implicit_Dereference);
    pragma Inline (Set_Has_Independent_Components);
    pragma Inline (Set_Has_Inheritable_Invariants);
-   pragma Inline (Set_Has_Inherited_Default_Init_Cond);
+   pragma Inline (Set_Has_Inherited_DIC);
    pragma Inline (Set_Has_Inherited_Invariants);
    pragma Inline (Set_Has_Initial_Value);
    pragma Inline (Set_Has_Loop_Entry_Attributes);
@@ -9007,6 +9012,7 @@ 
    pragma Inline (Set_Has_Non_Standard_Rep);
    pragma Inline (Set_Has_Object_Size_Clause);
    pragma Inline (Set_Has_Out_Or_In_Out_Parameter);
+   pragma Inline (Set_Has_Own_DIC);
    pragma Inline (Set_Has_Own_Invariants);
    pragma Inline (Set_Has_Partial_Visible_Refinement);
    pragma Inline (Set_Has_Per_Object_Constraint);
@@ -9090,8 +9096,8 @@ 
    pragma Inline (Set_Is_Controlled);
    pragma Inline (Set_Is_Controlling_Formal);
    pragma Inline (Set_Is_CPP_Class);
-   pragma Inline (Set_Is_Default_Init_Cond_Procedure);
    pragma Inline (Set_Is_Descendant_Of_Address);
+   pragma Inline (Set_Is_DIC_Procedure);
    pragma Inline (Set_Is_Discrim_SO_Function);
    pragma Inline (Set_Is_Discriminant_Check_Function);
    pragma Inline (Set_Is_Dispatch_Table_Entity);
Index: sem_prag.adb
===================================================================
--- sem_prag.adb	(revision 244223)
+++ sem_prag.adb	(working copy)
@@ -89,8 +89,6 @@ 
 with Validsw;   use Validsw;
 with Warnsw;    use Warnsw;
 
-with GNAT.HTable; use GNAT.HTable;
-
 package body Sem_Prag is
 
    ----------------------------------------------
@@ -166,40 +164,6 @@ 
      Table_Increment      => 100,
      Table_Name           => "Name_Externals");
 
-   ---------------------------------------------------------
-   -- Handling of inherited class-wide pre/postconditions --
-   ---------------------------------------------------------
-
-   --  Following AI12-0113, the expression for a class-wide condition is
-   --  transformed for a subprogram that inherits it, by replacing calls
-   --  to primitive operations of the original controlling type into the
-   --  corresponding overriding operations of the derived type. The following
-   --  hash table manages this mapping, and is expanded on demand whenever
-   --  such inherited expression needs to be constructed.
-
-   --  The mapping is also used to check whether an inherited operation has
-   --  a condition that depends on overridden operations. For such an
-   --  operation we must create a wrapper that is then treated as a normal
-   --  overriding. In SPARK mode such operations are illegal.
-
-   --  For a given root type there may be several type extensions with their
-   --  own overriding operations, so at various times a given operation of
-   --  the root will be mapped into different overridings. The root type is
-   --  also mapped into the current type extension to indicate that its
-   --  operations are mapped into the overriding operations of that current
-   --  type extension.
-
-   subtype Num_Primitives is Integer range 0 .. 510;
-   function Entity_Hash (E : Entity_Id) return Num_Primitives;
-
-   package Primitives_Mapping is new Gnat.HTable.Simple_Htable
-     (Header_Num => Num_Primitives,
-      Key        => Entity_Id,
-      Element    => Entity_Id,
-      No_element => Empty,
-      Hash       => Entity_Hash,
-      Equal      => "=");
-
    -------------------------------------
    -- Local Subprograms and Variables --
    -------------------------------------
@@ -13784,7 +13748,7 @@ 
 
          --  pragma Default_Initial_Condition [ (null | boolean_EXPRESSION) ];
 
-         when Pragma_Default_Initial_Condition => Default_Init_Cond : declare
+         when Pragma_Default_Initial_Condition => DIC : declare
             Discard : Boolean;
             Stmt    : Node_Id;
             Typ     : Entity_Id;
@@ -13835,14 +13799,22 @@ 
             --  purposes of legality checks and removal of ignored Ghost code.
 
             Mark_Pragma_As_Ghost (N, Typ);
-            Set_Has_Default_Init_Cond (Typ);
-            Set_Has_Inherited_Default_Init_Cond (Typ, False);
 
+            --  The pragma signals that the type defines its own DIC assertion
+            --  expression.
+
+            Set_Has_Own_DIC (Typ);
+
             --  Chain the pragma on the rep item chain for further processing
 
             Discard := Rep_Item_Too_Late (Typ, N, FOnly => True);
-         end Default_Init_Cond;
 
+            --  Create the declaration of the procedure which verifies the
+            --  assertion expression of pragma DIC at runtime.
+
+            Build_DIC_Procedure_Declaration (Typ);
+         end DIC;
+
          ----------------------------------
          -- Default_Scalar_Storage_Order --
          ----------------------------------
@@ -16819,18 +16791,6 @@ 
             Typ     : Entity_Id;
             Typ_Arg : Node_Id;
 
-            CRec_Typ : Entity_Id;
-            --  The corresponding record type of Full_Typ
-
-            Full_Base : Entity_Id;
-            --  The base type of Full_Typ
-
-            Full_Typ : Entity_Id;
-            --  The full view of Typ
-
-            Priv_Typ : Entity_Id;
-            --  The partial view of Typ
-
          begin
             GNAT_Pragma;
             Check_At_Least_N_Arguments (2);
@@ -16924,16 +16884,6 @@ 
                Set_Has_Inheritable_Invariants (Typ);
             end if;
 
-            Get_Views (Typ, Priv_Typ, Full_Typ, Full_Base, CRec_Typ);
-
-            --  Propagate invariant-related attributes to all views of the type
-            --  and any additional types that may have been created.
-
-            Propagate_Invariant_Attributes (Priv_Typ,  From_Typ => Typ);
-            Propagate_Invariant_Attributes (Full_Typ,  From_Typ => Typ);
-            Propagate_Invariant_Attributes (Full_Base, From_Typ => Typ);
-            Propagate_Invariant_Attributes (CRec_Typ,  From_Typ => Typ);
-
             --  Chain the pragma on to the rep item chain, for processing when
             --  the type is frozen.
 
@@ -26766,140 +26716,6 @@ 
       return False;
    end Appears_In;
 
-   ---------------------------------
-   -- Build_Class_Wide_Expression --
-   ---------------------------------
-
-   procedure Build_Class_Wide_Expression
-     (Prag        : Node_Id;
-      Subp        : Entity_Id;
-      Par_Subp    : Entity_Id;
-      Adjust_Sloc : Boolean)
-   is
-      function Replace_Entity (N : Node_Id) return Traverse_Result;
-      --  Replace reference to formal of inherited operation or to primitive
-      --  operation of root type, with corresponding entity for derived type,
-      --  when constructing the class-wide condition of an overriding
-      --  subprogram.
-
-      --------------------
-      -- Replace_Entity --
-      --------------------
-
-      function Replace_Entity (N : Node_Id) return Traverse_Result is
-         New_E : Entity_Id;
-
-      begin
-         if Adjust_Sloc then
-            Adjust_Inherited_Pragma_Sloc (N);
-         end if;
-
-         if Nkind (N) = N_Identifier
-           and then Present (Entity (N))
-           and then
-             (Is_Formal (Entity (N)) or else Is_Subprogram (Entity (N)))
-           and then
-             (Nkind (Parent (N)) /= N_Attribute_Reference
-               or else Attribute_Name (Parent (N)) /= Name_Class)
-         then
-            --  The replacement does not apply to dispatching calls within the
-            --  condition, but only to calls whose static tag is that of the
-            --  parent type.
-
-            if Is_Subprogram (Entity (N))
-              and then Nkind (Parent (N)) = N_Function_Call
-              and then Present (Controlling_Argument (Parent (N)))
-            then
-               return OK;
-            end if;
-
-            --  Determine whether entity has a renaming
-
-            New_E := Primitives_Mapping.Get (Entity (N));
-
-            if Present (New_E) then
-               Rewrite (N, New_Occurrence_Of (New_E, Sloc (N)));
-            end if;
-
-            --  Check that there are no calls left to abstract operations if
-            --  the current subprogram is not abstract.
-
-            if Nkind (Parent (N)) = N_Function_Call
-              and then N = Name (Parent (N))
-            then
-               if not Is_Abstract_Subprogram (Subp)
-                 and then Is_Abstract_Subprogram (Entity (N))
-               then
-                  Error_Msg_Sloc := Sloc (Current_Scope);
-                  Error_Msg_NE
-                    ("cannot call abstract subprogram in inherited condition "
-                      & "for&#", N, Current_Scope);
-
-               --  In SPARK mode, reject an inherited condition for an
-               --  inherited operation if it contains a call to an overriding
-               --  operation, because this implies that the pre/postcondition
-               --  of the inherited operation have changed silently.
-
-               elsif SPARK_Mode = On
-                 and then Warn_On_Suspicious_Contract
-                 and then Present (Alias (Subp))
-                 and then Present (New_E)
-                 and then Comes_From_Source (New_E)
-               then
-                  Error_Msg_N
-                    ("cannot modify inherited condition (SPARK RM 6.1.1(1))",
-                     Parent (Subp));
-                  Error_Msg_Sloc   := Sloc (New_E);
-                  Error_Msg_Node_2 := Subp;
-                  Error_Msg_NE
-                    ("\overriding of&# forces overriding of&",
-                     Parent (Subp), New_E);
-               end if;
-            end if;
-
-            --  Update type of function call node, which should be the same as
-            --  the function's return type.
-
-            if Is_Subprogram (Entity (N))
-              and then Nkind (Parent (N)) = N_Function_Call
-            then
-               Set_Etype (Parent (N), Etype (Entity (N)));
-            end if;
-
-         --  The whole expression will be reanalyzed
-
-         elsif Nkind (N) in N_Has_Etype then
-            Set_Analyzed (N, False);
-         end if;
-
-         return OK;
-      end Replace_Entity;
-
-      procedure Replace_Condition_Entities is
-        new Traverse_Proc (Replace_Entity);
-
-      --  Local variables
-
-      Par_Formal  : Entity_Id;
-      Subp_Formal : Entity_Id;
-
-   --  Start of processing for Build_Class_Wide_Expression
-
-   begin
-      --  Add mapping from old formals to new formals
-
-      Par_Formal := First_Formal (Par_Subp);
-      Subp_Formal  := First_Formal (Subp);
-
-      while Present (Par_Formal) and then Present (Subp_Formal) loop
-         Primitives_Mapping.Set (Par_Formal, Subp_Formal);
-         Next_Formal (Par_Formal);
-         Next_Formal (Subp_Formal);
-      end loop;
-
-      Replace_Condition_Entities (Prag);
-   end Build_Class_Wide_Expression;
-
    -----------------------------------
    -- Build_Pragma_Check_Equivalent --
    -----------------------------------
@@ -27930,15 +27746,6 @@ 
       end if;
    end Duplication_Error;
 
-   -----------------
-   -- Entity_Hash --
-   -----------------
-
-   function Entity_Hash (E : Entity_Id) return Num_Primitives is
-   begin
-      return Num_Primitives (E mod 511);
-   end Entity_Hash;
-
    ------------------------------
    -- Find_Encapsulating_State --
    ------------------------------
@@ -29780,145 +29587,4 @@ 
       return Empty;
    end Test_Case_Arg;
 
-   -------------------------------
-   -- Update_Primitives_Mapping --
-   -------------------------------
-
-   procedure Update_Primitives_Mapping
-     (Inher_Id : Entity_Id;
-      Subp_Id  : Entity_Id)
-   is
-      function Overridden_Ancestor (S : Entity_Id) return Entity_Id;
-      --  Locate the primitive operation with the name of S whose controlling
-      --  type is the dispatching type of Inher_Id.
-
-      -------------------------
-      -- Overridden_Ancestor --
-      -------------------------
-
-      function Overridden_Ancestor (S : Entity_Id) return Entity_Id is
-         Par : constant Entity_Id := Find_Dispatching_Type (Inher_Id);
-         Anc : Entity_Id;
-
-      begin
-         Anc := S;
-
-         --  Locate the ancestor subprogram with the proper controlling type
-
-         while Present (Overridden_Operation (Anc)) loop
-            Anc := Overridden_Operation (Anc);
-            exit when Find_Dispatching_Type (Anc) = Par;
-         end loop;
-
-         return Anc;
-      end Overridden_Ancestor;
-
-      --  Local variables
-
-      Old_Typ  : constant Entity_Id := Find_Dispatching_Type (Inher_Id);
-      Typ      : constant Entity_Id := Find_Dispatching_Type (Subp_Id);
-      Decl     : Node_Id;
-      Old_Elmt : Elmt_Id;
-      Old_Prim : Entity_Id;
-      Prim     : Entity_Id;
-
-   --  Start of processing for Update_Primitives_Mapping
-
-   begin
-      --  If the types are already in the map, it has been previously built for
-      --  some other overriding primitive.
-
-      if Primitives_Mapping.Get (Old_Typ) = Typ then
-         return;
-
-      else
-         --  Initialize new mapping with the primitive operations
-
-         Decl := First (List_Containing (Unit_Declaration_Node (Subp_Id)));
-
-         --  Look for primitive operations of the current type that have
-         --  overridden an operation of the type related to the original
-         --  class-wide precondition. There may be several intermediate
-         --  overridings between them.
-
-         while Present (Decl) loop
-            if Nkind_In (Decl, N_Abstract_Subprogram_Declaration,
-                               N_Subprogram_Declaration)
-            then
-               Prim := Defining_Entity (Decl);
-
-               if Is_Subprogram (Prim)
-                 and then Present (Overridden_Operation (Prim))
-                 and then Find_Dispatching_Type (Prim) = Typ
-               then
-                  Old_Prim := Overridden_Ancestor (Prim);
-
-                  Primitives_Mapping.Set (Old_Prim, Prim);
-               end if;
-            end if;
-
-            Next (Decl);
-         end loop;
-
-         --  Now examine inherited operations. these do not override, but have
-         --  an alias, which is the entity used in a call. That alias may be
-         --  inherited or come from source, in which case it may override an
-         --  earlier operation. We only need to examine inherited functions,
-         --  that can appear within the inherited expression.
-
-         Prim := First_Entity (Scope (Subp_Id));
-         while Present (Prim) loop
-            if not Comes_From_Source (Prim)
-              and then Ekind (Prim) = E_Function
-              and then Present (Alias (Prim))
-            then
-               Old_Prim := Alias (Prim);
-
-               if Comes_From_Source (Old_Prim) then
-                  Old_Prim := Overridden_Ancestor (Old_Prim);
-
-               else
-                  while Present (Alias (Old_Prim))
-                    and then Scope (Old_Prim) /= Scope (Inher_Id)
-                  loop
-                     Old_Prim := Alias (Old_Prim);
-
-                     if Comes_From_Source (Old_Prim) then
-                        Old_Prim := Overridden_Ancestor (Old_Prim);
-                        exit;
-                     end if;
-                  end loop;
-               end if;
-
-               Primitives_Mapping.Set (Old_Prim, Prim);
-            end if;
-
-            Next_Entity (Prim);
-         end loop;
-
-         --  If the parent operation is an interface operation, the overriding
-         --  indicator is not present. Instead, we get from the interface
-         --  operation the primitive of the current type that implements it.
-
-         if Is_Interface (Old_Typ) then
-            Old_Elmt := First_Elmt (Collect_Primitive_Operations (Old_Typ));
-            while Present (Old_Elmt) loop
-               Old_Prim := Node (Old_Elmt);
-               Prim := Find_Primitive_Covering_Interface (Typ, Old_Prim);
-
-               if Present (Prim) then
-                  Primitives_Mapping.Set (Old_Prim, Prim);
-               end if;
-
-               Next_Elmt (Old_Elmt);
-            end loop;
-         end if;
-      end if;
-
-      --  Map the types themselves, so that the process is not repeated for
-      --  other overriding primitives.
-
-      Primitives_Mapping.Set (Old_Typ, Typ);
-   end Update_Primitives_Mapping;
-
 end Sem_Prag;
Index: sem_prag.ads
===================================================================
--- sem_prag.ads	(revision 244223)
+++ sem_prag.ads	(working copy)
@@ -244,24 +244,6 @@ 
    procedure Analyze_Test_Case_In_Decl_Part (N : Node_Id);
    --  Perform preanalysis of pragma Test_Case
 
-   procedure Build_Class_Wide_Expression
-     (Prag        : Node_Id;
-      Subp        : Entity_Id;
-      Par_Subp    : Entity_Id;
-      Adjust_Sloc : Boolean);
-   --  Build the expression for an inherited class-wide condition. Prag is
-   --  the pragma constructed from the corresponding aspect of the parent
-   --  subprogram, and Subp is the overriding operation and Par_Subp is
-   --  the overridden operation that has the condition. Adjust_Sloc is True
-   --  when the sloc of nodes traversed should be adjusted for the inherited
-   --  pragma. The routine is also called to check whether an inherited
-   --  operation that is not overridden but has inherited conditions need
-   --  a wrapper, because the inherited condition includes calls to other
-   --  primitives that have been overridden. In that case the first argument
-   --  is the expression of the original class-wide aspect. In SPARK_Mode, such
-   --  operation which are just inherited but have modified pre/postconditions
-   --  are illegal.
-
    function Build_Pragma_Check_Equivalent
      (Prag           : Node_Id;
       Subp_Id        : Entity_Id := Empty;
@@ -543,13 +525,4 @@ 
    --
    --    Empty if there is no such argument
 
-   procedure Update_Primitives_Mapping
-     (Inher_Id : Entity_Id;
-      Subp_Id  : Entity_Id);
-   --  Map primitive operations of the parent type to the corresponding
-   --  operations of the descendant. Note that the descendant type may not be
-   --  frozen yet, so we cannot use the dispatch table directly. This is called
-   --  when elaborating a contract for a subprogram, and when freezing a type
-   --  extension to verify legality rules on inherited conditions.
-
 end Sem_Prag;
Index: sem_util.adb
===================================================================
--- sem_util.adb	(revision 244223)
+++ sem_util.adb	(working copy)
@@ -37,7 +37,6 @@ 
 with Exp_Util; use Exp_Util;
 with Fname;    use Fname;
 with Freeze;   use Freeze;
-with Ghost;    use Ghost;
 with Lib;      use Lib;
 with Lib.Xref; use Lib.Xref;
 with Namet.Sp; use Namet.Sp;
@@ -52,7 +51,6 @@ 
 with Sem_Attr; use Sem_Attr;
 with Sem_Ch6;  use Sem_Ch6;
 with Sem_Ch8;  use Sem_Ch8;
-with Sem_Ch13; use Sem_Ch13;
 with Sem_Disp; use Sem_Disp;
 with Sem_Eval; use Sem_Eval;
 with Sem_Prag; use Sem_Prag;
@@ -1194,294 +1192,6 @@ 
       return Decl;
    end Build_Component_Subtype;
 
-   ----------------------------------
-   -- Build_Default_Init_Cond_Call --
-   ----------------------------------
-
-   function Build_Default_Init_Cond_Call
-     (Loc    : Source_Ptr;
-      Obj_Id : Entity_Id;
-      Typ    : Entity_Id) return Node_Id
-   is
-      Proc_Id    : constant Entity_Id := Default_Init_Cond_Procedure (Typ);
-      Formal_Typ : constant Entity_Id := Etype (First_Formal (Proc_Id));
-
-   begin
-      return
-        Make_Procedure_Call_Statement (Loc,
-          Name                   => New_Occurrence_Of (Proc_Id, Loc),
-          Parameter_Associations => New_List (
-            Make_Unchecked_Type_Conversion (Loc,
-              Subtype_Mark => New_Occurrence_Of (Formal_Typ, Loc),
-              Expression   => New_Occurrence_Of (Obj_Id, Loc))));
-   end Build_Default_Init_Cond_Call;
-
-   ----------------------------------------------
-   -- Build_Default_Init_Cond_Procedure_Bodies --
-   ----------------------------------------------
-
-   procedure Build_Default_Init_Cond_Procedure_Bodies (Priv_Decls : List_Id) is
-      procedure Build_Default_Init_Cond_Procedure_Body (Typ : Entity_Id);
-      --  If type Typ is subject to pragma Default_Initial_Condition, build the
-      --  body of the procedure which verifies the assumption of the pragma at
-      --  run time. The generated body is added after the type declaration.
-
-      --------------------------------------------
-      -- Build_Default_Init_Cond_Procedure_Body --
-      --------------------------------------------
-
-      procedure Build_Default_Init_Cond_Procedure_Body (Typ : Entity_Id) is
-         Param_Id : Entity_Id;
-         --  The entity of the sole formal parameter of the default initial
-         --  condition procedure.
-
-         procedure Replace_Type_Reference (N : Node_Id);
-         --  Replace a single reference to type Typ with a reference to formal
-         --  parameter Param_Id.
-
-         ----------------------------
-         -- Replace_Type_Reference --
-         ----------------------------
-
-         procedure Replace_Type_Reference (N : Node_Id) is
-         begin
-            Rewrite (N, New_Occurrence_Of (Param_Id, Sloc (N)));
-         end Replace_Type_Reference;
-
-         procedure Replace_Type_References is
-           new Replace_Type_References_Generic (Replace_Type_Reference);
-
-         --  Local variables
-
-         Loc       : constant Source_Ptr := Sloc (Typ);
-         Prag      : constant Node_Id    :=
-                       Get_Pragma (Typ, Pragma_Default_Initial_Condition);
-         Proc_Id   : constant Entity_Id  := Default_Init_Cond_Procedure (Typ);
-         Body_Decl : Node_Id;
-         Expr      : Node_Id;
-         Spec_Decl : Node_Id;
-         Stmt      : Node_Id;
-
-         Save_Ghost_Mode : constant Ghost_Mode_Type := Ghost_Mode;
-
-      --  Start of processing for Build_Default_Init_Cond_Procedure_Body
-
-      begin
-         --  The procedure should be generated only for [sub]types subject to
-         --  pragma Default_Initial_Condition. Types that inherit the pragma do
-         --  not get this specialized procedure.
-
-         pragma Assert (Has_Default_Init_Cond (Typ));
-         pragma Assert (Present (Prag));
-
-         --  Nothing to do if the spec was not built. This occurs when the
-         --  expression of the Default_Initial_Condition is missing or is
-         --  null.
-
-         if No (Proc_Id) then
-            return;
-
-         --  Nothing to do if the body was already built
-
-         elsif Present (Corresponding_Body (Unit_Declaration_Node (Proc_Id)))
-         then
-            return;
-         end if;
-
-         --  The related type may be subject to pragma Ghost. Set the mode now
-         --  to ensure that the analysis and expansion produce Ghost nodes.
-
-         Set_Ghost_Mode_From_Entity (Typ);
-
-         Param_Id := First_Formal (Proc_Id);
-
-         --  The pragma has an argument. Note that the argument is analyzed
-         --  after all references to the current instance of the type are
-         --  replaced.
-
-         if Present (Pragma_Argument_Associations (Prag)) then
-            Expr :=
-              Get_Pragma_Arg (First (Pragma_Argument_Associations (Prag)));
-
-            if Nkind (Expr) = N_Null then
-               Stmt := Make_Null_Statement (Loc);
-
-            --  Preserve the original argument of the pragma by replicating it.
-            --  Replace all references to the current instance of the type with
-            --  references to the formal parameter.
-
-            else
-               Expr := New_Copy_Tree (Expr);
-               Replace_Type_References (Expr, Typ);
-
-               --  Generate:
-               --    pragma Check (Default_Initial_Condition, <Expr>);
-
-               Stmt :=
-                 Make_Pragma (Loc,
-                   Chars            => Name_Check,
-                   Pragma_Argument_Associations => New_List (
-                     Make_Pragma_Argument_Association (Loc,
-                       Expression =>
-                         Make_Identifier (Loc,
-                           Chars => Name_Default_Initial_Condition)),
-                     Make_Pragma_Argument_Association (Loc,
-                       Expression => Expr)));
-            end if;
-
-         --  Otherwise the pragma appears without an argument
-
-         else
-            Stmt := Make_Null_Statement (Loc);
-         end if;
-
-         --  Generate:
-         --    procedure <Typ>Default_Init_Cond (I : <Typ>) is
-         --    begin
-         --       <Stmt>;
-         --    end <Typ>Default_Init_Cond;
-
-         Spec_Decl := Unit_Declaration_Node (Proc_Id);
-         Body_Decl :=
-           Make_Subprogram_Body (Loc,
-             Specification              =>
-               Copy_Separate_Tree (Specification (Spec_Decl)),
-             Declarations               => Empty_List,
-             Handled_Statement_Sequence =>
-               Make_Handled_Sequence_Of_Statements (Loc,
-                 Statements => New_List (Stmt)));
-
-         --  Link the spec and body of the default initial condition procedure
-         --  to prevent the generation of a duplicate body.
-
-         Set_Corresponding_Body (Spec_Decl, Defining_Entity (Body_Decl));
-         Set_Corresponding_Spec (Body_Decl, Proc_Id);
-
-         Insert_After_And_Analyze (Declaration_Node (Typ), Body_Decl);
-         Ghost_Mode := Save_Ghost_Mode;
-      end Build_Default_Init_Cond_Procedure_Body;
-
-      --  Local variables
-
-      Decl : Node_Id;
-      Typ  : Entity_Id;
-
-   --  Start of processing for Build_Default_Init_Cond_Procedure_Bodies
-
-   begin
-      --  Inspect the private declarations looking for [sub]type declarations
-
-      Decl := First (Priv_Decls);
-      while Present (Decl) loop
-         if Nkind_In (Decl, N_Full_Type_Declaration,
-                            N_Subtype_Declaration)
-         then
-            Typ := Defining_Entity (Decl);
-
-            --  Guard against partially decorate types due to previous errors
-
-            if Is_Type (Typ) then
-
-               --  If the type is subject to pragma Default_Initial_Condition,
-               --  generate the body of the internal procedure which verifies
-               --  the assertion of the pragma at run time.
-
-               if Has_Default_Init_Cond (Typ) then
-                  Build_Default_Init_Cond_Procedure_Body (Typ);
-
-               --  A derived type inherits the default initial condition
-               --  procedure from its parent type.
-
-               elsif Has_Inherited_Default_Init_Cond (Typ) then
-                  Inherit_Default_Init_Cond_Procedure (Typ);
-               end if;
-            end if;
-         end if;
-
-         Next (Decl);
-      end loop;
-   end Build_Default_Init_Cond_Procedure_Bodies;
-
-   ---------------------------------------------------
-   -- Build_Default_Init_Cond_Procedure_Declaration --
-   ---------------------------------------------------
-
-   procedure Build_Default_Init_Cond_Procedure_Declaration (Typ : Entity_Id) is
-      Loc  : constant Source_Ptr := Sloc (Typ);
-      Prag : constant Node_Id    :=
-                  Get_Pragma (Typ, Pragma_Default_Initial_Condition);
-
-      Save_Ghost_Mode : constant Ghost_Mode_Type := Ghost_Mode;
-
-      Args    : List_Id;
-      Proc_Id : Entity_Id;
-
-   begin
-      --  The procedure should be generated only for types subject to pragma
-      --  Default_Initial_Condition. Types that inherit the pragma do not get
-      --  this specialized procedure.
-
-      pragma Assert (Has_Default_Init_Cond (Typ));
-      pragma Assert (Present (Prag));
-
-      Args := Pragma_Argument_Associations (Prag);
-
-      --  Nothing to do if default initial condition procedure already built
-
-      if Present (Default_Init_Cond_Procedure (Typ)) then
-         return;
-
-      --  Nothing to do if the default initial condition appears without an
-      --  expression.
-
-      elsif No (Args) then
-         return;
-
-      --  Nothing to do if the expression of the default initial condition is
-      --  null.
-
-      elsif Nkind (Get_Pragma_Arg (First (Args))) = N_Null then
-         return;
-      end if;
-
-      --  The related type may be subject to pragma Ghost. Set the mode now to
-      --  ensure that the analysis and expansion produce Ghost nodes.
-
-      Set_Ghost_Mode_From_Entity (Typ);
-
-      Proc_Id :=
-        Make_Defining_Identifier (Loc,
-          Chars => New_External_Name (Chars (Typ), "Default_Init_Cond"));
-
-      --  Associate default initial condition procedure with the private type
-
-      Set_Ekind (Proc_Id, E_Procedure);
-      Set_Is_Default_Init_Cond_Procedure (Proc_Id);
-      Set_Default_Init_Cond_Procedure (Typ, Proc_Id);
-
-      --  Mark the default initial condition procedure explicitly as Ghost
-      --  because it does not come from source.
-
-      if Ghost_Mode > None then
-         Set_Is_Ghost_Entity (Proc_Id);
-      end if;
-
-      --  Generate:
-      --    procedure <Typ>Default_Init_Cond (Inn : <Typ>);
-
-      Insert_After_And_Analyze (Prag,
-        Make_Subprogram_Declaration (Loc,
-          Specification =>
-            Make_Procedure_Specification (Loc,
-              Defining_Unit_Name       => Proc_Id,
-              Parameter_Specifications => New_List (
-                Make_Parameter_Specification (Loc,
-                  Defining_Identifier => Make_Temporary (Loc, 'I'),
-                  Parameter_Type      => New_Occurrence_Of (Typ, Loc))))));
-
-      Ghost_Mode := Save_Ghost_Mode;
-   end Build_Default_Init_Cond_Procedure_Declaration;
-
    ---------------------------
    -- Build_Default_Subtype --
    ---------------------------
@@ -8713,6 +8423,8 @@ 
       Full_Base : out Entity_Id;
       CRec_Typ  : out Entity_Id)
    is
+      IP_View : Entity_Id;
+
    begin
       --  Assume that none of the views can be recovered
 
@@ -8721,24 +8433,10 @@ 
       Full_Base := Empty;
       CRec_Typ  := Empty;
 
-      --  The input type is private
-
-      if Is_Private_Type (Typ) then
-         Priv_Typ := Typ;
-         Full_Typ := Full_View (Priv_Typ);
-
-         if Present (Full_Typ) then
-            Full_Base := Base_Type (Full_Typ);
-
-            if Ekind_In (Full_Typ, E_Protected_Type, E_Task_Type) then
-               CRec_Typ := Corresponding_Record_Type (Full_Typ);
-            end if;
-         end if;
-
       --  The input type is the corresponding record type of a protected or a
       --  task type.
 
-      elsif Ekind (Typ) = E_Record_Type
+      if Ekind (Typ) = E_Record_Type
         and then Is_Concurrent_Record_Type (Typ)
       then
          CRec_Typ  := Typ;
@@ -8746,29 +8444,36 @@ 
          Full_Base := Base_Type (Full_Typ);
          Priv_Typ  := Incomplete_Or_Partial_View (Full_Typ);
 
-      --  Otherwise the input type could be the full view of a private type
+      --  Otherwise the input type denotes an arbitrary type
 
       else
-         Full_Typ  := Typ;
-         Full_Base := Base_Type (Full_Typ);
+         IP_View := Incomplete_Or_Partial_View (Typ);
 
-         if Ekind_In (Full_Typ, E_Protected_Type, E_Task_Type) then
-            CRec_Typ := Corresponding_Record_Type (Full_Typ);
-         end if;
+         --  The input type denotes the full view of a private type
 
-         --  The type is the full view of a private type, obtain the partial
-         --  view.
+         if Present (IP_View) then
+            Priv_Typ := IP_View;
+            Full_Typ := Typ;
 
-         if Has_Private_Declaration (Full_Typ)
-           and then not Is_Private_Type (Full_Typ)
-         then
-            Priv_Typ := Incomplete_Or_Partial_View (Full_Typ);
+         --  The input type is a private type
 
-            --  The full view of a private type should always have a partial
-            --  view.
+         elsif Is_Private_Type (Typ) then
+            Priv_Typ := Typ;
+            Full_Typ := Full_View (Priv_Typ);
 
-            pragma Assert (Present (Priv_Typ));
+         --  Otherwise the input type does not have any views
+
+         else
+            Full_Typ := Typ;
          end if;
+
+         if Present (Full_Typ) then
+            Full_Base := Base_Type (Full_Typ);
+
+            if Ekind_In (Full_Typ, E_Protected_Type, E_Task_Type) then
+               CRec_Typ := Corresponding_Record_Type (Full_Typ);
+            end if;
+         end if;
       end if;
    end Get_Views;
 
@@ -9502,39 +9207,20 @@ 
    -------------------------------------
 
    function Has_Full_Default_Initialization (Typ : Entity_Id) return Boolean is
-      Arg  : Node_Id;
       Comp : Entity_Id;
       Prag : Node_Id;
 
    begin
-      --  A private type and its full view is fully default initialized when it
-      --  is subject to pragma Default_Initial_Condition without an argument or
-      --  with a non-null argument. Since any type may act as the full view of
-      --  a private type, this check must be performed prior to the specialized
-      --  tests below.
+      --  A type subject to pragma Default_Initial_Condition is fully default
+      --  initialized when the pragma appears with a non-null argument. Since
+      --  any type may act as the full view of a private type, this check must
+      --  be performed prior to the specialized tests below.
 
-      if Has_Default_Init_Cond (Typ)
-        or else Has_Inherited_Default_Init_Cond (Typ)
-      then
+      if Has_DIC (Typ) then
          Prag := Get_Pragma (Typ, Pragma_Default_Initial_Condition);
-
-         --  Pragma Default_Initial_Condition must be present if one of the
-         --  related entity flags is set.
-
          pragma Assert (Present (Prag));
-         Arg := First (Pragma_Argument_Associations (Prag));
 
-         --  A non-null argument guarantees full default initialization
-
-         if Present (Arg) then
-            return Nkind (Arg) /= N_Null;
-
-         --  Otherwise the missing argument defaults the pragma to "True" which
-         --  is considered a non-null argument (see above).
-
-         else
-            return True;
-         end if;
+         return Is_Verifiable_DIC_Pragma (Prag);
       end if;
 
       --  A scalar type is fully default initialized if it is subject to aspect
@@ -11302,23 +10988,6 @@ 
       return Off * (Expr_Value (Exp) - Expr_Value (Low_Bound ((Ind))));
    end Indexed_Component_Bit_Offset;
 
-   -----------------------------------------
-   -- Inherit_Default_Init_Cond_Procedure --
-   -----------------------------------------
-
-   procedure Inherit_Default_Init_Cond_Procedure (Typ : Entity_Id) is
-      Par_Typ : constant Entity_Id := Etype (Typ);
-
-   begin
-      --  A derived type inherits the default initial condition procedure of
-      --  its parent type.
-
-      if No (Default_Init_Cond_Procedure (Typ)) then
-         Set_Default_Init_Cond_Procedure
-           (Typ, Default_Init_Cond_Procedure (Par_Typ));
-      end if;
-   end Inherit_Default_Init_Cond_Procedure;
-
    ----------------------------
    -- Inherit_Rep_Item_Chain --
    ----------------------------
@@ -13493,20 +13162,16 @@ 
       end if;
    end Is_Local_Variable_Reference;
 
-   -----------------------------------------------
-   -- Is_Nontrivial_Default_Init_Cond_Procedure --
-   -----------------------------------------------
+   ---------------------------------
+   -- Is_Nontrivial_DIC_Procedure --
+   ---------------------------------
 
-   function Is_Nontrivial_Default_Init_Cond_Procedure
-     (Id : Entity_Id) return Boolean
-   is
+   function Is_Nontrivial_DIC_Procedure (Id : Entity_Id) return Boolean is
       Body_Decl : Node_Id;
-      Stmt : Node_Id;
+      Stmt      : Node_Id;
 
    begin
-      if Ekind (Id) = E_Procedure
-        and then Is_Default_Init_Cond_Procedure (Id)
-      then
+      if Ekind (Id) = E_Procedure and then Is_DIC_Procedure (Id) then
          Body_Decl :=
            Unit_Declaration_Node
              (Corresponding_Body (Unit_Declaration_Node (Id)));
@@ -13530,7 +13195,7 @@ 
       end if;
 
       return False;
-   end Is_Nontrivial_Default_Init_Cond_Procedure;
+   end Is_Nontrivial_DIC_Procedure;
 
    -------------------------
    -- Is_Null_Record_Type --
@@ -15391,6 +15056,21 @@ 
       end if;
    end Is_Variable;
 
+   ------------------------------
+   -- Is_Verifiable_DIC_Pragma --
+   ------------------------------
+
+   function Is_Verifiable_DIC_Pragma (Prag : Node_Id) return Boolean is
+      Args : constant List_Id := Pragma_Argument_Associations (Prag);
+
+   begin
+      --  To qualify as verifiable, a DIC pragma must have a non-null argument
+
+      return
+        Present (Args)
+          and then Nkind (Get_Pragma_Arg (First (Args))) /= N_Null;
+   end Is_Verifiable_DIC_Pragma;
+
    ---------------------------
    -- Is_Visibly_Controlled --
    ---------------------------
@@ -18481,7 +18161,6 @@ 
    ---------------------------
 
    function Primitive_Names_Match (E1, E2 : Entity_Id) return Boolean is
-
       function Non_Internal_Name (E : Entity_Id) return Name_Id;
       --  Given an internal name, returns the corresponding non-internal name
 
@@ -18701,6 +18380,70 @@ 
       Set_Sloc (Endl, Loc);
    end Process_End_Label;
 
+   --------------------------------
+   -- Propagate_Concurrent_Flags --
+   --------------------------------
+
+   procedure Propagate_Concurrent_Flags
+     (Typ      : Entity_Id;
+      Comp_Typ : Entity_Id)
+   is
+   begin
+      if Has_Task (Comp_Typ) then
+         Set_Has_Task (Typ);
+      end if;
+
+      if Has_Protected (Comp_Typ) then
+         Set_Has_Protected (Typ);
+      end if;
+
+      if Has_Timing_Event (Comp_Typ) then
+         Set_Has_Timing_Event (Typ);
+      end if;
+   end Propagate_Concurrent_Flags;
+
+   ------------------------------
+   -- Propagate_DIC_Attributes --
+   ------------------------------
+
+   procedure Propagate_DIC_Attributes
+     (Typ      : Entity_Id;
+      From_Typ : Entity_Id)
+   is
+      DIC_Proc : Entity_Id;
+
+   begin
+      if Present (Typ) and then Present (From_Typ) then
+         pragma Assert (Is_Type (Typ) and then Is_Type (From_Typ));
+
+         --  Nothing to do if both the source and the destination denote the
+         --  same type.
+
+         if From_Typ = Typ then
+            return;
+         end if;
+
+         DIC_Proc := DIC_Procedure (From_Typ);
+
+         --  The setting of the attributes is intentionally conservative. This
+         --  prevents accidental clobbering of enabled attributes.
+
+         if Has_Inherited_DIC (From_Typ)
+           and then not Has_Inherited_DIC (Typ)
+         then
+            Set_Has_Inherited_DIC (Typ);
+         end if;
+
+         if Has_Own_DIC (From_Typ) and then not Has_Own_DIC (Typ) then
+            Set_Has_Own_DIC (Typ);
+         end if;
+
+         if Present (DIC_Proc) and then No (DIC_Procedure (Typ)) then
+            Set_DIC_Procedure (Typ, DIC_Proc);
+         end if;
+      end if;
+   end Propagate_DIC_Attributes;
+
    ------------------------------------
    -- Propagate_Invariant_Attributes --
    ------------------------------------
@@ -18758,28 +18501,6 @@ 
       end if;
    end Propagate_Invariant_Attributes;
 
-   --------------------------------
-   -- Propagate_Concurrent_Flags --
-   --------------------------------
-
-   procedure Propagate_Concurrent_Flags
-     (Typ      : Entity_Id;
-      Comp_Typ : Entity_Id)
-   is
-   begin
-      if Has_Task (Comp_Typ) then
-         Set_Has_Task (Typ);
-      end if;
-
-      if Has_Protected (Comp_Typ) then
-         Set_Has_Protected (Typ);
-      end if;
-
-      if Has_Timing_Event (Comp_Typ) then
-         Set_Has_Timing_Event (Typ);
-      end if;
-   end Propagate_Concurrent_Flags;
-
    ---------------------------------------
    -- Record_Possible_Part_Of_Reference --
    ---------------------------------------
Index: sem_util.ads
===================================================================
--- sem_util.ads	(revision 244223)
+++ sem_util.ads	(working copy)
@@ -209,24 +209,6 @@ 
    --  Determine whether a selected component has a type that depends on
    --  discriminants, and build actual subtype for it if so.
 
-   function Build_Default_Init_Cond_Call
-     (Loc    : Source_Ptr;
-      Obj_Id : Entity_Id;
-      Typ    : Entity_Id) return Node_Id;
-   --  Build a call to the default initial condition procedure of type Typ with
-   --  Obj_Id as the actual parameter.
-
-   procedure Build_Default_Init_Cond_Procedure_Bodies (Priv_Decls : List_Id);
-   --  Inspect the contents of private declarations Priv_Decls and build the
-   --  bodies the default initial condition procedures for all types subject
-   --  to pragma Default_Initial_Condition.
-
-   procedure Build_Default_Init_Cond_Procedure_Declaration (Typ : Entity_Id);
-   --  If private type Typ is subject to pragma Default_Initial_Condition,
-   --  build the declaration of the procedure which verifies the assumption
-   --  of the pragma at runtime. The declaration is inserted after the related
-   --  pragma.
-
    function Build_Default_Subtype
      (T : Entity_Id;
       N : Node_Id) return Entity_Id;
@@ -1266,10 +1248,6 @@ 
    --  either the value is not yet known before back-end processing or it is
    --  not known at compile time after back-end processing.
 
-   procedure Inherit_Default_Init_Cond_Procedure (Typ : Entity_Id);
-   --  Inherit the default initial condition procedure from the parent type of
-   --  derived type Typ.
-
    procedure Inherit_Rep_Item_Chain (Typ : Entity_Id; From_Typ : Entity_Id);
    --  Inherit the rep item chain of type From_Typ without clobbering any
    --  existing rep items on Typ's chain. Typ is the destination type.
@@ -1528,8 +1506,7 @@ 
    --  parameter of the current enclosing subprogram.
    --  Why are OUT parameters not considered here ???
 
-   function Is_Nontrivial_Default_Init_Cond_Procedure
-     (Id : Entity_Id) return Boolean;
+   function Is_Nontrivial_DIC_Procedure (Id : Entity_Id) return Boolean;
    --  Determine whether entity Id denotes the procedure that verifies the
    --  assertion expression of pragma Default_Initial_Condition and if it does,
    --  the encapsulated expression is nontrivial.
@@ -1751,6 +1728,10 @@ 
    --  default is True since this routine is commonly invoked as part of the
    --  semantic analysis and it must not be disturbed by the rewriten nodes.
 
+   function Is_Verifiable_DIC_Pragma (Prag : Node_Id) return Boolean;
+   --  Determine whether pragma Default_Initial_Condition denoted by Prag has
+   --  an assertion expression which should be verified at runtime.
+
    function Is_Visibly_Controlled (T : Entity_Id) return Boolean;
    --  Check whether T is derived from a visibly controlled type. This is true
    --  if the root type is declared in Ada.Finalization. If T is derived
@@ -2050,12 +2031,6 @@ 
    --  parameter Ent gives the entity to which the End_Label refers,
    --  and to which cross-references are to be generated.
 
-   procedure Propagate_Invariant_Attributes
-     (Typ      : Entity_Id;
-      From_Typ : Entity_Id);
-   --  Inherit all invariant-related attributes form type From_Typ. Typ is the
-   --  destination type.
-
    procedure Propagate_Concurrent_Flags
      (Typ      : Entity_Id;
       Comp_Typ : Entity_Id);
@@ -2065,6 +2040,18 @@ 
    --  by one of these flags. This procedure can only set flags for Typ, and
    --  never clear them. Comp_Typ is the type of a component or a parent.
 
+   procedure Propagate_DIC_Attributes
+     (Typ      : Entity_Id;
+      From_Typ : Entity_Id);
+   --  Inherit all Default_Initial_Condition-related attributes from type
+   --  From_Typ. Typ is the destination type.
+
+   procedure Propagate_Invariant_Attributes
+     (Typ      : Entity_Id;
+      From_Typ : Entity_Id);
+   --  Inherit all invariant-related attributes form type From_Typ. Typ is the
+   --  destination type.
+
    procedure Record_Possible_Part_Of_Reference
      (Var_Id : Entity_Id;
       Ref    : Node_Id);
Index: sem_elab.adb
===================================================================
--- sem_elab.adb	(revision 244223)
+++ sem_elab.adb	(working copy)
@@ -1016,7 +1016,7 @@ 
          return;
       end if;
 
-      Is_DIC_Proc := Is_Nontrivial_Default_Init_Cond_Procedure (Ent);
+      Is_DIC_Proc := Is_Nontrivial_DIC_Procedure (Ent);
 
       --  Elaboration issues in SPARK are reported only for source constructs
       --  and for nontrivial Default_Initial_Condition procedures. The latter
Index: sem_warn.adb
===================================================================
--- sem_warn.adb	(revision 244223)
+++ sem_warn.adb	(working copy)
@@ -1702,21 +1702,22 @@ 
       -----------------------------
 
       function Is_OK_Fully_Initialized return Boolean is
+         Prag : Node_Id;
+
       begin
          if Is_Access_Type (Typ) and then Is_Dereferenced (N) then
             return False;
 
-         --  If a type has Default_Initial_Condition set, or it inherits it,
-         --  DIC might be specified with a boolean value, meaning that the type
-         --  is considered to be fully default initialized (SPARK RM 3.1 and
-         --  SPARK RM 7.3.3). To avoid generating spurious warnings in this
-         --  case, consider all types with DIC as fully initialized.
+         --  A type subject to pragma Default_Initial_Condition is fully
+         --  default initialized when the pragma appears with a non-null
+         --  argument (SPARK RM 3.1 and SPARK RM 7.3.3).
 
-         elsif Has_Default_Init_Cond (Typ)
-           or else Has_Inherited_Default_Init_Cond (Typ)
-         then
-            return True;
+         elsif Has_DIC (Typ) then
+            Prag := Get_Pragma (Typ, Pragma_Default_Initial_Condition);
+            pragma Assert (Present (Prag));
 
+            return Is_Verifiable_DIC_Pragma (Prag);
+
          else
             return Is_Fully_Initialized_Type (Typ);
          end if;
Index: exp_ch3.adb
===================================================================
--- exp_ch3.adb	(revision 244223)
+++ exp_ch3.adb	(working copy)
@@ -6528,19 +6528,18 @@ 
       --  pragma Default_Initial_Condition, add a runtime check to verify
       --  the assumption of the pragma (SPARK RM 7.3.3). Generate:
 
-      --    <Base_Typ>Default_Init_Cond (<Base_Typ> (Def_Id));
+      --    <Base_Typ>DIC (<Base_Typ> (Def_Id));
 
       --  Note that the check is generated for source objects only
 
       if Comes_From_Source (Def_Id)
-        and then (Has_Default_Init_Cond (Typ)
-                   or else Has_Inherited_Default_Init_Cond (Typ))
+        and then Has_DIC (Typ)
+        and then Present (DIC_Procedure (Typ))
         and then not Has_Init_Expression (N)
-        and then Present (Default_Init_Cond_Procedure (Typ))
       then
          declare
-            DIC_Call : constant Node_Id :=
-                         Build_Default_Init_Cond_Call (Loc, Def_Id, Typ);
+            DIC_Call : constant Node_Id := Build_DIC_Call (Loc, Def_Id, Typ);
+
          begin
             if Present (Next_N) then
                Insert_Before_And_Analyze (Next_N, DIC_Call);
@@ -7320,6 +7319,13 @@ 
       Process_Pending_Access_Types (Def_Id);
       Freeze_Stream_Operations (N, Def_Id);
 
+      --  Generate the [spec and] body of the procedure tasked with the runtime
+      --  verification of pragma Default_Initial_Condition's expression.
+
+      if Has_DIC (Def_Id) then
+         Build_DIC_Procedure_Body (Def_Id);
+      end if;
+
       --  Generate the [spec and] body of the invariant procedure tasked with
       --  the runtime verification of all invariants that pertain to the type.
       --  This includes invariants on the partial and full view, inherited