[multiple changes]
authorArnaud Charlet <charlet@gcc.gnu.org>
Wed, 20 Apr 2016 10:56:12 +0000 (12:56 +0200)
committerArnaud Charlet <charlet@gcc.gnu.org>
Wed, 20 Apr 2016 10:56:12 +0000 (12:56 +0200)
2016-04-20  Bob Duff  <duff@adacore.com>

* s-os_lib.ads: Minor comment fix.

2016-04-20  Ed Schonberg  <schonberg@adacore.com>

* exp_ch5.adb (Expand_N_Assignment_Statement): Do no generate
a discriminant check for a type whose partial view has unknown
discriminants when the full view has discriminants with defaults.

2016-04-20  Javier Miranda  <miranda@adacore.com>

* exp_util.adb (Remove_Side_Effects): When generating C code
remove side effect of type conversion of access to unconstrained
array type.
(Side_Effect_Free): Return false for the type
conversion of access to unconstrained array type when generating
C code.
* sem_res.adb (Resolved_Type_Conversion): Remove side effects
of access to unconstrained array type conversion when generating
C code.

2016-04-20  Ed Schonberg  <schonberg@adacore.com>

* sem_ch13.adb (Build_Predicate_Function_Declaration): New
function, to construct the declaration of a predicate function
at the end of the current declarative part rather than at the
(possibly later) freeze point of the type. This also allows uses
of a type with predicates in instantiations elsewhere.
(Resolve_Aspect_Expression): New procedure to detect visiblity
errors in aspect expressions, at the end of the declarative part
that includes the type declaration.
* sem_ch3.adb (Complete_Private_Subtype): Propagate properly the
predicate function from private to full view.
* einfo.adb (Predicate_Function): Refine search for predicate
function when type has a full view and predicate function may
be defined on either view.

2016-04-20  Javier Miranda  <miranda@adacore.com>

* frontend.adb: Passing the root of the tree to
Unnest_Subprograms().
* exp_ch6.adb (Expand_N_Subprogram_Body): Remove code that
took care of adding subprograms to the Unest_Bodies table since
performing such action too early disables the ability to process
generic instantiations.
(Unnest_Subprograms): Adding parameter.
(Search_Unnesting_Subprograms): New subprogram.
* exp_ch6.ads (Unnest_Subrograms): Update documentation.

From-SVN: r235268

gcc/ada/ChangeLog
gcc/ada/einfo.adb
gcc/ada/exp_ch5.adb
gcc/ada/exp_ch6.adb
gcc/ada/exp_ch6.ads
gcc/ada/exp_util.adb
gcc/ada/frontend.adb
gcc/ada/s-os_lib.ads
gcc/ada/sem_ch13.adb
gcc/ada/sem_ch3.adb
gcc/ada/sem_res.adb

