with Treepr; -- ???For debugging code below
 
-with Aspects;  use Aspects;
 with Casing;   use Casing;
 with Checks;   use Checks;
 with Debug;    use Debug;
 with Sem_Cat;  use Sem_Cat;
 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_Elab; use Sem_Elab;
 with Sem_Eval; use Sem_Eval;
       end if;
    end Check_No_Hidden_State;
 
+   ---------------------------------------------
+   -- Check_Nonoverridable_Aspect_Consistency --
+   ---------------------------------------------
+
+   procedure Check_Inherited_Nonoverridable_Aspects
+     (Inheritor      : Entity_Id;
+      Interface_List : List_Id;
+      Parent_Type    : Entity_Id) is
+
+      --  array needed for iterating over subtype values
+      Nonoverridable_Aspects : constant array (Positive range <>) of
+        Nonoverridable_Aspect_Id :=
+          (Aspect_Default_Iterator,
+           Aspect_Iterator_Element,
+           Aspect_Implicit_Dereference,
+           Aspect_Constant_Indexing,
+           Aspect_Variable_Indexing,
+           Aspect_Aggregate,
+           Aspect_Max_Entry_Queue_Length
+           --  , Aspect_No_Controlled_Parts
+          );
+
+      --  Note that none of these 8 aspects can be specified (for a type)
+      --  via a pragma. For 7 of them, the corresponding pragma does not
+      --  exist. The Pragma_Id enumeration type does include
+      --  Pragma_Max_Entry_Queue_Length, but that pragma is only use to
+      --  specify the aspect for a protected entry or entry family, not for
+      --  a type, and therefore cannot introduce the sorts of inheritance
+      --  issues that we are concerned with in this procedure.
+
+      type Entity_Array is array (Nat range <>) of Entity_Id;
+
+      function Ancestor_Entities return Entity_Array;
+      --  Returns all progenitors (including parent type, if present)
+
+      procedure Check_Consistency_For_One_Aspect_Of_Two_Ancestors
+        (Aspect        : Nonoverridable_Aspect_Id;
+         Ancestor_1    : Entity_Id;
+         Aspect_Spec_1 : Node_Id;
+         Ancestor_2    : Entity_Id;
+         Aspect_Spec_2 : Node_Id);
+      --  A given aspect has been specified for each of two ancestors;
+      --  check that the two aspect specifications are compatible (see
+      --  RM 13.1.1(18.5) and AI12-0211).
+
+      -----------------------
+      -- Ancestor_Entities --
+      -----------------------
+
+      function Ancestor_Entities return Entity_Array is
+         Ifc_Count : constant Nat := List_Length (Interface_List);
+         Ifc_Ancestors : Entity_Array (1 .. Ifc_Count);
+         Ifc : Node_Id := First (Interface_List);
+      begin
+         for Idx in Ifc_Ancestors'Range loop
+            Ifc_Ancestors (Idx) := Entity (Ifc);
+            pragma Assert (Present (Ifc_Ancestors (Idx)));
+            Ifc := Next (Ifc);
+         end loop;
+         pragma Assert (not Present (Ifc));
+         if Present (Parent_Type) then
+            return Parent_Type & Ifc_Ancestors;
+         else
+            return Ifc_Ancestors;
+         end if;
+      end Ancestor_Entities;
+
+      -------------------------------------------------------
+      -- Check_Consistency_For_One_Aspect_Of_Two_Ancestors --
+      -------------------------------------------------------
+
+      procedure Check_Consistency_For_One_Aspect_Of_Two_Ancestors
+        (Aspect        : Nonoverridable_Aspect_Id;
+         Ancestor_1    : Entity_Id;
+         Aspect_Spec_1 : Node_Id;
+         Ancestor_2    : Entity_Id;
+         Aspect_Spec_2 : Node_Id) is
+      begin
+         if not Is_Confirming (Aspect, Aspect_Spec_1, Aspect_Spec_2) then
+            Error_Msg_Name_1 := Aspect_Names (Aspect);
+            Error_Msg_Name_2 := Chars (Ancestor_1);
+            Error_Msg_Name_3 := Chars (Ancestor_2);
+
+            Error_Msg (
+              "incompatible % aspects inherited from ancestors % and %",
+              Sloc (Inheritor));
+         end if;
+      end Check_Consistency_For_One_Aspect_Of_Two_Ancestors;
+
+      Ancestors : constant Entity_Array := Ancestor_Entities;
+
+      --  start of processing for Check_Inherited_Nonoverridable_Aspects
+   begin
+      --  No Ada_Version check here; AI12-0211 is a binding interpretation.
+
+      if Ancestors'Length < 2 then
+         return; --  Inconsistency impossible; it takes 2 to disagree.
+      elsif In_Instance_Body then
+         return;  -- No legality checking in an instance body.
+      end if;
+
+      for Aspect of Nonoverridable_Aspects loop
+         declare
+            First_Ancestor_With_Aspect : Entity_Id := Empty;
+            First_Aspect_Spec, Current_Aspect_Spec : Node_Id := Empty;
+         begin
+            for Ancestor of Ancestors loop
+               Current_Aspect_Spec := Find_Aspect (Ancestor, Aspect);
+               if Present (Current_Aspect_Spec) then
+                  if Present (First_Ancestor_With_Aspect) then
+                     Check_Consistency_For_One_Aspect_Of_Two_Ancestors
+                       (Aspect        => Aspect,
+                        Ancestor_1    => First_Ancestor_With_Aspect,
+                        Aspect_Spec_1 => First_Aspect_Spec,
+                        Ancestor_2    => Ancestor,
+                        Aspect_Spec_2 => Current_Aspect_Spec);
+                  else
+                     First_Ancestor_With_Aspect := Ancestor;
+                     First_Aspect_Spec := Current_Aspect_Spec;
+                  end if;
+               end if;
+            end loop;
+         end;
+      end loop;
+   end Check_Inherited_Nonoverridable_Aspects;
+
    ----------------------------------------
    -- Check_Nonvolatile_Function_Profile --
    ----------------------------------------
       return False;
    end Is_Child_Or_Sibling;
 
