]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/ada/sem_disp.adb
3psoccon.ads, [...]: Files added.
[thirdparty/gcc.git] / gcc / ada / sem_disp.adb
index 29b8e409e2134d5ceb07aa33c23e70414cf033dd..4c538b0ff40f8499e87e1566567657600fc28630 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2002 Free Software Foundation, Inc.          --
+--          Copyright (C) 1992-2003 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- --
@@ -54,7 +54,7 @@ package body Sem_Disp is
      (Tagged_Type : Entity_Id;
       Prev_Op     : Entity_Id;
       New_Op      : Entity_Id);
-   --  Replace an implicit dispatching operation with an  explicit one.
+   --  Replace an implicit dispatching operation with an explicit one.
    --  Prev_Op is an inherited primitive operation which is overridden
    --  by the explicit declaration of New_Op.
 
@@ -145,7 +145,7 @@ package body Sem_Disp is
                  ("operation can be dispatching in only one type", Subp);
             end if;
 
-         --  Verify that the restriction in E.2.2 (1) is obeyed.
+         --  Verify that the restriction in E.2.2 (14) is obeyed
 
          elsif Remote
            and then Ekind (Etype (Formal)) = E_Anonymous_Access_Type
@@ -274,8 +274,8 @@ package body Sem_Disp is
               and then not Is_Abstract (Alias (Func))
               and then No (DTC_Entity (Func))
             then
-               --  private overriding of inherited abstract operation,
-               --  call is legal
+               --  Private overriding of inherited abstract operation,
+               --  call is legal.
 
                Set_Entity (Name (N), Alias (Func));
                return;
@@ -341,7 +341,7 @@ package body Sem_Disp is
                   if not Is_Controlling_Actual (Actual) then
                      null; -- can be anything
 
-                  elsif (Is_Dynamically_Tagged (Actual)) then
+                  elsif Is_Dynamically_Tagged (Actual) then
                      null; --  valid parameter
 
                   elsif Is_Tag_Indeterminate (Actual) then
@@ -437,8 +437,9 @@ package body Sem_Disp is
       --  inherited private subprograms are treated as dispatching, even
       --  if the associated tagged type is already frozen.
 
-      Has_Dispatching_Parent := Present (Alias (Subp))
-        and then Is_Dispatching_Operation (Alias (Subp));
+      Has_Dispatching_Parent :=
+         Present (Alias (Subp))
+           and then Is_Dispatching_Operation (Alias (Subp));
 
       if No (Tagged_Type) then
          return;
@@ -487,7 +488,7 @@ package body Sem_Disp is
             then
                declare
                   Subp_Body : constant Node_Id := Unit_Declaration_Node (Subp);
-                  Decl_Item : Node_Id := Next (Parent (Tagged_Type));
+                  Decl_Item : Node_Id          := Next (Parent (Tagged_Type));
 
                begin
                   --  ??? The checks here for whether the type has been
@@ -537,7 +538,7 @@ package body Sem_Disp is
 
                   elsif Is_Frozen (Subp) then
 
-                     --  the subprogram body declares a primitive operation.
+                     --  The subprogram body declares a primitive operation.
                      --  if the subprogram is already frozen, we must update
                      --  its dispatching information explicitly here. The
                      --  information is taken from the overridden subprogram.
@@ -595,7 +596,7 @@ package body Sem_Disp is
       if Present (Old_Subp) then
          Check_Subtype_Conformant (Subp, Old_Subp);
          Override_Dispatching_Operation (Tagged_Type, Old_Subp, Subp);
-
+         Set_Is_Overriding_Operation (Subp);
       else
          Add_Dispatching_Operation (Tagged_Type, Subp);
       end if;
@@ -612,7 +613,7 @@ package body Sem_Disp is
            or else Chars (Subp) = Name_Finalize)
       then
          declare
-            F_Node   : Node_Id := Freeze_Node (Tagged_Type);
+            F_Node   : constant Node_Id := Freeze_Node (Tagged_Type);
             Decl     : Node_Id;
             Old_P    : Entity_Id;
             Old_Bod  : Node_Id;
@@ -623,19 +624,19 @@ package body Sem_Disp is
                          Name_Adjust,
                          Name_Finalize);
 
-            D_Names : constant array (1 .. 3) of Name_Id :=
-                        (Name_uDeep_Initialize,
-                         Name_uDeep_Adjust,
-                         Name_uDeep_Finalize);
+            D_Names : constant array (1 .. 3) of TSS_Name_Type :=
+                        (TSS_Deep_Initialize,
+                         TSS_Deep_Adjust,
+                         TSS_Deep_Finalize);
 
          begin
             --  Remove previous controlled function, which was constructed
             --  and analyzed when the type was frozen. This requires