index 81bc2cc5db1b6f3541634d49d29ad12936e2e8ca..17e8bdac36b82ce654fd3023407fc5d6389cddbb 100644 (file)
@@ -1,3 +1,53 @@
+2016-04-20  Bob Duff  <duff@adacore.com>
+
+       * s-os_lib.ads: Minor comment fix.
+
+2016-04-20  Ed Schonberg  <schonberg@adacore.com>
+
+       * exp_ch5.adb (Expand_N_Assignment_Statement): Do no generate
+       a discriminant check for a type whose partial view has unknown
+       discriminants when the full view has discriminants with defaults.
+
+2016-04-20  Javier Miranda  <miranda@adacore.com>
+
+       * exp_util.adb (Remove_Side_Effects): When generating C code
+       remove side effect of type conversion of access to unconstrained
+       array type.
+       (Side_Effect_Free): Return false for the type
+       conversion of access to unconstrained array type when generating
+       C code.
+       * sem_res.adb (Resolved_Type_Conversion): Remove side effects
+       of access to unconstrained array type conversion when generating
+       C code.
+
+2016-04-20  Ed Schonberg  <schonberg@adacore.com>
+
+       * sem_ch13.adb (Build_Predicate_Function_Declaration): New
+       function, to construct the declaration of a predicate function
+       at the end of the current declarative part rather than at the
+       (possibly later) freeze point of the type. This also allows uses
+       of a type with predicates in instantiations elsewhere.
+       (Resolve_Aspect_Expression): New procedure to detect visiblity
+       errors in aspect expressions, at the end of the declarative part
+       that includes the type declaration.
+       * sem_ch3.adb (Complete_Private_Subtype): Propagate properly the
+       predicate function from private to full view.
+       * einfo.adb (Predicate_Function): Refine search for predicate
+       function when type has a full view and predicate function may
+       be defined on either view.
+
+2016-04-20  Javier Miranda  <miranda@adacore.com>
+
+       * frontend.adb: Passing the root of the tree to
+       Unnest_Subprograms().
+       * exp_ch6.adb (Expand_N_Subprogram_Body): Remove code that
+       took care of adding subprograms to the Unest_Bodies table since
+       performing such action too early disables the ability to process
+       generic instantiations.
+       (Unnest_Subprograms): Adding parameter.
+       (Search_Unnesting_Subprograms): New subprogram.
+       * exp_ch6.ads (Unnest_Subrograms): Update documentation.
+
 2016-04-20  Hristian Kirtchev  <kirtchev@adacore.com>
 
        * exp_util.adb, freeze.adb, sem_util.adb: Minor reformatting.
index 5586ea7a268b36674b9133e116816f919b455a9b..9f1f3a9fe32681dc926d82cd24ccca92c468d698 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2015, 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- --
@@ -8213,8 +8213,13 @@ package body Einfo is
       --  If type is private and has a completion, predicate may be defined
       --  on the full view.
 
-      if Is_Private_Type (Id) and then Present (Full_View (Id)) then
+      if Is_Private_Type (Id)
+         and then
+           (not Has_Predicates (Id) or else No (Subprograms_For_Type (Id)))
+         and then Present (Full_View (Id))
+      then
          T := Full_View (Id);
+
       else
          T := Id;
       end if;
index 9f9c832ac4726e1cb47457b4c59189dc4d22cec8..139f5ca3ae24a6c539289997e098bf0e140e34ad 100644 (file)
@@ -1946,10 +1946,12 @@ package body Exp_Ch5 is
       --  have a full view with discriminants, but those are nameable only
       --  in the underlying type, so convert the Rhs to it before potential
       --  checking. Convert Lhs as well, otherwise the actual subtype might
-      --  not be constructible.
+      --  not be constructible. If the discriminants have defaults the type
+      --  is unconstrained and there is nothing to check.
 
       elsif Has_Unknown_Discriminants (Base_Type (Etype (Lhs)))
         and then Has_Discriminants (Typ)
+        and then not Has_Defaulted_Discriminants (Typ)
       then
          Rewrite (Rhs, OK_Convert_To (Base_Type (Typ), Rhs));
          Rewrite (Lhs, OK_Convert_To (Base_Type (Typ), Lhs));
index 54f4d029a9743c4f9ddb5b2587de1b2fcab01163..876aca98fd95efa7fd8f5fc3b1d5ad8e7c6b9a6a 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2015, 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- --
@@ -5491,28 +5491,6 @@ package body Exp_Ch6 is
 
       Qualify_Entity_Names (N);
 
-      --  If we are unnesting procedures, and this is an outer level procedure
-      --  with nested subprograms, do the unnesting operation now.
-
-      if Opt.Unnest_Subprogram_Mode
-
-        --  We are only interested in subprograms (not generic subprograms)
-
-        and then Is_Subprogram (Spec_Id)
-
-        --  Only deal with outer level subprograms. Nested subprograms are
-        --  handled as part of dealing with the outer level subprogram in
-        --  which they are nested.
-
-        and then Enclosing_Subprogram (Spec_Id) = Empty
-
-        --  We are only interested in subprograms that have nested subprograms
-
-        and then Has_Nested_Subprogram (Spec_Id)
-      then
-         Unest_Bodies.Append ((Spec_Id, N));
-      end if;
-
       Ghost_Mode := Save_Ghost_Mode;
    end Expand_N_Subprogram_Body;
 
