This patch fixes a spurious error on an instantiation of an unbounded
container, when the element type is a private type with unknown discriminants,
derived from an array subtype with a predicate aspect.

The following must ocmpile quietly:

   gcc -c gpr2-attribute.adb

---
package GPR2 is

   subtype Name_Type is String
     with Dynamic_Predicate => Name_Type'Length > 0;

end GPR2;
---
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;

package GPR2.Attribute is

   type Qualified_Name (<>) is private;

   function Create (Name : Name_Type) return Qualified_Name;

private

   type Qualified_Name is new Name_Type;

end GPR2.Attribute;
---
with Ada.Containers.Indefinite_Ordered_Maps;

package body GPR2.Attribute is

   type Def is null record;

   package Attribute_Definitions is new Ada.Containers.Indefinite_Ordered_Maps
     (Qualified_Name, Def);

   function Create (Name : Name_Type) return Qualified_Name is
   begin
      return Qualified_Name (Name);
   end Create;

end GPR2.Attribute;

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

2016-06-22  Ed Schonberg  <schonb...@adacore.com>

        * einfo.ads, einfo.adb (Is_Actual_Subtype): New flag, defined
        on subtypes that are created within subprogram bodies to handle
        unconstrained composite formals.
        * checks.adb (Apply_Predicate_Check): Do not generate a check on
        an object whose type is an actual subtype.
        * sem_ch6.adb (Set_Actual_Subtypes): Do not generate an
        actual subtype for a formal whose base type is private.
        Set Is_Actual_Subtype on corresponding entity after analyzing
        its declaration.

Index: einfo.adb
===================================================================
--- einfo.adb   (revision 237680)
+++ einfo.adb   (working copy)
@@ -607,8 +607,8 @@
 
    --    Has_Inherited_Invariants        Flag291
    --    Is_Partial_Invariant_Procedure  Flag292
+   --    Is_Actual_Subtype               Flag293
 
-   --    (unused)                        Flag293
    --    (unused)                        Flag294
    --    (unused)                        Flag295
    --    (unused)                        Flag296
@@ -2014,6 +2014,12 @@
       return Flag69 (Id);
    end Is_Access_Constant;
 
+   function Is_Actual_Subtype (Id : E) return B is
+   begin
+      pragma Assert (Is_Type (Id));
+      return Flag293 (Id);
+   end Is_Actual_Subtype;
+
    function Is_Ada_2005_Only (Id : E) return B is
    begin
       return Flag185 (Id);
@@ -5036,6 +5042,12 @@
       Set_Flag69 (Id, V);
    end Set_Is_Access_Constant;
 
+   procedure Set_Is_Actual_Subtype (Id : E; V : B := True) is
+   begin
+      pragma Assert (Is_Type (Id));
+      Set_Flag293 (Id, V);
+   end Set_Is_Actual_Subtype;
+
    procedure Set_Is_Ada_2005_Only (Id : E; V : B := True) is
    begin
       Set_Flag185 (Id, V);
@@ -9186,6 +9198,7 @@
       W ("Is_Abstract_Subprogram",          Flag19  (Id));
       W ("Is_Abstract_Type",                Flag146 (Id));
       W ("Is_Access_Constant",              Flag69  (Id));
+      W ("Is_Actual_Subtype",               Flag293 (Id));
       W ("Is_Ada_2005_Only",                Flag185 (Id));
       W ("Is_Ada_2012_Only",                Flag199 (Id));
       W ("Is_Aliased",                      Flag15  (Id));
Index: einfo.ads
===================================================================
--- einfo.ads   (revision 237680)
+++ einfo.ads   (working copy)
@@ -2232,6 +2232,10 @@
 --    Is_Access_Type (synthesized)
 --       Applies to all entities, true for access types and subtypes
 
+--    Is_Actual_Subtype (Flag293)
+--       Defined on all types, true for the generated constrained subtypes
+--       that are built for unconstrained composite actuals.
+
 --    Is_Ada_2005_Only (Flag185)
 --       Defined in all entities, true if a valid pragma Ada_05 or Ada_2005
 --       applies to the entity which specifically names the entity, indicating