-            --  removing the body of the redefined primitive, as well as its
-            --  specification if needed (there is no spec created for
+            --  removing the body of the redefined primitive, as well as
+            --  its specification if needed (there is no spec created for
             --  Deep_Initialize, see exp_ch3.adb). We must also dismantle
-            --  the exception information that may have been generated for it
-            --  when zero-cost is enabled.
+            --  the exception information that may have been generated for
+            --  it when front end zero-cost tables are enabled.
 
             for J in D_Names'Range loop
                Old_P := TSS (Tagged_Type, D_Names (J));
@@ -654,7 +655,7 @@ package body Sem_Disp is
                      Old_Spec := Corresponding_Spec (Old_Bod);
                      Set_Has_Completion             (Old_Spec, False);
 
-                     if Exception_Mechanism = Front_End_ZCX then
+                     if Exception_Mechanism = Front_End_ZCX_Exceptions then
                         Set_Has_Subprogram_Descriptor (Old_Spec, False);
                         Set_Handler_Records           (Old_Spec, No_List);
                         Set_Is_Eliminated             (Old_Spec);
@@ -772,10 +773,9 @@ package body Sem_Disp is
          Next_Elmt (Op2);
       end loop;
 
-      --  Operation is a new primitive.
+      --  Operation is a new primitive
 
       Append_Elmt (Subp, New_Prim);
-
    end Check_Operation_From_Incomplete_Type;
 
    ---------------------------------------
@@ -800,6 +800,35 @@ package body Sem_Disp is
             --  dispatching attributes here.
 
             if not Is_Dispatching_Operation (Old_Subp) then
+
+               --  If the untagged type has no discriminants, and the full
+               --  view is constrained, there will be a spurious mismatch
+               --  of subtypes on the controlling arguments, because the tagged
+               --  type is the internal base type introduced in the derivation.
+               --  Use the original type to verify conformance, rather than the
+               --  base type.
+
+               if not Comes_From_Source (Tagged_Type)
+                 and then Has_Discriminants (Tagged_Type)
+               then
+                  declare
+                     Formal : Entity_Id;
+                  begin
+                     Formal := First_Formal (Old_Subp);
+                     while Present (Formal) loop
+                        if Tagged_Type = Base_Type (Etype (Formal)) then
+                           Tagged_Type := Etype (Formal);
+                        end if;
+
+                        Next_Formal (Formal);
+                     end loop;
+                  end;
+
+                  if Tagged_Type = Base_Type (Etype (Old_Subp)) then
+                     Tagged_Type := Etype (Old_Subp);
+                  end if;
+               end if;
+
                Check_Controlling_Formals (Tagged_Type, Old_Subp);
                Set_Is_Dispatching_Operation (Old_Subp, True);
                Set_DT_Position (Old_Subp, No_Uint);
@@ -816,6 +845,7 @@ package body Sem_Disp is
                Set_Alias (Old_Subp, Alias (Subp));
 
                --  The derived subprogram should inherit the abstractness
+
                --  of the parent subprogram (except in the case of a function
                --  returning the type). This sets the abstractness properly
                --  for cases where a private extension may have inherited
@@ -853,7 +883,11 @@ package body Sem_Disp is
 
       --  Normal case
 
-      elsif Is_Controlling_Actual (N) then
+      elsif Is_Controlling_Actual (N)
+        or else
+         (Nkind (Parent (N)) = N_Qualified_Expression
+           and then Is_Controlling_Actual (Parent (N)))
+      then
          Typ := Etype (N);
 
          if Is_Access_Type (Typ) then
@@ -880,7 +914,12 @@ package body Sem_Disp is
             end if;
          end if;
 
-         if Is_Class_Wide_Type (Typ) then
+         if Is_Class_Wide_Type (Typ)
+           or else
+             (Nkind (Parent (N)) = N_Qualified_Expression
+               and then Is_Access_Type (Etype (N))
+               and then Is_Class_Wide_Type (Designated_Type (Etype (N))))
+         then
             return N;
          end if;
       end if;
@@ -953,6 +992,12 @@ package body Sem_Disp is
          if not Has_Controlling_Result (Nam) then
             return False;
 
+         --  An explicit dereference means that the call has already been
+         --  expanded and there is no tag to propagate.
+
+         elsif Nkind (N) = N_Explicit_Dereference then
+            return False;
+
          --  If there are no actuals, the call is tag-indeterminate
 
          elsif No (Parameter_Associations (Orig_Node)) then
@@ -992,7 +1037,7 @@ package body Sem_Disp is
       Prev_Op     : Entity_Id;
       New_Op      : Entity_Id)
    is
-      Op_Elmt   : Elmt_Id := First_Elmt (Primitive_Operations (Tagged_Type));
+      Op_Elmt : Elmt_Id := First_Elmt (Primitive_Operations (Tagged_Type));
 
    begin
       --  Patch the primitive operation list