@@ -8497,8 +8475,74 @@ package body Exp_Ch6 is
    -- Unnest_Subprograms --
    ------------------------
 
-   procedure Unnest_Subprograms is
+   procedure Unnest_Subprograms (N : Node_Id) is
+
+      procedure Search_Unnesting_Subprograms (N : Node_Id);
+      --  Search for outer level procedures with nested subprograms and append
+      --  them to the Unnest table.
+
+      ----------------------------------
+      -- Search_Unnesting_Subprograms --
+      ----------------------------------
+
+      procedure Search_Unnesting_Subprograms (N : Node_Id) is
+
+         function Search_Subprograms (N : Node_Id) return Traverse_Result;
+         --  Tree visitor that search for outer level procedures with nested
+         --  subprograms and adds them to the Unnest table.
+
+         ------------------------
+         -- Search_Subprograms --
+         ------------------------
+
+         function Search_Subprograms (N : Node_Id) return Traverse_Result is
+         begin
+            if Nkind_In (N, N_Subprogram_Body,
+                            N_Subprogram_Body_Stub)
+            then
+               declare
+                  Spec_Id : constant Entity_Id := Unique_Defining_Entity (N);
+
+               begin
+                  --  We are only interested in subprograms (not generic
+                  --  subprograms), that have nested subprograms.
+
+                  if Is_Subprogram (Spec_Id)
+                    and then Has_Nested_Subprogram (Spec_Id)
+                    and then Is_Library_Level_Entity (Spec_Id)
+                  then
+                     Unest_Bodies.Append ((Spec_Id, N));
+                  end if;
+               end;
+            end if;
+
+            return OK;
+         end Search_Subprograms;
+
+         ---------------
+         -- Do_Search --
+         ---------------
+
+         procedure Do_Search is new Traverse_Proc (Search_Subprograms);
+         --  Subtree visitor instantiation
+
+      --  Start of processing for Search_Unnesting_Subprograms
+
+      begin
+         if Opt.Unnest_Subprogram_Mode then
+            Do_Search (N);
+         end if;
+      end Search_Unnesting_Subprograms;
+
+   --  Start of processing for Unnest_Subprograms
+
    begin
+      if not Opt.Unnest_Subprogram_Mode then
+         return;
+      end if;
+
+      Search_Unnesting_Subprograms (N);
+
       for J in Unest_Bodies.First .. Unest_Bodies.Last loop
          declare
             UBJ : Unest_Entry renames Unest_Bodies.Table (J);
index 7ae19de63777cf0ba8394bd74f2b0be9116c98a8..551cb1e6af1b71e4dea711767b0b7cd477dd7d4a 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1992-2015, 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- --
@@ -212,9 +212,9 @@ package Exp_Ch6 is
    --  parameter to identify the accessibility level of the function result
    --  "determined by the point of call".
 
-   procedure Unnest_Subprograms;
-   --  Called to unnest subprograms. If we are in unnest subprogram mode, and
-   --  subprograms have been gathered in the Unest_Bodies table, this is the
-   --  call that causes them to be processed for unnesting.
+   procedure Unnest_Subprograms (N : Node_Id);
+   --  Called to unnest subprograms. If we are in unnest subprogram mode, this
+   --  is the call that traverses the tree N and locates all the library level
+   --  subprograms with nested subprograms to process them.
 
 end Exp_Ch6;
index da9ed388521d1f09d43ffd958e20fd0d50acca72..4b0f1f8fd9a2169a7ec8ad7ed34d680d2a403c84 100644 (file)
@@ -7800,7 +7800,30 @@ package body Exp_Util is
 
       elsif Nkind (Exp) = N_Type_Conversion then
          Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