@@ -7017,6 +7021,7 @@
    function Is_Abstract_Subprogram              (Id : E) return B;
    function Is_Abstract_Type                    (Id : E) return B;
    function Is_Access_Constant                  (Id : E) return B;
+   function Is_Actual_Subtype                   (Id : E) return B;
    function Is_Ada_2005_Only                    (Id : E) return B;
    function Is_Ada_2012_Only                    (Id : E) return B;
    function Is_Aliased                          (Id : E) return B;
@@ -7689,6 +7694,7 @@
    procedure Set_Is_Abstract_Subprogram          (Id : E; V : B := True);
    procedure Set_Is_Abstract_Type                (Id : E; V : B := True);
    procedure Set_Is_Access_Constant              (Id : E; V : B := True);
+   procedure Set_Is_Actual_Subtype               (Id : E; V : B := True);
    procedure Set_Is_Ada_2005_Only                (Id : E; V : B := True);
    procedure Set_Is_Ada_2012_Only                (Id : E; V : B := True);
    procedure Set_Is_Aliased                      (Id : E; V : B := True);
@@ -8477,6 +8483,7 @@
    pragma Inline (Is_Abstract_Subprogram);
    pragma Inline (Is_Abstract_Type);
    pragma Inline (Is_Access_Constant);
+   pragma Inline (Is_Actual_Subtype);
    pragma Inline (Is_Access_Protected_Subprogram_Type);
    pragma Inline (Is_Access_Subprogram_Type);
    pragma Inline (Is_Access_Type);
@@ -8989,6 +8996,7 @@
    pragma Inline (Set_Is_Abstract_Subprogram);
    pragma Inline (Set_Is_Abstract_Type);
    pragma Inline (Set_Is_Access_Constant);
+   pragma Inline (Set_Is_Actual_Subtype);
    pragma Inline (Set_Is_Ada_2005_Only);
    pragma Inline (Set_Is_Ada_2012_Only);
    pragma Inline (Set_Is_Aliased);
Index: checks.adb
===================================================================
--- checks.adb  (revision 237691)
+++ checks.adb  (working copy)
@@ -2650,7 +2650,17 @@
 
             Check_Expression_Against_Static_Predicate (N, Typ);
 
-            if Is_Entity_Name (N) then
+            if not Expander_Active then
+               return;
+            end if;
+
+            --  For an entity of the type, generate a call to the predicate
+            --  function, unless its type is an actual subtype, which is not
+            --  visible outside of the enclosing subprogram.
+
+            if Is_Entity_Name (N)
+              and then not Is_Actual_Subtype (Typ)
+            then
                Insert_Action (N,
                  Make_Predicate_Check
                    (Typ, New_Occurrence_Of (Entity (N), Sloc (N))));
Index: sem_ch6.adb
===================================================================
--- sem_ch6.adb (revision 237688)
+++ sem_ch6.adb (working copy)
@@ -11226,9 +11226,12 @@
 
          --  At this stage we have an unconstrained type that may need an
          --  actual subtype. For sure the actual subtype is needed if we have
-         --  an unconstrained array type.
+         --  an unconstrained array type. However, in an instance, the type
+         --  may appear as a subtype of the full view, while the actual is
+         --  in fact private (in which case no actual subtype is needed) so
+         --  check the kind of the base type.
 
-         elsif Is_Array_Type (T) then
+         elsif Is_Array_Type (Base_Type (T)) then
             AS_Needed := True;
 
          --  The only other case needing an actual subtype is an unconstrained
@@ -11299,6 +11302,7 @@
             --  therefore needs no constraint checks.
 
             Analyze (Decl, Suppress => All_Checks);
+            Set_Is_Actual_Subtype (Defining_Identifier (Decl));
 
             --  We need to freeze manually the generated type when it is
             --  inserted anywhere else than in a declarative part.

Reply via email to