This patch adds several legality checks on calls to an instance of the
predefined Generic_Dispatchin_Constructor. The following three tests are
performed:

a) The tag argument is defined, i.e. is not No_Tag.

b) The  tag is not that of an abstract type.

c) The accessibility level of the type denoted by the tag is no greater than
that of the specified constructor function.

Tested in  ACATS 4.0H C390012.

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

2015-11-12  Ed Schonberg  <schonb...@adacore.com>

        * exp_intr.adb: Add legality checks on calls to a
        Generic_Dispatching_Constructor: the given tag must be defined,
        it cannot be the tag of an abstract type, and its accessibility
        level must not be greater than that of the constructor.

Index: exp_intr.adb
===================================================================
--- exp_intr.adb        (revision 230223)
+++ exp_intr.adb        (working copy)
@@ -311,6 +311,31 @@
 
       Remove_Side_Effects (Tag_Arg);
 
+      --  Check that we have a proper tag
+
+      Insert_Action (N,
+        Make_Implicit_If_Statement (N,
+          Condition       => Make_Op_Eq (Loc,
+            Left_Opnd  => New_Copy_Tree (Tag_Arg),
+            Right_Opnd => New_Occurrence_Of (RTE (RE_No_Tag), Loc)),
+
+          Then_Statements => New_List (
+            Make_Raise_Statement (Loc,
+              New_Occurrence_Of (RTE (RE_Tag_Error), Loc)))));
+
+      --  Check that it is not the tag of an abstract type
+
+      Insert_Action (N,
+        Make_Implicit_If_Statement (N,
+          Condition       => Make_Function_Call (Loc,
+             Name                   =>
+               New_Occurrence_Of (RTE (RE_Type_Is_Abstract), Loc),
+             Parameter_Associations => New_List (New_Copy_Tree (Tag_Arg))),
+
+          Then_Statements => New_List (
+            Make_Raise_Statement (Loc,
+              New_Occurrence_Of (RTE (RE_Tag_Error), Loc)))));
+
       --  The subprogram is the third actual in the instantiation, and is
       --  retrieved from the corresponding renaming declaration. However,
       --  freeze nodes may appear before, so we retrieve the declaration
@@ -324,6 +349,22 @@
       Act_Constr := Entity (Name (Act_Rename));
       Result_Typ := Class_Wide_Type (Etype (Act_Constr));
 
+      --  Check that the accessibility level of the tag is no deeper than that
+      --  of the constructor function.
+
+      Insert_Action (N,
+        Make_Implicit_If_Statement (N,
+          Condition       =>
+            Make_Op_Gt (Loc,
+              Left_Opnd  =>
+                Build_Get_Access_Level (Loc, New_Copy_Tree (Tag_Arg)),
+              Right_Opnd =>
+                Make_Integer_Literal (Loc, Scope_Depth (Act_Constr))),
+
+          Then_Statements => New_List (
+            Make_Raise_Statement (Loc,
+              New_Occurrence_Of (RTE (RE_Tag_Error), Loc)))));
+
       if Is_Interface (Etype (Act_Constr)) then
 
          --  If the result type is not known to be a parent of Tag_Arg then we
@@ -390,7 +431,6 @@
       --  conversion of the call to the actual constructor.
 
       Rewrite (N, Convert_To (Result_Typ, Cnstr_Call));
-      Analyze_And_Resolve (N, Etype (Act_Constr));
 
       --  Do not generate a run-time check on the built object if tag
       --  checks are suppressed for the result type or tagged type expansion
@@ -458,6 +498,8 @@
                  Make_Raise_Statement (Loc,
                    Name => New_Occurrence_Of (RTE (RE_Tag_Error), Loc)))));
       end if;
+
+      Analyze_And_Resolve (N, Etype (Act_Constr));
    end Expand_Dispatching_Constructor_Call;
 
    ---------------------------
Index: rtsfind.ads
===================================================================
--- rtsfind.ads (revision 230223)
+++ rtsfind.ads (working copy)
@@ -640,6 +640,7 @@
      RE_Max_Predef_Prims,                -- Ada.Tags
      RE_Needs_Finalization,              -- Ada.Tags
      RE_No_Dispatch_Table_Wrapper,       -- Ada.Tags
+     RE_No_Tag,                          -- Ada.Tags
      RE_NDT_Prims_Ptr,                   -- Ada.Tags
      RE_NDT_TSD,                         -- Ada.Tags
      RE_Num_Prims,                       -- Ada.Tags
@@ -1871,6 +1872,7 @@
      RE_Max_Predef_Prims                 => Ada_Tags,
      RE_Needs_Finalization               => Ada_Tags,
      RE_No_Dispatch_Table_Wrapper        => Ada_Tags,
+     RE_No_Tag                           => Ada_Tags,
      RE_NDT_Prims_Ptr                    => Ada_Tags,
      RE_NDT_TSD                          => Ada_Tags,
      RE_Num_Prims                        => Ada_Tags,

Reply via email to