-         goto Leave;
+
+         --  Generating C code the type conversion of an access to constrained
+         --  array type into an access to unconstrained array type involves
+         --  initializing a fat pointer and the expression must be free of
+         --  side effects to safely compute its bounds.
+
+         if Generate_C_Code
+           and then Is_Access_Type (Etype (Exp))
+           and then Is_Array_Type (Designated_Type (Etype (Exp)))
+           and then not Is_Constrained (Designated_Type (Etype (Exp)))
+         then
+            Def_Id := Build_Temporary (Loc, 'R', Exp);
+            Set_Etype (Def_Id, Exp_Type);
+            Res := New_Occurrence_Of (Def_Id, Loc);
+
+            Insert_Action (Exp,
+              Make_Object_Declaration (Loc,
+                Defining_Identifier => Def_Id,
+                Object_Definition   => New_Occurrence_Of (Exp_Type, Loc),
+                Constant_Present    => True,
+                Expression          => Relocate_Node (Exp)));
+         else
+            goto Leave;
+         end if;
 
       --  If this is an unchecked conversion that Gigi can't handle, make
       --  a copy or a use a renaming to capture the value.
@@ -9076,6 +9099,19 @@ package body Exp_Util is
         and then Is_Class_Wide_Type (Typ)
       then
          return True;
+
+      --  Generating C the type conversion of an access to constrained array
+      --  type into an access to unconstrained array type involves initializing
+      --  a fat pointer and the expression cannot be assumed to be free of side
+      --  effects since it must referenced several times to compute its bounds.
+
+      elsif Generate_C_Code
+        and then Nkind (N) = N_Type_Conversion
+        and then Is_Access_Type (Typ)
+        and then Is_Array_Type (Designated_Type (Typ))
+        and then not Is_Constrained (Designated_Type (Typ))
+      then
+         return False;
       end if;
 
       --  For other than entity names and compile time known values,
index 723096ccc1feeab4ed237013dff14131a0ca297c..8ed90b0999c2bcac02d421193839a04118db6887 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2015, 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- --
@@ -440,7 +440,7 @@ begin
 
          --  At this stage we can unnest subprogram bodies if required
 
-         Exp_Ch6.Unnest_Subprograms;
+         Exp_Ch6.Unnest_Subprograms (Cunit (Main_Unit));
 
          --  List library units if requested
 
index f53c2ec1a583191b3abb144062438dcc47b80fc3..dd0851ded7dab897110f9292c74c55876886aa07 100644 (file)
@@ -454,7 +454,7 @@ package System.OS_Lib is
    --  that is writable. Returns True if so, False otherwise. Note that this
    --  function simply interrogates the file attributes (e.g. using the C
    --  function stat), so it does not indicate a situation in which a file may
-   --  not actually be writeable due to some other process having exclusive
+   --  not actually be writable due to some other process having exclusive
    --  access.
 
    function Locate_Exec_On_Path (Exec_Name : String) return String_Access;
index 859e67e3c676262b799cd54ac7952f339658df29..57e4c8dcb81a24e5355a506bf2277ccae30aa8b5 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2015, 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- --
@@ -101,17 +101,24 @@ package body Sem_Ch13 is
    --  list is stored in Static_Discrete_Predicate (Typ), and the Expr is
    --  rewritten as a canonicalized membership operation.
 
+   function Build_Predicate_Function_Declaration
+      (Typ : Entity_Id) return Node_Id;
+   --  Build the declaration for a predicate function. The declaration is built
+   --  at the end of the declarative part containing the type definition, which
+   --  may be before the freeze point of the type. The predicate expression is
+   --  pre-analyzed at this point, to catch visibility errors.
+
    procedure Build_Predicate_Functions (Typ : Entity_Id; N : Node_Id);
    --  If Typ has predicates (indicated by Has_Predicates being set for Typ),
    --  then either there are pragma Predicate entries on the rep chain for the
    --  type (note that Predicate aspects are converted to pragma Predicate), or
    --  there are inherited aspects from a parent type, or ancestor subtypes.