+   -------------------
+   -- Is_Confirming --
+   -------------------
+
+   function Is_Confirming (Aspect : Nonoverridable_Aspect_Id;
+                           Aspect_Spec_1, Aspect_Spec_2 : Node_Id)
+                          return Boolean is
+      function Names_Match (Nm1, Nm2 : Node_Id) return Boolean;
+      function Names_Match (Nm1, Nm2 : Node_Id) return Boolean is
+      begin
+         if Nkind (Nm1) /= Nkind (Nm2) then
+            return False;
+         end if;
+         case Nkind (Nm1) is
+            when N_Identifier =>
+               return Name_Equals (Chars (Nm1), Chars (Nm2));
+            when N_Expanded_Name =>
+               return Names_Match (Prefix (Nm1), Prefix (Nm2))
+                 and then Names_Match (Selector_Name (Nm1),
+                                       Selector_Name (Nm2));
+            when N_Empty =>
+               return True; -- needed for Aggregate aspect checking
+
+            when others =>
+               --  e.g., 'Class attribute references
+               if Is_Entity_Name (Nm1) and Is_Entity_Name (Nm2) then
+                  return Entity (Nm1) = Entity (Nm2);
+               end if;
+
+               raise Program_Error;
+         end case;
+      end Names_Match;
+   begin
+      --  allow users to disable "shall be confirming" check, at least for now
+      if Relaxed_RM_Semantics then
+         return True;
+      end if;
+
+      --  ??? Type conversion here (along with "when others =>" below) is a
+      --  workaround for a bootstrapping problem related to casing on a
+      --  static-predicate-bearing subtype.
+
+      case Aspect_Id (Aspect) is
+         --  name-valued aspects; compare text of names, not resolution.
+         when Aspect_Default_Iterator
+            | Aspect_Iterator_Element
+            | Aspect_Constant_Indexing
+            | Aspect_Variable_Indexing
+            | Aspect_Implicit_Dereference =>
+            declare
+               Item_1 : constant Node_Id := Aspect_Rep_Item (Aspect_Spec_1);
+               Item_2 : constant Node_Id := Aspect_Rep_Item (Aspect_Spec_2);
+            begin
+               if (Nkind (Item_1) /= N_Attribute_Definition_Clause)
+                 or (Nkind (Item_2) /= N_Attribute_Definition_Clause)
+               then
+                  pragma Assert (Serious_Errors_Detected > 0);
+                  return True;
+               end if;
+
+               return Names_Match (Expression (Item_1),
+                                   Expression (Item_2));
+            end;
+
+         --  one of a kind
+         when Aspect_Aggregate =>
+            declare
+               Empty_1,
+               Add_Named_1,
+               Add_Unnamed_1,
+               New_Indexed_1,
+               Assign_Indexed_1,
+               Empty_2,
+               Add_Named_2,
+               Add_Unnamed_2,
+               New_Indexed_2,
+               Assign_Indexed_2 : Node_Id := Empty;
+            begin
+               Parse_Aspect_Aggregate
+                 (N                   => Expression (Aspect_Spec_1),
+                  Empty_Subp          => Empty_1,
+                  Add_Named_Subp      => Add_Named_1,
+                  Add_Unnamed_Subp    => Add_Unnamed_1,
+                  New_Indexed_Subp    => New_Indexed_1,
+                  Assign_Indexed_Subp => Assign_Indexed_1);
+               Parse_Aspect_Aggregate
+                 (N                   => Expression (Aspect_Spec_2),
+                  Empty_Subp          => Empty_2,
+                  Add_Named_Subp      => Add_Named_2,
+                  Add_Unnamed_Subp    => Add_Unnamed_2,
+                  New_Indexed_Subp    => New_Indexed_2,
+                  Assign_Indexed_Subp => Assign_Indexed_2);
+               return
+                 Names_Match (Empty_1, Empty_2) and then
+                 Names_Match (Add_Named_1, Add_Named_2) and then
+                 Names_Match (Add_Unnamed_1, Add_Unnamed_2) and then
+                 Names_Match (New_Indexed_1, New_Indexed_2) and then
+                 Names_Match (Assign_Indexed_1, Assign_Indexed_2);
+            end;
+
+         --  scalar-valued aspects; compare (static) values.
+         when Aspect_Max_Entry_Queue_Length --  | Aspect_No_Controlled_Parts
+              =>
+            --  This should be unreachable. No_Controlled_Parts is
+            --  not yet supported at all in GNAT and Max_Entry_Queue_Length
+            --  is supported only for protected entries, not for types.
+            pragma Assert (Serious_Errors_Detected /= 0);
+            return True;
+
+         when others =>
+            raise Program_Error;
+      end case;
+   end Is_Confirming;
+
    -----------------------------
    -- Is_Concurrent_Interface --
    -----------------------------