-   --  This procedure builds the spec and body for the Predicate function that
-   --  tests these predicates. N is the freeze node for the type. The spec of
-   --  the function is inserted before the freeze node, and the body of the
-   --  function is inserted after the freeze node. If the predicate expression
-   --  has at least one Raise_Expression, then this procedure also builds the
-   --  M version of the predicate function for use in membership tests.
+   --  This procedure builds body for the Predicate function that tests these
+   --  predicates. N is the freeze node for the type. The spec of the function
+   --  is inserted before the freeze node, and the body of the function is
+   --  inserted after the freeze node. If the predicate expression has a least
+   --  one Raise_Expression, then this procedure also builds the M version of
+   --  the predicate function for use in membership tests.
 
    procedure Check_Pool_Size_Clash (Ent : Entity_Id; SP, SS : Node_Id);
    --  Called if both Storage_Pool and Storage_Size attribute definition
@@ -8419,18 +8426,23 @@ package body Sem_Ch13 is
       --  function. It differs in that raise expressions are marked for
       --  special expansion (see Process_REs).
 
-      Object_Name : constant Name_Id := New_Internal_Name ('I');
+      Object_Name : Name_Id;
       --  Name for argument of Predicate procedure. Note that we use the same
       --  name for both predicate functions. That way the reference within the
       --  predicate expression is the same in both functions.
 
-      Object_Entity : constant Entity_Id :=
-                        Make_Defining_Identifier (Loc, Chars => Object_Name);
+      Object_Entity : Entity_Id;
       --  Entity for argument of Predicate procedure
 
-      Object_Entity_M : constant Entity_Id :=
-                         Make_Defining_Identifier (Loc, Chars => Object_Name);
-      --  Entity for argument of Predicate_M procedure
+      Object_Entity_M : Entity_Id;
+      --  Entity for argument of separate Predicate procedure when exceptions
+      --  are present in expression.
+
+      FDecl         : Node_Id;
+      --  The function declaration.
+
+      SId            : Entity_Id;
+      --  Its entity.
 
       Raise_Expression_Present : Boolean := False;
       --  Set True if Expr has at least one Raise_Expression
@@ -8669,8 +8681,9 @@ package body Sem_Ch13 is
    begin
       --  Return if already built or if type does not have predicates
 
+      SId := Predicate_Function (Typ);
       if not Has_Predicates (Typ)
-        or else Present (Predicate_Function (Typ))
+        or else (Present (SId) and then Has_Completion (SId))
       then
          return;
       end if;
@@ -8684,6 +8697,24 @@ package body Sem_Ch13 is
 
       Expr := Empty;
 
+      if Present (SId) then
+         FDecl := Unit_Declaration_Node (SId);
+
+      else
+         FDecl := Build_Predicate_Function_Declaration (Typ);
+         SId   := Defining_Entity (FDecl);
+      end if;
+
+      --  Recover name of formal parameter of function that replaces references
+      --  to the type in predicate expressions.
+
+      Object_Entity :=
+         Defining_Identifier
+           (First (Parameter_Specifications (Specification (FDecl))));
+
+      Object_Name     := Chars (Object_Entity);
+      Object_Entity_M := Make_Defining_Identifier (Loc, Chars => Object_Name);
+
       --  Add predicates for ancestor if present. These must come before the
       --  ones for the current type, as required by AI12-0071-1.
 
@@ -8694,7 +8725,6 @@ package body Sem_Ch13 is
             Add_Call (Atyp);
          end if;
       end;
-
       --  Add Predicates for the current type
 
       Add_Predicates;
@@ -8757,27 +8787,15 @@ package body Sem_Ch13 is
          --  Build the main predicate function
 
          declare
-            SId : constant Entity_Id :=
-                    Make_Defining_Identifier (Loc,
-                      Chars => New_External_Name (Chars (Typ), "Predicate"));
-            --  The entity for the function spec
-
             SIdB : constant Entity_Id :=
               Make_Defining_Identifier (Loc,
                 Chars => New_External_Name (Chars (Typ), "Predicate"));
             --  The entity for the function body
 
             Spec  : Node_Id;
-            FDecl : Node_Id;
             FBody : Node_Id;
 
          begin
-            --  Build function declaration
-
-            Set_Ekind (SId, E_Function);
-            Set_Is_Internal (SId);
-            Set_Is_Predicate_Function (SId);
-            Set_Predicate_Function (Typ, SId);
 
             --  The predicate function is shared between views of a type
 
@@ -8792,20 +8810,6 @@ package body Sem_Ch13 is
                Set_Is_Ghost_Entity (SId);
             end if;
 
-            Spec :=
-              Make_Function_Specification (Loc,
-                Defining_Unit_Name       => SId,
-                Parameter_Specifications => New_List (
-                  Make_Parameter_Specification (Loc,
-                    Defining_Identifier => Object_Entity,
-                    Parameter_Type      => New_Occurrence_Of (Typ, Loc))),
-                Result_Definition        =>
-                  New_Occurrence_Of (Standard_Boolean, Loc));
-
-            FDecl :=
-              Make_Subprogram_Declaration (Loc,
-                Specification => Spec);
-
             --  Build function body
 
             Spec :=
@@ -8830,9 +8834,14 @@ package body Sem_Ch13 is
                       Make_Simple_Return_Statement (Loc,
                         Expression => Expr))));
 
-            --  Insert declaration before freeze node and body after
+            --  If declaration has not been analyzed yet, Insert declaration
+            --  before freeze node.
+            --  Insert body after freeze node.
+
+            if not Analyzed (FDecl) then
+               Insert_Before_And_Analyze (N, FDecl);
+            end if;
 
-            Insert_Before_And_Analyze (N, FDecl);
             Insert_After_And_Analyze  (N, FBody);
 
             --  Static predicate functions are always side-effect free, and
@@ -8863,8 +8872,8 @@ package body Sem_Ch13 is
                --  The entity for the function body
 
                Spec  : Node_Id;
-               FDecl : Node_Id;
                FBody : Node_Id;
+               FDecl : Node_Id;
                BTemp : Entity_Id;
 
             begin
@@ -9046,6 +9055,59 @@ package body Sem_Ch13 is
       Ghost_Mode := Save_Ghost_Mode;
    end Build_Predicate_Functions;
 
+   ------------------------------------------
+   -- Build_Predicate_Function_Declaration --
+   ------------------------------------------
+
+   function Build_Predicate_Function_Declaration
+     (Typ : Entity_Id) return Node_Id
+   is
+      Loc : constant Source_Ptr := Sloc (Typ);
+
+      Object_Entity : constant Entity_Id :=
+              Make_Defining_Identifier (Loc, Chars => New_Internal_Name ('I'));
+
+      --  The formal parameter of the function
+
+      SId : constant Entity_Id :=
+              Make_Defining_Identifier (Loc,
+                Chars => New_External_Name (Chars (Typ), "Predicate"));
+
+      --  The entity for the function spec
+
+      FDecl : Node_Id;
+      Spec  : Node_Id;
+
+   begin
+      Spec :=
+        Make_Function_Specification (Loc,
+          Defining_Unit_Name       => SId,
+          Parameter_Specifications => New_List (
+            Make_Parameter_Specification (Loc,
+              Defining_Identifier => Object_Entity,
+              Parameter_Type      => New_Occurrence_Of (Typ, Loc))),
+          Result_Definition        =>
+            New_Occurrence_Of (Standard_Boolean, Loc));
+
+      FDecl := Make_Subprogram_Declaration (Loc, Specification => Spec);
+
+      Set_Ekind (SId, E_Function);
+      Set_Etype (SId, Standard_Boolean);
+      Set_Is_Internal (SId);
+      Set_Is_Predicate_Function (SId);
+      Set_Predicate_Function (Typ, SId);
+
+      if Comes_From_Source (Typ) then
+         Insert_After (Parent (Typ), FDecl);
+      else
+         Insert_After (Parent (Base_Type (Typ)), FDecl);
+      end if;
+
+      Analyze (FDecl);
+
+      return FDecl;
+   end Build_Predicate_Function_Declaration;
+
    -----------------------------------------
    -- Check_Aspect_At_End_Of_Declarations --
    -----------------------------------------
@@ -12532,6 +12594,37 @@ package body Sem_Ch13 is
       A_Id : Aspect_Id;
       Expr : Node_Id;
 
+      function Resolve_Name (N : Node_Id) return Traverse_Result;
+      --  Verify that all identifiers in the expression, with the exception
+      --  of references to the current entity, denote visible entities. This
+      --  is done only to detect visibility errors, as the expression will be
+      --  properly analyzed/expanded during analysis of the predicate function
+      --  body.
+
+      ------------------
+      -- Resolve_Name --
+      ------------------
+
+      function Resolve_Name (N : Node_Id) return Traverse_Result is
+      begin
+         if Nkind (N) = N_Selected_Component then
+            if Nkind (Prefix (N)) = N_Identifier
+              and then Chars (Prefix (N)) /= Chars (E)
+            then
+               Find_Selected_Component (Parent (N));
+            end if;
+            return Skip;
+
+         elsif Nkind (N) = N_Identifier and then  Chars (N) /= Chars (E) then
+            Find_Direct_Name (N);
+            Set_Entity (N, Empty);
+         end if;
+
+         return OK;
+      end Resolve_Name;
+
+      procedure Resolve_Aspect_Expression is new Traverse_Proc (Resolve_Name);
+
    begin
       ASN := First_Rep_Item (E);
       while Present (ASN) loop
@@ -12546,11 +12639,25 @@ package body Sem_Ch13 is
 
                when Aspect_Predicate |
                     Aspect_Predicate_Failure |
-                    Aspect_Invariant |
-                    Aspect_Static_Predicate |
-                    Aspect_Dynamic_Predicate =>
+                    Aspect_Invariant =>
                   null;
 
+               when Aspect_Static_Predicate |
+                    Aspect_Dynamic_Predicate =>
+
+                  --  build predicate function specification and preanalyze
+                  --  expression after type replacement.
+
+                  if No (Predicate_Function (E)) then
+                     declare
+                        FDecl : constant Node_Id :=
+                           Build_Predicate_Function_Declaration (E);
+                        pragma Unreferenced (FDecl);
+                     begin
+                        Resolve_Aspect_Expression (Expr);
+                     end;
+                  end if;
+
                when Pre_Post_Aspects =>
                   null;
 
index cc82e710795ddfaab31ce7b553dab6dc72a4bbe1..71af299777db902b755b5a809921a036d6f0514f 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2015, 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- --
@@ -11820,8 +11820,17 @@ package body Sem_Ch3 is
       --  in particular when the full type is a scalar type for which an
       --  anonymous base type is constructed.
 
+      --  The predicate functions are generated either at the freeze point
+      --  of the type or at the end of the visible part, and we must avoid
+      --  generating them twice.
+
       if Has_Predicates (Priv) then
          Set_Has_Predicates (Full);
+         if Present (Predicate_Function (Priv))
+            and then No (Predicate_Function (Full))
+         then
+            Set_Predicate_Function (Full, Predicate_Function (Priv));
+         end if;
       end if;
 
       if Has_Delayed_Aspects (Priv) then
index 2ce47e23f97266fe2e68ded96850246b2d59d412..8957287dbfda2bd412796f4765492d4a8acccc0b 100644 (file)
@@ -10847,6 +10847,23 @@ package body Sem_Res is
       then
          Set_Do_Range_Check (Operand);
       end if;
+
+      --  Generating C code a type conversion of an access to constrained
+      --  array type to access to unconstrained array type involves building
+      --  a fat pointer which in general cannot be generated on the fly. We
+      --  remove side effects in order to store the result of the conversion
+      --  into a temporary.
+
+      if Generate_C_Code
+        and then Nkind (N) = N_Type_Conversion
+        and then Nkind (Parent (N)) /= N_Object_Declaration
+        and then Is_Access_Type (Etype (N))
+        and then Is_Array_Type (Designated_Type (Etype (N)))
+        and then not Is_Constrained (Designated_Type (Etype (N)))
+        and then Is_Constrained (Designated_Type (Etype (Expression (N))))
+      then
+         Remove_Side_Effects (N);
+      end if;
    end Resolve_Type_Conversion;
 
    ----------------------